มีอะไรผิดปกติกับกุญแจต่างประเทศ?


259

ฉันจำได้ว่าเคยได้ยินJoel Spolskyพูดถึงในพอดคาสต์ 014ว่าเขาแทบจะไม่เคยใช้กุญแจต่างประเทศ (ถ้าฉันจำได้ถูกต้อง) อย่างไรก็ตามสำหรับฉันแล้วพวกเขาดูเหมือนจะสำคัญมากที่จะหลีกเลี่ยงการทำซ้ำและปัญหาความถูกต้องของข้อมูลในฐานข้อมูลของคุณ

ผู้คนมีเหตุผลที่ชัดเจนว่าทำไม (เพื่อหลีกเลี่ยงการสนทนาในแนวที่มีหลักการสแต็คล้น)?

แก้ไข: "ฉันยังไม่มีเหตุผลในการสร้างคีย์ต่างประเทศดังนั้นนี่อาจเป็นเหตุผลแรกที่ฉันตั้งค่าจริง"


9
ฉันไม่คิดว่าโจเอลไม่ได้ใช้ FK มันเป็นเพียงว่าเขาไม่ได้ทำให้ฐานข้อมูลบังคับใช้พวกเขา เหตุผลพวกเขายังคงเป็น FKs!
Daren Thomas

6
เขาบอกว่าเขาไม่ได้ใช้กุญแจต่างประเทศ แต่ฉันเห็นด้วยกับ Daren ว่าสิ่งที่เขาหมายถึงคือเขาไม่ได้ใช้ข้อ จำกัด กุญแจต่างประเทศ คอลัมน์ในตารางหนึ่งซึ่งควรจะนำค่ามาจากคีย์หลัก / ที่ไม่ซ้ำกันของอีกตารางหนึ่งคือ foreign key ไม่ว่าคุณจะเพิ่มข้อ จำกัด หรือไม่ก็ตาม
Tony Andrews

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

2
+1 สำหรับความคิดเห็นของโทนี่ มีความสับสนมากเกินไประหว่างฟีเจอร์และแนวคิดเชิงตรรกะของคีย์แปลกปลอม
JohnFx

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

คำตอบ:


352

เหตุผลในการใช้ Foreign Keys:

  • คุณจะไม่ได้รับ Orphaned Rows
  • คุณจะได้รับพฤติกรรมที่ดี "เมื่อลบน้ำตก" ทำความสะอาดตารางโดยอัตโนมัติ
  • การทราบเกี่ยวกับความสัมพันธ์ระหว่างตารางในฐานข้อมูลจะช่วยให้เครื่องมือเพิ่มประสิทธิภาพวางแผนแบบสอบถามของคุณเพื่อการดำเนินการที่มีประสิทธิภาพที่สุดเนื่องจากสามารถรับการประมาณที่ดีขึ้นเกี่ยวกับการเข้าร่วม cardinality
  • FK ให้คำแนะนำที่ดีเกี่ยวกับสถิติที่สำคัญที่สุดในการรวบรวมในฐานข้อมูลซึ่งจะนำไปสู่ประสิทธิภาพที่ดีขึ้น
  • พวกเขาเปิดใช้งานการสนับสนุนที่สร้างขึ้นอัตโนมัติทุกประเภท - ORM สามารถสร้างตัวเองเครื่องมือสร้างภาพจะสามารถสร้างโครงร่างสคีมาที่ดีสำหรับคุณ ฯลฯ
  • คนใหม่ในโครงการจะเข้าสู่การไหลของสิ่งต่าง ๆ ได้เร็วขึ้นมิฉะนั้นความสัมพันธ์โดยนัยจะได้รับการบันทึกไว้อย่างชัดเจน

เหตุผลที่ไม่ใช้รหัสต่างประเทศ:

  • คุณกำลังทำให้ DB ทำงานพิเศษในการดำเนินการCRUDทุกครั้งเนื่องจากต้องตรวจสอบความสอดคล้อง FK นี่อาจเป็นค่าใช้จ่ายที่ยิ่งใหญ่ถ้าคุณมีความปั่นป่วนมากมาย
  • โดยการบังคับใช้ความสัมพันธ์ FKs ระบุลำดับที่คุณต้องเพิ่ม / ลบสิ่งต่าง ๆ ซึ่งอาจนำไปสู่การปฏิเสธโดย DB เพื่อทำสิ่งที่คุณต้องการ (ได้รับในกรณีเช่นนี้สิ่งที่คุณพยายามจะทำคือสร้างแถวเด็กกำพร้าและนั่นไม่ใช่สิ่งที่ดี) โดยเฉพาะอย่างยิ่งเมื่อคุณทำการอัปเดตชุดใหญ่และคุณโหลดตารางหนึ่งต่อหน้าอีกตารางหนึ่งด้วยตารางที่สองที่สร้างสถานะที่สอดคล้องกัน (แต่คุณควรทำสิ่งนั้นหากมีความเป็นไปได้ที่การโหลดครั้งที่สองล้มเหลวและ ฐานข้อมูลไม่สอดคล้องกันตอนนี้หรือไม่)
  • บางครั้งคุณรู้ล่วงหน้าว่าข้อมูลของคุณจะสกปรกคุณก็ยอมรับมันและคุณต้องการให้ DB ยอมรับมัน
  • คุณเป็นคนขี้เกียจ :-)

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


12
รายการที่ดี! DBMs จะไม่ตรวจสอบความสอดคล้องของส่วน "R" ของ CRUD ดังนั้นฉันจะเอาส่วนนั้นออก นอกจากนี้อาจล้างเพราะในแอปของคุณคุณทำสิ่งเดียวกับที่ DBMS ทำ: คุณจะตรวจสอบและตรวจสอบว่า ID ผู้ปกครองถูกต้องก่อน CRD และที่จริงช้ากว่าการใช้ DBMs!
Matt Rogish

6
เกิดอะไรขึ้นถ้ามีคนลบผู้ปกครองในขณะที่คุณกำลังแทรกเด็ก ตอนนี้เมื่อฉันส่ง "เพิ่มความคิดเห็น" - หากคุณลบคำตอบแล้วความคิดเห็นนี้จะกลายเป็นเด็กกำพร้า FK จะป้องกันไว้ นอกจากนี้ฉันสามารถเปลี่ยน parentID ให้เป็นอะไรก็ได้ที่ฉันต้องการ มีคนต้องการตรวจสอบ :)
Matt Rogish

