กำลังอัปเดตคีย์หลักแบบผสม

ฉันกำลังดิ้นรนกับการอภิปรายเชิงปรัชญาว่าจะใช้คีย์หลักแบบผสมบนฐานข้อมูล SQL Server ของฉันหรือไม่ ฉันเคยใช้กุญแจตัวแทนมาโดยตลอดในอดีต และฉันกำลังท้าทายตัวเองด้วยการออกจากเขตความสะดวกสบายของฉันเพื่อลองสิ่งที่แตกต่างออกไป ฉันได้อ่านการสนทนามากมาย แต่ยังไม่สามารถหาวิธีแก้ปัญหาใดๆ ได้ ปัญหาที่ฉันมีคือเมื่อต้องอัปเดตบันทึกด้วย PK แบบผสม

ตัวอย่างเช่น บันทึกในคำถามจะเป็นดังนี้:

ContactID, RoleID, EffectiveDate, TerminationDT

PK ในกรณีนี้คือ (ContactID, RoleID, EffectiveDate) TerminationDT อาจเป็นโมฆะได้

หากใน UI ของฉัน ผู้ใช้เปลี่ยน RoleID แล้วฉันต้องอัปเดตบันทึก การใช้คีย์ตัวแทน ฉันสามารถดำเนินการ Update Table Set RoleID = 1 WHERE surrogateID = Z ได้ อย่างไรก็ตาม เมื่อใช้วิธีคีย์ผสม เมื่อฟิลด์ใดฟิลด์หนึ่งในคีย์คอมโพสิตเปลี่ยนแปลง ฉันไม่สามารถอ้างอิงบันทึกเก่าเพื่ออัปเดตได้โดยไม่ต้องรักษาที่ใดที่หนึ่งใน UI ไว้เพื่ออ้างอิงถึงค่าเก่า

ฉันไม่ผูกแหล่งข้อมูลใน UI ของฉัน ฉันเปิดการเชื่อมต่อ รับข้อมูลและจัดเก็บไว้ในบัคเก็ต จากนั้นปิดการเชื่อมต่อ ทุกคนมีความคิดเห็นอย่างไร? ขอบคุณ.


person VBCSharp    schedule 18.01.2011    source แหล่งที่มา


คำตอบ (3)


สิ่งที่คุณพูดโดยอ้างอิงแนวคิดเช่น "บันทึกเก่า" ก็คือความสัมพันธ์มีความหมายเชิงความหมายโดยไม่ขึ้นกับองค์ประกอบหลักที่ประกอบกัน ข้อเท็จจริงที่ว่าคุณต้องการคีย์เพื่ออ้างอิงถึงบันทึกเก่าหมายความว่าองค์ประกอบคีย์ผสมนั้นไม่เพียงพอ แน่นอนว่าคุณยังคงเก็บคีย์ต่างประเทศไว้ แต่ดูเหมือนชัดเจนสำหรับฉันว่าคุณต้องมีคีย์หลักที่นี่ และมันไม่ใช่คีย์ตัวแทนในความหมายปกติ

ใช้คีย์ตัวแทนโดยไม่มีความผิดในความคิดของฉัน

person Chris B. Behrens    schedule 18.01.2011
comment
+1. คีย์หลักของ IMO จะต้องไม่เปลี่ยนรูป - เมื่อคุณกำหนดแล้ว จะไม่มีการเปลี่ยนแปลง ระยะเวลา. ถ้ามันเปลี่ยน-ไม่ใช่ PK - person Alexander Malakhov; 18.01.2011
comment
นั่นคือความคิดของฉันที่จะไม่ใช้คอมโพสิต PK ในกรณีนี้ ขอบคุณที่ให้เหตุผล!! - person VBCSharp; 18.01.2011

คุณมาถูกทางแล้ว แต่เมื่อดูที่คีย์หลักของคุณแล้ว ฉันขอแนะนำให้คุณดูที่ การทำให้เป็นมาตรฐาน ฉันคิดว่าคุณควรพยายามหลีกเลี่ยงการใช้คีย์ผสม และลองใช้คีย์หลักหนึ่งคีย์ต่อตาราง เว้นแต่จำเป็น ตัวอย่างเช่น คุณสามารถใช้ RoleID และทำให้เป็นตารางของตัวเอง พร้อมด้วยคำอธิบายบทบาท และสิ่งอื่นใดที่กำหนดบทบาท และใส่เป็นการอ้างอิงคีย์ต่างประเทศในตารางอื่นๆ ของคุณ

person Nick Rolando    schedule 18.01.2011
comment
ฉันเดาว่าฉันควรจะชี้แจงเพิ่มเติมอีกสักหน่อย ContactID และ RoleID เป็นคีย์ต่างประเทศ ContactID และ RoleID เป็นคีย์หลักในตาราง Contact และ Role ตามลำดับ - person VBCSharp; 18.01.2011

ก่อนอื่นส่วนที่ง่าย:

ดูเหมือนว่าตารางของคุณจะเป็นตัวอ้างอิงโยงใช่ไหม ในกรณีนี้ ฉันพบว่าคีย์คอมโพสิตทำงานได้ดีมาก IF และนี่คือ IF ที่สำคัญ หาก UI ของคุณและไลบรารีอื่นๆ เข้าใจ UI หลายรายการในปัจจุบันไม่มี และดูเหมือนว่า UI ของคุณจะไม่เป็นเช่นนั้น ดังนั้น:

1) คุณถูกต้องที่จะใช้คีย์ผสมสำหรับการอ้างอิงโยง ซึ่งเป็นหนึ่งในไม่กี่แห่งที่มันสมเหตุสมผลเสมอ แต่:

2) คุณสามารถใส่คีย์ตัวแทนเข้าไปได้เช่นกัน ถ้ามันช่วยให้โค้ดที่เหลือง่ายขึ้น แต่ อย่าลืมเพิ่มข้อจำกัดเฉพาะในสามคอลัมน์นั้น

ยิ่งไปกว่านั้น คุณอาจจำเป็นต้องมีข้อจำกัดในการตรวจสอบเพื่อให้แน่ใจว่าจะไม่มีการทับซ้อนในช่วงวันที่ เนื่องจากฐานข้อมูลไม่รองรับ "คีย์หลักที่มีช่วง" โดยกำเนิดซึ่งเป็นสิ่งที่ดูเหมือนว่าคุณกำลังทำอยู่

เมื่อกล่าวถึงเรื่องนี้แล้ว ผมขอสร้างความสับสนเพิ่มเติมอีก เหตุใดคุณจึงอัปเดตแถวนี้ การดำเนินการที่ถูกต้องจะเป็นการใส่วันที่สิ้นสุดไว้ที่เดิมและบังคับให้สร้างแถวใหม่ที่ระบุบทบาทใหม่ของผู้ติดต่อหรือไม่ ในกรณีนี้ คุณอาจจะต้องเก็บคอมโพสิตและควบคุม UI เล็กน้อยเพื่ออนุญาต/ไม่อนุญาตการดำเนินการบางอย่าง

person Ken Downs    schedule 18.01.2011
comment
เมื่อคิดจากมุมมองของผู้ใช้ (GASP!!) สมมติว่าผู้ใช้ทำผิดพลาดกับรายการเดิมและต้องกลับไปเปลี่ยนบทบาทเนื่องจากไม่ถูกต้อง ในโลกที่สมบูรณ์แบบ บทบาทเก่าจะสิ้นสุดลง และบทบาทใหม่จะเริ่มหลังจากวันที่ครบวาระ ฉันสามารถบังคับให้ผู้ใช้ลบบันทึกที่ไม่ถูกต้องและป้อนบันทึกที่ถูกต้องใหม่ซึ่งฉันได้พิจารณาแล้วว่าจะทำใน UI การตรวจสอบวันที่ (ไม่มีการทับซ้อนกัน) เกิดขึ้นใน UI - person VBCSharp; 18.01.2011
comment
เฮ้ ไม่ต้องอ้าปากค้างเมื่อคิดถึงผู้ใช้ ถ้าเพียงแต่ฉันจะทำให้โปรแกรมเมอร์ของฉันทำอย่างนั้นได้ :) ฉันเดาว่าคุณต้องตัดสินใจว่าจะเป็นเรื่องใหญ่แค่ไหนหากผู้ใช้ต้องลบ/แทรก ผู้ใช้คนใดจะทราบได้อย่างรวดเร็วว่าพวกเขาไม่สามารถเปลี่ยนแปลงได้ และพวกเขาจะลบมันทิ้ง มันเป็นเรื่องที่คุณเรียกร้องจริงๆ ว่าคุณรู้จักฐานผู้ใช้ของคุณดีแค่ไหน - person Ken Downs; 18.01.2011
comment
@VBCSharp: การตรวจสอบ ‹...› เกิดขึ้นใน UI ทุกครั้งที่ฉันได้ยินสิ่งนี้ในบริบทของความสมบูรณ์ของข้อมูล DB ฉันสงสัยมาก - person Alexander Malakhov; 18.01.2011
comment
สงสัย? ฉันอยากจะป้องกันไม่ให้วันที่ทับซ้อนกันไปที่ DB โดยตรวจสอบอินพุตของผู้ใช้ก่อนทำการเรียกไปยัง DB และให้ DB ส่งข้อผิดพลาด ดังที่กล่าวไปแล้ว มีข้อจำกัดใน DB ที่จะป้องกันไม่ให้วันที่ทับซ้อนกันหากมีบางอย่างทำให้ผ่านกระบวนการตรวจสอบ UIs - person VBCSharp; 18.01.2011
comment
@VBCSharp: ถ้าอย่างนั้นมันก็ใช้ได้สำหรับฉัน ฉันมักจะทำซ้ำข้อจำกัดใน UI เพื่อหลีกเลี่ยงข้อยกเว้นของ DB เช่นกัน - person Alexander Malakhov; 19.01.2011