7
แม่นยำ - มันควรจะเป็นงานของ DB เพราะมันเป็นเพียงสิ่งเดียวที่สามารถรับประกันความถูกต้องในการทำธุรกรรมในการเผชิญกับลูกค้าหลายคนพร้อมกัน
SquareCog

3
+1 คำตอบที่ยอดเยี่ยม - เหตุผลที่สองที่จะไม่ใช้ข้อ จำกัด FK อาจคิดว่า "ทำให้ยากที่จะทำลายความมั่นคง" ซึ่งฟังดูดีจริง ๆ!
Bill Karwin

9
ประโยชน์ของการใช้กุญแจต่างประเทศ FAR มีค่ามากกว่าผลประโยชน์ใด ๆ ที่ไม่ได้ใช้ในความคิดของฉัน
Nick Bedford

80

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

อย่างไรก็ตามหากคุณไม่เคยมีประสบการณ์ในเชิงบวกหรือเชิงบวกในอดีตกับความพยายามที่เกี่ยวข้องกับ RDBMS แสดงว่าคุณอาจไม่ได้รับข้อมูลดังกล่าว หรือบางทีที่ผ่านมาของคุณรวมถึงการแช่ตัวในสภาพแวดล้อมที่ต่อต้านฐานข้อมูลอย่างรวดเร็ว (เช่น "DBA เหล่านั้นเป็นคนงี่เง่า - เราน้อยเราเลือกไม่กี่จาวา / c # โค้ดสลิงเกอร์สจะบันทึกวัน") ซึ่งในกรณีนี้ การพูดคลุมเครือของผู้มีอำนาจบางคนบอกคุณว่า FKs (และข้อ จำกัด ที่พวกเขาสามารถบ่งบอก) เป็นสิ่งสำคัญหากคุณเพียงแค่ฟัง

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


61
ฉันจะใช้ "กุญแจต่างประเทศที่กลั่นเป็นแปรงฟันของคุณ: ไปข้างหน้าทำโดยไม่ได้ แต่ระวังเมื่อคุณยิ้ม"
Mark Sowul

5
โดยส่วนตัวแล้วฉันพบว่าหลักการของ RDBMS นั้นง่ายกว่าและชัดเจนกว่าสุขอนามัยช่องปากเป็นอย่างมาก
Ali Gangji

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

52

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

หากคุณใช้ฐานข้อมูลเชิงสัมพันธ์ดูเหมือนว่าคุณควรกำหนดความสัมพันธ์บางอย่างไว้ น่าเสียดายที่ทัศนคติแบบนี้ (คุณไม่ต้องการคีย์ต่างประเทศ) ดูเหมือนว่าจะได้รับการยอมรับจากนักพัฒนาแอพพลิเคชั่นจำนวนมากที่ไม่ต้องการใส่ใจกับเรื่องโง่ ๆ เช่นความถูกต้องของข้อมูล (แต่ต้องการเพราะ บริษัท ของพวกเขาไม่มี โดยปกติแล้วในฐานข้อมูลที่รวบรวมโดยประเภทเหล่านี้คุณโชคดีที่มีคีย์หลัก;)


26
ฉันไม่ได้รับคนที่ไม่มี FKs ในฐานข้อมูลของพวกเขา ครั้งสุดท้ายที่ฉันทำงานกับคนที่ไม่มีเขาบอกว่า "ไม่เราบังคับใช้ในใบสมัคร" ยกเว้นว่าฉันทำแบบสำรวจฐานข้อมูลลูกค้าทั้งหมดและพบว่าพวกเขาส่วนใหญ่มีเด็กกำพร้า ...
ErikE

1
ที่มักจะเป็นกรณี ฉันคิดว่าคุณสามารถออกไปบังคับใช้เฉพาะในฐานข้อมูล (ตราบใดที่ผู้ใช้ของคุณไม่สนใจข้อยกเว้นรันไทม์) แต่การมีทั้งคู่เป็นวิธีเดียวที่จะไป
AlexCuse

ทั้งหมดในการถอดเสียง / การตอบสนองของ Atwood "Atwood: ... ขึ้นอยู่กับกุญแจต่างประเทศที่คุณตั้งไว้ในดัชนีพวกเขาคิดออก ... Spolsky: [หัวเราะ] สมมติว่าคุณทำอย่างนั้น Atwood: ดีสมมติว่า คุณตั้งค่าฐานข้อมูลของคุณอย่างถูกต้อง ... "
MemeDeveloper

4
ฐานข้อมูลไม่ได้ถูกเรียกว่าสัมพันธ์เนื่องจากความสัมพันธ์ระหว่างตาราง (ฐานข้อมูลทุกชนิดมีความสัมพันธ์ระหว่างเอนทิตี้!) แต่เนื่องจากตารางเองมีความสัมพันธ์ในแง่คณิตศาสตร์ ดูวิกิพีเดีย
Massimiliano Kraus

41

คีย์ต่างประเทศมีความสำคัญต่อโมเดลฐานข้อมูลเชิงสัมพันธ์


54
รูปแบบใช่ การใช้งานไม่จำเป็นเพียง แต่อาจมีประโยชน์
dkretz

4
ขออภัย แต่สาเหตุหลักที่ผู้พัฒนาแอปไม่ได้ใช้ระบบจัดการฐานข้อมูลเชิงวัตถุ (หรือที่รู้จักว่าฐานข้อมูล NoSQL!) อย่างกว้างขวางมากขึ้นก็เนื่องมาจากการลงทุนใน RDBMS ส่วนใหญ่แล้วฐานข้อมูล (ไม่ใช่ระบบจัดการฐานข้อมูล) เป็นโมเดลวัตถุระดับกลางที่มักเกี่ยวข้องกับแคชแบบกระจาย นี่คือที่การลบเรียงซ้อนความเป็นเจ้าของและการซิงโครไนซ์ของการเปลี่ยนแปลงจะเกิดขึ้นต่อไป RDBMS ใช้สำหรับการคงอยู่ของโมเดลวัตถุนี้เป็นหลักและโดยปกติหลังจากการฝึก ORM ที่ใช้ความอุตสาหะและไร้ค่า โมเดลความสัมพันธ์ส่วนใหญ่ไม่จำเป็น!
Sentinel

2
ไม่ปุ่มต่างประเทศไม่ได้บังคับให้ระบุ "relational"
Silver Moon

มันไม่ได้อธิบายอะไรมากนัก
Nae

29

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

นอกจากนี้ยังมีความจริงที่ว่าหลาย ๆ ระบบจำเป็นต้องเชื่อมต่อโดยตรงกับฐานข้อมูล - จากระบบอื่น ๆ ที่เพิ่งอ่านข้อมูล (Crystal Reports) ไปยังระบบที่แทรกข้อมูล (ไม่จำเป็นต้องใช้ API ที่ฉันออกแบบมามันอาจเขียนโดย ผู้จัดการโง่ที่เพิ่งค้นพบ VBScript และมีรหัสผ่าน SA สำหรับกล่อง SQL) ถ้าฐานข้อมูลนั้นไม่งี่เง่าเท่าที่ควรจะเป็น

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


2
ข้อมูลเชิงลึกที่ดี ฉันจะยืนยันว่าข้อมูลนี้สำคัญสำหรับแอปพลิเคชันทุกอย่างที่นำไปใช้จริง สิ่งเดียวที่แตกต่างคือผลลัพธ์ของข้อมูลที่เสียหาย พวกเขาสูงสำหรับแอปประเภทของคุณ ...
Jay Godse

20

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


คีย์ต่างประเทศทำให้การทดสอบอัตโนมัติยุ่งยากขึ้น

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

อย่างไรก็ตามaccountsมีคีย์ต่างประเทศให้contractsและcontractsมี FK ไปclientsและclientsมี FK ไปcitiesและcitiesมี FK statesเพื่อ

ตอนนี้ฐานข้อมูลจะไม่ช่วยให้คุณสามารถเรียกใช้การทดสอบของคุณโดยไม่ต้องตั้งค่าข้อมูลในสี่ของตารางที่ไม่เกี่ยวข้องกับการทดสอบของคุณ

มีอย่างน้อยสองมุมมองที่เป็นไปได้เกี่ยวกับเรื่องนี้:

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

อาจเป็นไปได้ที่จะปิดการตรวจสอบกุญแจต่างประเทศชั่วคราวขณะทำการทดสอบ MySQL อย่างน้อยสนับสนุนนี้


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

คุณควรใช้ตารางลิงก์ระหว่างเอนทิตีที่ไม่เกี่ยวข้องกันบางที หรือดำเนินการต่อ - แยก DBS: พิจารณาสถานการณ์ใน Service Oriented Architecture หรือ Microservice โดยที่แต่ละองค์ประกอบ (ลูกค้าบัญชีธุรกรรม) เป็นระบบที่แตกต่างกันและมี DB ต่างกัน ไม่มี FKs ระหว่างพวกเขาทั้งหมด ในกรณีนี้ควรใช้ FK เพื่อป้องกันข้อมูลที่ถูกโยงถึงในรูปแบบย่อยสำหรับข้อมูลแต่ละประเภท
JeeBee

3
นอกจากนี้ยังมี DBMS ที่อนุญาตให้มีข้อ จำกัด ในการเลื่อนเวลาเพื่อให้มีการตรวจสอบเฉพาะเมื่อคุณส่งมอบธุรกรรมทั้งหมดดังนั้นลำดับของการแทรก, อัปเดต, การลบจะไม่สำคัญ
a_horse_with_no_name

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

3
ฐานข้อมูลของคุณไม่ควรมีส่วนร่วมในการทดสอบหน่วยของคุณคุณควรเยาะเย้ยพวกเขา ในการทดสอบการรวมพวกเขาจะมีส่วนเกี่ยวข้อง แต่ปัญหาใด ๆ ที่นั่นเนื่องจากคีย์ต่างประเทศเป็นสิ่งที่ผู้ใช้ของคุณจะทำงานด้วยเว้นแต่ว่าคุณจะแก้ไข
Andreas Bergström

16

"พวกเขาสามารถลบระเบียนที่ยุ่งยากมากขึ้น - คุณไม่สามารถลบบันทึก" มาสเตอร์ "ที่มีระเบียนในตารางอื่น ๆ ที่คีย์ต่างประเทศจะละเมิดข้อ จำกัด นั้น"

สิ่งสำคัญคือต้องจำไว้ว่ามาตรฐาน SQL จะกำหนดการกระทำที่เกิดขึ้นเมื่อมีการลบหรือปรับปรุงคีย์ต่างประเทศ สิ่งที่ฉันรู้คือ:

  • ON DELETE RESTRICT- ป้องกันแถวใด ๆ ในตารางอื่นที่มีคีย์ในคอลัมน์นี้ไม่ให้ถูกลบ นี่คือสิ่งที่ Ken Ray อธิบายไว้ข้างต้น
  • ON DELETE CASCADE - หากแถวในตารางอื่นถูกลบให้ลบแถวใด ๆ ในตารางนี้ที่อ้างอิง
  • ON DELETE SET DEFAULT - หากลบแถวในตารางอื่นให้ตั้งค่าคีย์ต่างประเทศที่อ้างอิงถึงค่าเริ่มต้นของคอลัมน์
  • ON DELETE SET NULL - หากลบแถวในตารางอื่นให้ตั้งค่าคีย์ต่างประเทศที่อ้างอิงในตารางนี้เป็นโมฆะ
  • ON DELETE NO ACTION- รหัสต่างประเทศนี้ทำเครื่องหมายเพียงว่าเป็นรหัสต่างประเทศเท่านั้น ใช้สำหรับในตัวทำแผนที่ OR

ON UPDATEการกระทำเช่นนี้ยังนำไปใช้

ดูเหมือนว่าค่าเริ่มต้นจะขึ้นอยู่กับว่า เซิร์ฟเวอร์ที่คุณกำลังใช้


14

@ การเลื่อนขึ้น - นี่เป็นประเภทของความคิดที่ก่อให้เกิดฝันร้ายในการบำรุงรักษา

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


เพราะนักพัฒนาที่เกี่ยวข้องไม่เคยจัดการกับปัญหาที่ต้องใช้โมเดลเชิงสัมพันธ์ ปัญหาจำนวนมากไม่ได้โดยเฉพาะอย่างยิ่งการเรียงลำดับที่มากในเว็บ / "โซเชียลมีเดีย" การเขียนโปรแกรมประเภทที่เป็นที่นิยมในทุกวันนี้ หากสิ่งที่เลี้ยงลูกออกจากส่วนท้ายของกรอบ ORM เป็นไปตามปัญหาในอัลฟาก็ไม่น่าเป็นไปได้ที่ทุกคนจะคิดมากเกี่ยวกับการสร้างแบบจำลองข้อมูล ปัญหาดังกล่าวจำนวนมากได้รับการจัดการอย่างง่ายดายโดยร้านค้า K / V ฐานข้อมูลเอกสารหรือการทำให้เป็นอันดับวัตถุแบบตรง
zxq9

12

มีเหตุผลหนึ่งที่ดีที่ไม่ควรใช้: หากคุณไม่เข้าใจบทบาทหรือวิธีการใช้งาน

ในสถานการณ์ที่ไม่ถูกต้องข้อ จำกัด ที่สำคัญต่างประเทศสามารถนำไปสู่น้ำตกซ้ำซ้อนของอุบัติเหตุ หากใครบางคนลบบันทึกที่ไม่ถูกต้องการเลิกทำมันอาจกลายเป็นงานมหึมา

นอกจากนี้ในทางกลับกันเมื่อคุณต้องการลบบางสิ่งบางอย่างหากการออกแบบไม่ดีข้อ จำกัด อาจทำให้ล็อคทุกประเภทที่ป้องกันคุณไม่ได้


8
การลบแถวในการผลิตโดยไม่มีการสำรองข้อมูลไม่ใช่อาร์กิวเมนต์ที่ถูกต้อง หากคุณไม่เข้าใจพวกเขาคุณควรพิจารณาเรียนรู้เกี่ยวกับมันแทนที่จะละไว้
Guillaume

2
@ Guillaume ฉันคิดว่าคำตอบของเขาเป็นคำพูดประชดประชันไม่ใช่คำตอบ: ถ้าคุณไม่เข้าใจพวกเขาก็อย่าใช้มัน แต่แน่นอนคุณควรเข้าใจและใช้พวกเขา
เบนจามิน

^ นี่ มันเป็นเครื่องมือที่มีประโยชน์ แต่อยู่ในมือของมือใหม่พวกมันเป็นเครื่องมือที่อันตราย
Kent Fredric

11

ไม่มีเหตุผลที่ดีที่จะไม่ใช้พวกเขา ... เว้นแต่ว่าแถวเด็กกำพร้าจะไม่ใช่เรื่องใหญ่สำหรับคุณ


11
ทำไมเด็กกำพร้าถึงเป็นเรื่องใหญ่
Seun Osewa

2
แล้วมัลติเธรดล่ะ พวกเขาสามารถทำให้ฝันร้ายแบบมัลติเธรดในบางสถานการณ์ ในแอปพลิเคชันที่ซับซ้อนที่มีหลายเธรดที่เขียนฐานข้อมูลที่อาจพบวัตถุที่ต้องอ้างอิงซึ่งกันและกันจะเป็นการดีกว่าในการควบคุม Referential Integrity ในตรรกะทางธุรกิจโดยเฉพาะถ้าตารางกำลังจะคงที่หลังจากนั้น
Keith Pinson

ฉันเห็นด้วย. นอกจากนี้ฉันชอบที่จะมีแถวโอแฮนที่ฉันสามารถกู้คืนได้ในเวลาต่อมามากกว่าที่จะให้พวกเขาทิ้งอย่างไร้ความปราณี
PedroD

4

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

ผ่านวงจรชีวิตของแอปพลิเคชันการอ้างอิงและข้อมูลการตรวจสอบข้อ จำกัด การเก็บรวบรวมข้อมูลตำรวจผ่านแอปพลิเคชันโดยเฉพาะอย่างยิ่งเมื่อข้อกำหนดใหม่ผลักดันการเปลี่ยนแปลงแอปพลิเคชันเชิงตรรกะ

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

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

QUERY PERFORMANCE - หากตารางถูกรวมเข้ากับ foreign key ให้ระลึกถึงความจริงที่ว่าคอลัมน์คีย์ต่างประเทศนั้นไม่ได้ถูก INDEXED (แม้ว่าคีย์หลักนั้นจะถูกทำดัชนีโดยการกำหนด) ด้วยการทำดัชนีคีย์ต่างประเทศสำหรับเรื่องนั้นโดยการทำดัชนีคีย์ใด ๆ และการเข้าร่วมตารางบนดัชนีที่จัดทำขึ้นจะช่วยให้มีประสิทธิภาพที่ดีขึ้นไม่ใช่โดยการเข้าร่วมกับคีย์ที่ไม่ได้จัดทำดัชนีด้วยข้อ จำกัด ของคีย์ต่างประเทศ

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


ฉันไม่รู้ว่าทำไมแทรก 3 บรรทัดใหม่ขึ้นมาแทนที่ช่องว่างและการเปลี่ยนสองคำนับเป็น '67% คือ Jonathan Leffler' แต่ฉันไม่คิดว่าฉันทำอะไรแบบนี้ ข้อความหลักมีส่วนร่วมโดย @jay (ผู้ใช้ 183837)
Jonathan Leffler

ฉันแค่คิดว่า paragrahps จะไม่ทำงานที่นี่เหมือนในเว็บไซต์อื่น ๆ ส่วนใหญ่ ดังนั้นฉันจึงใส่ทั้งหมดเป็นหนึ่งเดียวโดยใช้ตัวหนาสำหรับการเปลี่ยนแปลงการไหล
jasbir L

3

เหตุผลเพิ่มเติมในการใช้ Foreign Keys: - อนุญาตให้ใช้ฐานข้อมูลได้มากขึ้น

เหตุผลเพิ่มเติมที่จะไม่ใช้ Foreign Keys: - คุณพยายามล็อคลูกค้าไว้ในเครื่องมือของคุณโดยลดการใช้ซ้ำ


3

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

มันจะดีกว่าที่จะหลีกเลี่ยง FKs แต่ความเสี่ยงจะต้องได้รับการจัดการโดยโปรแกรมเมอร์


8
ฉันไม่คิดว่าแนวทางการพัฒนาของธนาคารขนาดใหญ่จะกำหนดมาตรฐานทองคำ
Adriaan Koster

3

"ก่อนเพิ่มระเบียนให้ตรวจสอบว่ามีระเบียนที่เกี่ยวข้องอยู่ในตารางอื่น" เป็นตรรกะทางธุรกิจ

นี่คือสาเหตุบางประการที่คุณไม่ต้องการในฐานข้อมูล:

  1. หากกฎธุรกิจเปลี่ยนแปลงคุณต้องเปลี่ยนฐานข้อมูล ฐานข้อมูลจะต้องสร้างดัชนีใหม่ในหลายกรณีและจะช้าในตารางขนาดใหญ่ (การเปลี่ยนกฎรวมถึง: อนุญาตให้แขกโพสต์ข้อความหรืออนุญาตให้ผู้ใช้ลบบัญชีของพวกเขาแม้จะมีการโพสต์ความคิดเห็น ฯลฯ )

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

  3. TDD ในการทดสอบหน่วยคุณสามารถแทนที่ฐานข้อมูลสำหรับ mocks และทดสอบการทำงาน หากคุณมีตรรกะทางธุรกิจใด ๆ ในฐานข้อมูลของคุณคุณไม่ได้ทำการทดสอบอย่างสมบูรณ์และจะต้องทดสอบกับฐานข้อมูลหรือทำซ้ำตรรกะทางธุรกิจในรหัสเพื่อการทดสอบทำซ้ำตรรกะและเพิ่มโอกาสของตรรกะที่ไม่ทำงานใน วิธีการเดียวกัน.

  4. ใช้ตรรกะของคุณใหม่ด้วยแหล่งข้อมูลที่แตกต่างกัน หากไม่มีตรรกะในฐานข้อมูลแอปพลิเคชันของฉันสามารถสร้างวัตถุจากบันทึกจากฐานข้อมูลสร้างจากเว็บเซอร์วิสไฟล์ json หรือแหล่งอื่น ๆ ฉันต้องการสลับการใช้งาน mapper data และสามารถใช้ตรรกะทางธุรกิจทั้งหมดของฉันกับแหล่งใด ๆ หากมีลอจิกในฐานข้อมูลนี่เป็นไปไม่ได้และคุณต้องใช้ลอจิกที่เลเยอร์ mapper ข้อมูลหรือในตรรกะทางธุรกิจ ไม่ว่าด้วยวิธีใดคุณต้องมีการตรวจสอบในรหัสของคุณ หากไม่มีตรรกะในฐานข้อมูลฉันสามารถปรับใช้แอปพลิเคชันในสถานที่ต่าง ๆ โดยใช้ฐานข้อมูลที่แตกต่างกันหรือการใช้งานไฟล์แบน


2

ฉันเห็นด้วยกับคำตอบก่อนหน้าว่าพวกเขามีประโยชน์ในการรักษาความสอดคล้องของข้อมูล อย่างไรก็ตามมีโพสต์ที่น่าสนใจโดย Jeff Atwood เมื่อหลายสัปดาห์ก่อนที่กล่าวถึงข้อดีข้อเสียของข้อมูลที่เป็นมาตรฐานและสม่ำเสมอ

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


Jeff ทำคะแนนได้ดี อย่างไรก็ตาม Dan Chak ใน "Enterprise Rails" แสดงวิธีการออกแบบตารางแคชซึ่งเป็นข้อมูลที่ไม่ได้มาตรฐาน คำค้นหาทำงานเร็วและหากไม่จำเป็นต้องรีเฟรชตารางก็ใช้งานได้ดี ฉันพบว่าหากข้อมูลของคุณขับเคลื่อนพฤติกรรม (เช่นสถานะแอปพลิเคชัน) ของแอปพลิเคชันของคุณคุณต้องมีข้อมูลที่จะทำให้เป็นมาตรฐานมากที่สุดเท่าที่จะทำได้เพราะมิฉะนั้นข้อมูลที่ไม่สอดคล้องกันจะนำไปสู่
Jay Godse

ข้อมูล denormalised คลังสินค้าอาจจะมีการใช้งานเมื่ออ่านปริมาณข้อมูลขนาดใหญ่ในสอดคล้องเส้นทางการเข้าถึงที่คาดการณ์ไว้ ในสถานการณ์อื่น ๆ ทั้งหมดนี่เป็นความเข้าใจผิดที่เป็นอันตราย
Peter Wone

2

ฐานข้อมูล Clarify เป็นตัวอย่างของฐานข้อมูลเชิงพาณิชย์ที่ไม่มีคีย์หลักหรือคีย์ต่างประเทศ

http://www.geekinterview.com/question_details/18869

สิ่งที่ตลกคือเอกสารทางเทคนิคมีความยาวมากพอที่จะอธิบายว่าตารางเกี่ยวข้องอย่างไรคอลัมน์ใดบ้างที่จะใช้เพื่อเข้าร่วมเป็นต้น

ในคำอื่น ๆ ที่พวกเขาจะได้เข้าร่วมตารางที่มีการประกาศอย่างชัดเจน (DRI) แต่พวกเขาเลือกที่จะไม่

ดังนั้นฐานข้อมูล Clarify เต็มไปด้วยความไม่สอดคล้องกันและมีประสิทธิภาพต่ำกว่า

แต่ฉันคิดว่ามันทำให้นักพัฒนาทำงานได้ง่ายขึ้นโดยไม่ต้องเขียนโค้ดเพื่อจัดการกับ Referential Integrity เช่นการตรวจสอบแถวที่เกี่ยวข้องก่อนที่จะลบเพิ่ม

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


รหัสที่จะจัดการกับการตรวจสอบความสมบูรณ์ของการอ้างอิงที่ล้มเหลวมีขนาดเล็กกว่ารหัสในการจัดการข้อมูลที่ไม่สอดคล้องกัน
Jay Godse

@ เจย์เห็นด้วย! อย่าคิดว่าฉันกำลังสนับสนุนวิธีการนี้
Ed Guiness

2

ฉันรู้ฐานข้อมูล Oracle เท่านั้นไม่มีใครอื่นและฉันสามารถบอกได้ว่า Foreign Keys มีความสำคัญต่อการรักษาความถูกต้องของข้อมูล ก่อนที่จะแทรกข้อมูลโครงสร้างข้อมูลจะต้องทำและแก้ไขให้ถูกต้อง เมื่อทำเสร็จแล้วและสร้างคีย์หลักและกุญแจต่างประเทศทั้งหมด - งานเสร็จ!

แถวที่ถูกโยงถึง? ไม่เคยเห็นว่าในชีวิตของฉัน นอกเสียจากโปรแกรมเมอร์ที่ไม่ดีจะลืมรหัสต่างประเทศหรือถ้าเขาใช้มันในระดับอื่น ทั้งสองเป็น - ในบริบทของ Oracle - ข้อผิดพลาดขนาดใหญ่ซึ่งจะนำไปสู่การทำสำเนาข้อมูล, ข้อมูลเด็กกำพร้าและทำให้: ข้อมูลเสียหาย ฉันนึกภาพไม่ออกว่าฐานข้อมูลไม่มี FK ที่บังคับใช้ ดูเหมือนความสับสนวุ่นวายสำหรับฉัน มันเหมือนกับระบบอนุญาตของ Unix: ลองจินตนาการว่าทุกคนเป็นรูต คิดถึงความโกลาหล

Foreign Keys มีความสำคัญเช่นเดียวกับ Primary Keys มันเหมือนกับว่า: ถ้าเราลบคีย์หลัก? ความวุ่นวายทั้งหมดจะเกิดขึ้น นั่นคือสิ่งที่ คุณไม่สามารถย้ายความรับผิดชอบหลักหรือคีย์ต่างประเทศไปยังระดับการเขียนโปรแกรมจะต้องอยู่ในระดับข้อมูล

ข้อเสียหรือไม่ ใช่แล้ว! เพราะในส่วนแทรกการตรวจสอบก็จะมีมากขึ้น แต่ถ้าความถูกต้องของข้อมูลมีความสำคัญมากกว่าประสิทธิภาพการทำงานมันก็ไม่ใช่เรื่องง่าย ปัญหาเกี่ยวกับประสิทธิภาพของ Oracle เกี่ยวข้องกับดัชนีซึ่งมาพร้อมกับ PK และ FK


1

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

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

ฉันเชื่อว่าข้อดีในการใช้กุญแจ fireign มีค่ามากกว่าข้อเสียที่ควรทราบ


5
ฉันมักจะลบสิ่งต่าง ๆ อย่างไรก็ตาม เพียงทำเครื่องหมายว่ามีบิต "Visible / active"
Dana

+1 สำหรับ "ผมเชื่อว่าข้อได้เปรียบในการใช้คีย์ fireign เมื่อเทียบกับข้อเสียควรใด ๆ"
เอียนบอยด์

2
คุณไม่เคยเปลี่ยนคุณค่าของคีย์หลัก คุณลบทั้งแถวและสร้างใหม่ในลักษณะที่แตกต่างกัน หากคุณคิดว่าคุณจำเป็นต้องเปลี่ยนสคีมาของคุณนั้นมีข้อบกพร่อง
DanMan

การเปลี่ยนชื่อลูกค้าจะไม่เจ็บปวดเลยหากรหัสต่างประเทศของคุณตั้งอยู่ที่ CustomerId (PK) ในตารางคำสั่งซื้อ วิธีเดียวที่จะเจ็บปวดคือถ้าตั้งค่า FK ใน CustomerName ซึ่งไม่ควรเป็นกรณี IMHO
KeyOfJ

1

การตรวจสอบข้อ จำกัด กุญแจต่างประเทศใช้เวลา CPU สักครู่ดังนั้นผู้ใช้บางคนจึงไม่ใช้ปุ่มต่างประเทศเพื่อรับประสิทธิภาพพิเศษ


6
เวลา CPU ใช้เวลาเท่าใดในการลบข้อมูลที่ซ้ำกันและไม่สอดคล้องกัน
Ed Guiness

ใช่นี่เป็นเรื่องจริง ในระบบที่ฉันทำงานอยู่เราต้องแทรกข้อมูล 10 - 40 gigs ต่อครั้งลงในฐานข้อมูลและประสิทธิภาพของ FK ทั้งแบบมีและไม่มีให้เห็นตลอดเวลา
Paul Mendoza

1

ฉันเคยได้ยินเรื่องนี้เช่นกัน - จากคนที่ลืมใส่ดัชนีในคีย์ต่างประเทศของพวกเขาแล้วบ่นว่าการดำเนินการบางอย่างช้า (เพราะการตรวจสอบข้อ จำกัด สามารถใช้ประโยชน์จากดัชนีใด ๆ ) ดังนั้นสรุป: ไม่มีเหตุผลที่ดีที่จะไม่ใช้กุญแจต่างประเทศ ฐานข้อมูลที่ทันสมัยทั้งหมดสนับสนุนการลบแบบเรียงซ้อนดังนั้น ...


9
ฉันเชื่อว่าเหตุผลที่แท้จริงของข้อ จำกัด FKs ไม่ได้ถูกใช้โดยบางคน (ส่วนใหญ่จากมุมมองของฉัน) คือความเกียจคร้านภายใต้ข้ออ้างที่ว่าพวกเขาสามารถปกป้องความขี้เกียจของพวกเขาด้วยอาร์กิวเมนต์การออมของพวกเขา ฉันเชื่อมั่นอย่างแรงกล้าว่าค่าใช้จ่ายส่วนใหญ่ของ บริษัท ของเรานั้นเกิดจากการบังคับใช้ข้อ จำกัด FK และผลกระทบระลอกคลื่นที่เกิดขึ้นผ่าน บริษัท Lack of Unique Keys เป็นอีกสิ่งหนึ่งที่ทำให้ฉันติดกับขั้นตอนการจัดเก็บมากกว่า 2000+ บรรทัดที่มี IFs ที่ซ้อนกัน 12 ระดับและการเยื้องแบบสุ่ม แต่ฉันจะหยุดทันที
ชาด

1

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

แก้ไข:เดาของฉันคือเขาอ้างถึงข้อ จำกัดกุญแจต่างประเทศไม่ใช่กุญแจต่างประเทศเป็นแนวคิด


Nope เขาไม่ชอบกุญแจจริง!
ljs

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

ใช่ฉันตกใจเมื่อฉันได้ยินเขา เขาอาจใช้ลิ้นโดยไม่ตั้งใจ บางทีเขาอาจจะโพสต์ที่นี่และชี้แจงในบางขั้นตอน :-)
ljs

1

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


1

ฉันต้องให้ความเห็นส่วนใหญ่เป็นอันดับสองที่นี่ Foreign Keys เป็นรายการที่จำเป็นเพื่อให้แน่ใจว่าคุณมีข้อมูลด้วยความซื่อสัตย์ ตัวเลือกต่าง ๆ สำหรับ ON DELETE และ ON UPDATE จะช่วยให้คุณสามารถหลีกเลี่ยง "down fall" ที่ผู้คนพูดถึงเกี่ยวกับการใช้

ฉันพบว่าใน 99% ของโครงการทั้งหมดของฉันฉันจะมี FK เพื่อบังคับใช้ความถูกต้องของข้อมูลอย่างไรก็ตามมีโอกาสที่หายากเหล่านั้นที่ฉันมีลูกค้าที่ต้องเก็บข้อมูลเก่าไว้โดยไม่คำนึงว่ามันแย่แค่ไหน ... แต่จากนั้นฉันใช้เวลาเขียนโค้ดที่ได้รับข้อมูลที่ถูกต้องเท่านั้นดังนั้นมันจึงไม่มีจุดหมาย


1

วิธีการเกี่ยวกับการบำรุงรักษาและความมั่นคงตลอดอายุการใช้งาน? ข้อมูลส่วนใหญ่มีอายุการใช้งานที่ยาวนานกว่าแอพพลิเคชั่นที่ทำการใช้งาน ความสัมพันธ์และความถูกต้องของข้อมูลมีความสำคัญมากเกินกว่าที่จะออกไปด้วยความหวังว่าทีมนักพัฒนาซอฟต์แวร์คนต่อไปจะทำให้ถูกต้องในรหัสแอพ หากคุณไม่ได้ทำงานกับ db ด้วยข้อมูลสกปรกที่ไม่เคารพความสัมพันธ์ตามธรรมชาติคุณจะ ความสำคัญของความถูกต้องของข้อมูลจะชัดเจนมาก


1

ฉันคิดว่าคีย์ต่างประเทศเป็นสิ่งจำเป็นในฐานข้อมูลส่วนใหญ่ ข้อเสียเปรียบเพียงอย่างเดียว (นอกเหนือจากความนิยมในประสิทธิภาพที่มาพร้อมกับการบังคับใช้ความสอดคล้องกัน) คือการมี foreign key ช่วยให้ผู้ใช้สามารถเขียนรหัสที่สมมติว่ามี foreign key ที่ใช้งานได้ ที่ไม่ควรได้รับอนุญาต

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

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

หากเปิดใช้งานคุณลักษณะเหล่านั้นรหัสของคุณจะเลียนแบบและคุณจะเสียประสิทธิภาพเล็กน้อย

ดังนั้นสรุป .... คีย์ต่างประเทศมีความสำคัญหากคุณต้องการฐานข้อมูลที่สอดคล้องกัน คีย์ต่างประเทศไม่ควรถูกสันนิษฐานว่ามีอยู่หรือทำงานในโค้ดที่คุณเขียน


1

ฉันก้องคำตอบของมิทรี - ดีมาก

สำหรับผู้ที่กังวลเกี่ยวกับค่าใช้จ่ายด้านประสิทธิภาพที่ FK นำมานั้นมักจะมีวิธี (ใน Oracle) คุณสามารถรับข้อได้เปรียบของตัวเพิ่มประสิทธิภาพการสืบค้นของข้อ จำกัด FK โดยไม่มีค่าใช้จ่ายในการตรวจสอบความถูกต้องของข้อ จำกัด นั่นคือการสร้างข้อ จำกัด FK ด้วยคุณลักษณะ RELY DISABLE NOVALIDATE ซึ่งหมายความว่าตัวเพิ่มประสิทธิภาพการสืบค้นจะสันนิษฐานว่ามีการบังคับใช้ข้อ จำกัด เมื่อสร้างคิวรีโดยไม่มีฐานข้อมูลบังคับใช้ข้อ จำกัด จริง ๆ คุณต้องระวังให้มากที่นี่เพื่อรับผิดชอบเมื่อคุณเติมตารางด้วยข้อ จำกัด FK เช่นนี้เพื่อให้แน่ใจว่าคุณไม่มีข้อมูลในคอลัมน์ FK ของคุณที่ละเมิดข้อ จำกัด ดังเช่นที่คุณทำ อาจได้รับผลลัพธ์ที่ไม่น่าเชื่อถือจากข้อความค้นหาที่เกี่ยวข้องกับตารางที่ข้อ จำกัด FK นี้เปิดอยู่

ฉันมักจะใช้กลยุทธ์นี้ในบางตารางใน data schema ของฉัน แต่ไม่ใช่ใน schema การจัดเตรียมแบบรวม ฉันแน่ใจว่าตารางที่ฉันกำลังคัดลอกข้อมูลจากนั้นมีการบังคับใช้ข้อ จำกัด เดียวกันหรือรูทีน ETL บังคับใช้ข้อ จำกัด


1

ผู้คนจำนวนมากที่ตอบคำถามที่นี่รับทราบถึงความสำคัญของความสมบูรณ์ของการอ้างอิงที่นำมาใช้ผ่านข้อ จำกัด ในการอ้างอิง การทำงานกับฐานข้อมูลขนาดใหญ่ที่มี Referential Integrity ไม่ได้ผล Oracle ดูเหมือนไม่ดีโดยเฉพาะอย่างยิ่งในการลบซ้อน กฎง่ายๆของฉันคือแอพพลิเคชั่นไม่ควรอัพเดทฐานข้อมูลโดยตรงและควรผ่านขั้นตอนการจัดเก็บ สิ่งนี้จะเก็บรหัสฐานไว้ในฐานข้อมูลและหมายความว่าฐานข้อมูลยังคงความสมบูรณ์อยู่

ในกรณีที่แอปพลิเคชันจำนวนมากอาจเข้าถึงฐานข้อมูลปัญหาจะเกิดขึ้นเนื่องจากข้อ จำกัด ของ Referential Integrity แต่สิ่งนี้จะอยู่ในการควบคุม

มีปัญหาที่กว้างขึ้นเช่นกันนักพัฒนาแอปพลิเคชันอาจมีข้อกำหนดที่แตกต่างกันมากซึ่งผู้พัฒนาฐานข้อมูลอาจไม่จำเป็นต้องคุ้นเคย


5
"แอปพลิเคชันไม่ควรอัปเดตฐานข้อมูลโดยตรงและควรผ่านขั้นตอนการจัดเก็บสิ่งนี้จะเก็บรหัสฐานไว้ในฐานข้อมูลและหมายความว่าฐานข้อมูลยังคงความสมบูรณ์อยู่" <- มีข้อสันนิษฐานว่าตรรกะในขั้นตอนการจัดเก็บไม่สามารถละเมิดความสมบูรณ์ของข้อมูลซึ่งเป็นเพียงผิดธรรมดา
Tim Gautier

1

หากคุณมั่นใจอย่างแน่นอนว่าระบบฐานข้อมูลพื้นฐานจะไม่เปลี่ยนแปลงในอนาคตฉันจะใช้คีย์ต่างประเทศเพื่อรับรองความถูกต้องของข้อมูล

แต่นี่เป็นอีกเหตุผลในชีวิตจริงที่ดีมากที่จะไม่ใช้กุญแจต่างประเทศเลย:

คุณกำลังพัฒนาผลิตภัณฑ์ซึ่งควรสนับสนุนระบบฐานข้อมูลที่แตกต่างกัน

หากคุณกำลังทำงานกับ Entity Framework ซึ่งสามารถเชื่อมต่อกับระบบฐานข้อมูลที่แตกต่างกันมากมายคุณอาจต้องการสนับสนุนฐานข้อมูลเซิร์ฟเวอร์แบบไม่มีเซิร์ฟเวอร์ "โอเพ่นซอร์สฟรี" ฐานข้อมูลเหล่านี้บางอย่างอาจไม่สนับสนุนกฎกุญแจต่างประเทศของคุณ (อัปเดตลบแถว ... )

สิ่งนี้สามารถนำไปสู่ปัญหาต่าง ๆ :

1. ) คุณอาจพบข้อผิดพลาดเมื่อโครงสร้างฐานข้อมูลถูกสร้างหรืออัปเดต อาจจะมีเพียงข้อผิดพลาดที่เงียบเนื่องจากคีย์ต่างประเทศของคุณจะถูกละเว้นโดยระบบฐานข้อมูล

2. ) ถ้าคุณพึ่งพาคีย์ต่างประเทศคุณจะสามารถทำการตรวจสอบความสมบูรณ์ของข้อมูลในตรรกะทางธุรกิจของคุณได้น้อยลงหรือไม่มีเลย ตอนนี้หากระบบฐานข้อมูลใหม่ไม่สนับสนุนกฎกุญแจต่างประเทศเหล่านี้หรือเพียงแค่ทำงานในวิธีที่แตกต่างกันคุณต้องเขียนตรรกะทางธุรกิจของคุณใหม่

คุณอาจถามว่า: ใครต้องการระบบฐานข้อมูลที่แตกต่างกัน ไม่ใช่ทุกคนที่จะสามารถซื้อหรือต้องการ SQL-Server ที่ถูกเป่าเต็มในเครื่องของเขา นี่คือซอฟต์แวร์ที่ต้องได้รับการดูแลรักษา คนอื่นมีเวลาและเงินลงทุนไปแล้วในระบบฐานข้อมูลอื่น ฐานข้อมูลแบบไม่ใช้เซิร์ฟเวอร์เหมาะสำหรับลูกค้าขนาดเล็กในเครื่องเดียว

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


0

ฉันมักจะคิดว่ามันขี้เกียจที่จะไม่ใช้มัน ฉันถูกสอนว่าควรจะทำ แต่แล้วฉันไม่ได้ฟังการสนทนาของโจเอล เขาอาจมีเหตุผลที่ดีฉันไม่รู้


มันเป็นคำพูดที่เกินความคาดหมายมากกว่าการอภิปรายแม้ว่าบางทีฉันควรค้นคว้าอย่างแม่นยำถึงสิ่งที่เขาคิดเกี่ยวกับเรื่องนี้อย่างอิสระ! อย่างไรก็ตามฉันสงสัยเกี่ยวกับความเห็นของชุมชนในหัวข้อนี้เช่นกัน!
ljs

0

ครั้งหนึ่งเมื่อ FK อาจทำให้คุณมีปัญหาคือเมื่อคุณมีข้อมูลประวัติที่อ้างอิงถึงคีย์ (ในตารางการค้นหา) แม้ว่าคุณจะไม่ต้องการให้มีคีย์อีกต่อไป
เห็นได้ชัดว่าวิธีแก้ปัญหาคือการออกแบบสิ่งต่าง ๆ ให้ดีขึ้น แต่ฉันกำลังคิดถึงสถานการณ์ในโลกแห่งความเป็นจริงที่นี่ซึ่งคุณไม่สามารถควบคุมโซลูชันทั้งหมดได้เสมอ
ตัวอย่างเช่น: บางทีคุณอาจมีตารางค้นหาcustomer_typeที่แสดงประเภทลูกค้าที่แตกต่างกัน - สมมติว่าคุณจำเป็นต้องลบลูกค้าบางประเภท แต่ (เนื่องจากข้อ จำกัด ทางธุรกิจ) ไม่สามารถอัปเดตซอฟต์แวร์ไคลเอ็นต์และไม่มีใครสนใจสถานการณ์นี้ เมื่อพัฒนาซอฟต์แวร์ข้อเท็จจริงที่ว่ามันเป็นรหัสต่างประเทศในตารางอื่น ๆ อาจทำให้คุณไม่สามารถลบแถวได้แม้ว่าคุณจะรู้ข้อมูลในอดีตที่อ้างอิงว่ามันไม่เกี่ยวข้อง
หลังจากที่ถูกไฟไหม้ครั้งนี้ไม่กี่ครั้งคุณอาจจะห่างจากการบังคับใช้ฐานข้อมูล
(ฉันไม่ได้บอกว่านี่เป็นสิ่งที่ดี - เพียงแค่ให้เหตุผลว่าทำไมคุณอาจตัดสินใจหลีกเลี่ยงข้อ จำกัด FK และฐานข้อมูลโดยทั่วไป)


หากฉันเข้าใจสิ่งที่คุณพยายามจะพูดฉันคิดว่าคำตอบของฉันคือการลบบันทึกในตารางการค้นหาอย่างมีเหตุผลหรือเก็บถาวรไม่มีข้อมูลประวัติที่เกี่ยวข้องอีกต่อไปและเก็บบันทึกการค้นหาด้วยเช่นกัน
ชาด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.