คุณชอบคีย์หลักของคุณอย่างไร? [ปิด]


89

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

  1. Int / BigInt ซึ่งการเพิ่มอัตโนมัติเป็นคีย์หลักที่ดีพอ
  2. ควรมีอย่างน้อย 3 คอลัมน์ที่ประกอบเป็นคีย์หลัก
  3. Id, GUID และตัวระบุแถวที่มนุษย์อ่านได้ทั้งหมดควรได้รับการปฏิบัติที่แตกต่างกัน

แนวทางที่ดีที่สุดสำหรับ PK คืออะไร? จะดีมากถ้าคุณสามารถแสดงความคิดเห็นของคุณได้ มีแนวทางที่ดีกว่าข้างต้นหรือไม่?

แก้ไข: ใครมีตัวอย่าง / อัลกอริทึมง่ายๆในการสร้างตัวระบุที่มนุษย์อ่านได้สำหรับแถวที่ปรับขนาดได้ดี?


1
เนื่องจากนี่เป็นเรื่องส่วนตัวจึงควรเป็นวิกิชุมชน
John Sheehan

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

@ S.Lott PK(NEWID(),NEWID(),NEWID());-)

@pst: ทำไมจึงเป็นข้อกำหนด? ทำไมต้องมีสามคอลัมน์ใน PK? ทำไมหนึ่งหรือสี่?
ล็อตต์

ฉันเห็น PK สามคอลัมน์ดูเหมือน ... LocalID (Auto Increment int), GlobalID (GUID), ForeignId (คีย์ต่างประเทศเช่น RolesType) เป็นต้น LocalID + ForiegnId อาจเป็นคีย์ผสม Guid ใช้สำหรับเว็บไซต์ / บริการอื่น ๆ โดยส่วนตัวฉันจะไม่ทำสิ่งนี้ฉันแค่ใช้ Guid + ForiegnId
เจอราด

คำตอบ:


78

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

Autoincrement ints ควรเป็นค่าเริ่มต้นของคุณและการไม่ใช้ควรเป็นธรรม


3
ไม่จำเป็นต้องใช้ GUID เพียงแค่เปลี่ยนขั้นตอนเป็น 10 หรือ 20 หรือจำนวนเซิร์ฟเวอร์ที่คุณจะต้องซิงค์ด้วยในอนาคต
Robert C.Barth

44
อย่างน้อย 90% ไม่จำเป็นต้องใช้ GUID และทำให้สิ้นเปลืองพื้นที่
Jonathan Leffler

8
ฉันรู้สึกว่า GUID เป็นสิ่งที่เกินความจริง ไม่เคยจำเป็นต้องมี GUID เป็นคีย์หลักของฉันเลย
Cyril Gupta

7
หรือแทนที่จะเสียพื้นที่และเสี่ยงต่อการชนกับ GUID ให้สร้างคีย์ผสมของคีย์หลักดั้งเดิมและตัวระบุขนาดเล็กโดยที่ตัวระบุขนาดเล็กจะแตกต่างกันสำหรับแหล่งที่มาของการซิงค์แต่ละรายการ
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
ร้านค้าที่ฉันทำงานเพื่อใช้ GUID สำหรับทุกอย่างแม้ว่าจะมีตัวระบุสาธารณะเช่นรหัสประเทศหรือภาษา ISO ก็ตาม และแม้ว่าบูลีนหรือCHAR(1)จะเพียงพอแล้วsexก็ตาม ไม่จำเป็นต้องพูดว่ามันเป็นฝันร้ายที่ต้องทำงานด้วย
Lumi

56

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

ตัวอย่างเช่นในตารางชื่อและรหัสสถานะ (US) ชื่อหรือรหัสอาจเป็นคีย์หลัก - ประกอบด้วยคีย์ตัวเลือกสองคีย์ที่แตกต่างกันและหนึ่งในนั้น (โดยปกติจะเป็นรหัสที่สั้นกว่า) จะถูกเลือกเป็น คีย์หลัก ในทฤษฎีการพึ่งพาการทำงาน (และเข้าร่วมการอ้างอิง - 1NF ถึง 5NF - เป็นคีย์ตัวเลือกที่มีความสำคัญมากกว่าคีย์หลัก

สำหรับตัวอย่างที่โต้แย้งโดยทั่วไปชื่อของมนุษย์มักเป็นตัวเลือกที่ไม่ถูกต้องสำหรับคีย์หลัก มีหลายคนที่ใช้ชื่อ "John Smith" หรือชื่ออื่นที่คล้ายกัน แม้จะคำนึงถึงชื่อกลาง (จำไว้ว่าไม่ใช่ทุกคนที่มีชื่อเดียวเช่นฉันไม่มี) มีขอบเขตมากมายสำหรับการทำซ้ำ ดังนั้นผู้คนจึงไม่ใช้ชื่อเป็นคีย์หลัก พวกเขาประดิษฐ์กุญแจเทียมเช่นหมายเลขประกันสังคม (SSN) หรือหมายเลขพนักงานและใช้เพื่อกำหนดตัวบุคคล

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

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

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

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

นี่เป็นมุมมองที่ค่อนข้างยากในบางประเด็น

ฉันไม่มีปัญหากับการใช้ GUID เมื่อจำเป็น แต่มักจะมีขนาดใหญ่ (เช่น 16-64 ไบต์) และมักใช้บ่อยเกินไป บ่อยครั้งที่ค่า 4 ไบต์ที่ดีอย่างสมบูรณ์แบบก็เพียงพอแล้ว การใช้ GUID ซึ่งค่า 4 ไบต์จะเพียงพอทำให้สิ้นเปลืองเนื้อที่ดิสก์และทำให้การเข้าถึงข้อมูลที่จัดทำดัชนีช้าลงเนื่องจากมีค่าน้อยกว่าต่อหน้าดัชนีดังนั้นดัชนีจะมีความลึกและต้องอ่านหน้ามากขึ้นเพื่อไปที่ ข้อมูล.


10
เกี่ยวกับตัวอย่างของคุณที่มีชื่อรัฐในสหรัฐอเมริกาฉันต้องการรหัสตัวแทนแยกต่างหากเนื่องจากรหัสเป็นสิ่งที่อยู่นอกเหนือการควบคุมของคุณ หากควรเปลี่ยนด้วยเหตุผลใดก็ตามที่คุณมีปัญหา
Dirk Vollmar

1
(ต่อ) ตัวอย่างเช่นเยอรมนีแทนที่ระบบรหัสไปรษณีย์ 4 หลักด้วยระบบ 5 หลักย้อนกลับไปในปี 1990 หลังจากการรวมกันอีกครั้ง
Dirk Vollmar

@divo: ฉันเป็นผู้สนับสนุนคีย์เทียม / ตัวแทน แต่ถึงแม้ฉันจะไม่เห็นการเปลี่ยนรหัสไปรษณีย์ 4 หลักถึง 5 หลักว่าเป็นตัวอย่างที่ดี โดยทั่วไปรหัสไปรษณีย์ไม่ได้ใช้เป็นกุญแจสำคัญ (ครั้งสุดท้ายที่คุณต้องค้นหาตาราง PostalCode เพื่อค้นหาบางอย่างเกี่ยวกับรหัสนั้นคือเมื่อใดไม่มันเกือบจะถูกใช้เป็นส่วนหนึ่งของที่อยู่โดยไม่ต้องอ้างอิงในตารางอื่น ๆ ฉันจะบอกว่าข้อเสนอแนะของคุณเกือบจะเทียบเท่ากับการใช้ คีย์ตัวแทนสำหรับที่อยู่ตัวเอง)
ErikE

@Emtucifor: ใช่ ZIP อาจไม่ใช่ตัวอย่างที่ใช้ได้จริง แต่ประเด็นของฉันก็คือถ้าส่วนหนึ่งของรหัสตัวแทนของคุณอยู่นอกเหนือการควบคุมและการเปลี่ยนแปลงไม่ว่าด้วยเหตุผลใดคุณก็มีปัญหา ลองนึกถึงใครบางคนที่สร้างรูปแบบหมายเลขประกันสังคมใหม่โครงการ ISSN ใหม่หรือ - อาจจะเป็นจริงมากขึ้น - บริษัท ตัดสินใจที่จะสร้างระบบรหัสผลิตภัณฑ์ใหม่หลังจากการรวมการกำหนดหมายเลขพนักงานใหม่ให้กับพนักงานเพื่อปรับการเติบโตเป็นต้นสิ่งเหล่านี้คือ ทั้งหมดเป็นเพียงตัวอย่างสมมติ แต่ตามตัวอย่างก่อนหน้าของฉันที่มี ZIP แสดงให้เห็นบางครั้งระบบที่มีการยอมรับอย่างดีอาจเปลี่ยนไป
Dirk Vollmar

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

26

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

  • คีย์ตัวแทนมีประโยชน์เมื่อไม่มีแอตทริบิวต์หรือชุดแอตทริบิวต์อื่น ๆ ในตารางที่เหมาะสมในการระบุแถวโดยไม่ซ้ำกัน
  • หากเป็นไปได้ควรใช้คีย์ธรรมชาติเพื่อให้มนุษย์อ่านตารางได้ง่ายขึ้น คีย์ธรรมชาติยังอนุญาตให้คีย์ต่างประเทศในตารางที่อ้างอิงมีค่าจริงแทนที่จะเป็นรหัสตัวแทน เช่นเมื่อคุณต้องการจัดเก็บstate(CA, TX, NY) คุณอาจใช้char(2)คีย์ธรรมชาติแทน int ได้เช่นกัน
  • ใช้คีย์หลักผสมตามความเหมาะสม อย่าเพิ่มidคีย์ตัวแทน "" โดยไม่จำเป็นเมื่อมีคีย์ผสมที่ดีอย่างสมบูรณ์ (โดยเฉพาะอย่างยิ่งในตารางแบบกลุ่มต่อกลุ่ม) คำสั่งสำหรับคีย์สามคอลัมน์ในทุกตารางเป็นเรื่องไร้สาระอย่างแท้จริง
  • GUID เป็นวิธีแก้ปัญหาเมื่อคุณต้องการรักษาความเป็นเอกลักษณ์ในหลาย ๆ ไซต์ นอกจากนี้ยังมีประโยชน์หากคุณต้องการให้ค่าในคีย์หลักไม่ซ้ำกัน แต่ไม่เรียงลำดับหรือต่อเนื่องกัน
  • INT กับ BIGINT: ไม่ใช่เรื่องปกติที่ตารางจะต้องมีช่วง 64 บิตสำหรับคีย์หลัก แต่ด้วยความพร้อมใช้งานที่เพิ่มขึ้นของฮาร์ดแวร์ 64 บิตจึงไม่ควรเป็นภาระและให้ความมั่นใจมากขึ้นว่าคุณจะไม่ล้น INT นั้นเล็กกว่าแน่นอนดังนั้นหากพื้นที่ว่างอยู่ในระดับพรีเมี่ยมก็สามารถให้ข้อได้เปรียบเล็กน้อย

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

2
@Robert: อ่านเกี่ยวกับ "ON UPDATE CASCADE" แต่ฉันเข้าใจในสิ่งที่คุณกำลังพูดและฉันเห็นด้วยว่าควรใช้รหัสตัวแทนเป็นส่วนใหญ่เพราะคุณสมบัติอาจมีการเปลี่ยนแปลงและไม่ซ้ำกัน
Bill Karwin

2
คีย์หลักควรไม่เปลี่ยนรูป การอัปเดต Cascade เป็นเพียงการแฮ็กที่น่าเกลียดสำหรับการตัดสินใจออกแบบที่ไม่ดีในกรณีนี้ ไม่ต้องการคีย์ธรรมชาติ เช่นเดียวกับคีย์คอมโพสิตที่แพร่กระจายตัวเองเหมือนโรคระบาด ใครก็ตามที่มีประสบการณ์ในการพัฒนาฐานข้อมูลมากกว่า 3 เดือนจะทราบดี
FDCastel

7
@FD: ฉันไม่เห็นด้วยกับคำสั่งที่ชัดเจนของคุณและฉันได้พัฒนาฐานข้อมูล SQL มาตั้งแต่ปี 1992 แต่แน่นอนว่ามันเป็นความจริงที่คีย์ตัวแทนสามารถคงสภาพไม่เปลี่ยนรูปได้ดีที่สุด
Bill Karwin

20

ฉันชอบบล็อก The Database Programmerเป็นแหล่งข้อมูลประเภทนี้

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


2
พวกเขาเปลี่ยนลิงค์ของพวกเขานี่คือบุ๊คมาร์คที่อัปเดตแล้ว: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

เพิ่งรับช่วงโครงการเช่นนี้ และสิ่งแรกที่พวกเขาต้องการจะทำให้สคีมาพังทลาย คีย์ตัวแทน FTW ตรรกะทางธุรกิจใน DB FTL ของคุณ
Jason


11

นอกประเด็นเล็กน้อย แต่ฉันรู้สึกถูกบังคับให้ตีระฆังด้วย ...

ถ้าคีย์หลักของคุณคือ GUID ที่, ไม่ได้ทำให้มันเป็นดัชนีคลัสเตอร์ เนื่องจาก GUID ไม่ใช่ลำดับข้อมูลจึงจะถูกจัดเรียงใหม่บนดิสก์ในระหว่างการแทรกเกือบทุกครั้ง (Yuck.) หากใช้ GUID เป็นคีย์หลักควรเป็นดัชนีที่ไม่ใช่คลัสเตอร์


1
จุดที่ดีมาก - เราต้องแยกความแตกต่างระหว่างแนวคิดLOGICALของคีย์หลัก (อาจใช้ได้ในการใช้ GUID สำหรับสิ่งนั้นโดยเฉพาะอย่างยิ่งหากเกี่ยวข้องกับการจำลองแบบ) และแนวคิดทางกายภาพของคีย์การทำคลัสเตอร์ซึ่งไม่ควรเป็น GUID ตั้งแต่ นำไปสู่การกระจายตัวของดัชนีมากเกินไป
marc_s

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

@ ราล์ฟคุณพูดถูกไม่ใช่ทุกอย่าง แต่เพียงพอที่จะทำให้เกิดประสิทธิภาพ 20x sql-server-performance.com/articles/per/…
Portman

ฟังก์ชัน SQL Server newsequentialid () แก้ปัญหาการแตกตัวของดัชนีด้วย GUIDs (แม้ว่า 24 ไบต์จะยังคงมากเกินไปหากคุณไม่ต้องการความเป็นเอกลักษณ์ส่วนกลาง) โปรดดูที่ msdn.microsoft.com/en-us/library/ms189786.aspx
ErikE

10

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

ตอนนี้สำหรับการเลือกคีย์ตัวแทนฉันยึดติดกับคอลัมน์ข้อมูลประจำตัว (ฉันทำงานส่วนใหญ่ใน MS SQL Server) GUID มีขนาดใหญ่เกินไปและ Microsoft แนะนำกับใช้พวกเขาเป็นเภสัชจลนศาสตร์ หากคุณมีเซิร์ฟเวอร์หลายเครื่องสิ่งที่คุณต้องทำคือเพิ่มจำนวน 10 หรือ 20 หรืออะไรก็ได้ที่คุณคิดว่าจำนวนเซิร์ฟเวอร์สูงสุดที่คุณจะต้องใช้ในการซิงค์ / ขยายและเพียงแค่ใส่เมล็ดสำหรับแต่ละตารางในแต่ละเซิร์ฟเวอร์ที่ตามมา และคุณจะไม่มีการชนกันของข้อมูล

แน่นอนว่าเนื่องจากการเพิ่มขึ้นฉันจึงทำให้คอลัมน์ข้อมูลประจำตัวเป็น BigInt (หรือที่เรียกว่า long [64 บิต])

การคำนวณเล็กน้อยแม้ว่าคุณจะเพิ่มขึ้นเป็น 100 คุณก็ยังสามารถมี 92,233,720,368,547,758 (> 92 quadrillion) แถวในตารางได้


9

ฉันคิดว่าการใช้คำว่า "Primary" ในวลี "Primary" นั้นเป็นความหมายที่แท้จริงทำให้เข้าใจผิด

ขั้นแรกให้ใช้คำจำกัดความว่า "คีย์" คือแอตทริบิวต์หรือชุดของแอตทริบิวต์ที่ต้องไม่ซ้ำกันภายในตาราง

จากนั้นการมีคีย์ใด ๆ จะทำหน้าที่หลายจุดประสงค์ที่ไม่สอดคล้องกัน

  1. เพื่อใช้เป็นเงื่อนไขการรวมกับหนึ่งหรือหลายระเบียนในตารางลูกที่มีความสัมพันธ์กับตารางหลักนี้ (การกำหนด Foreign Key อย่างชัดเจนหรือโดยปริยายในตารางย่อยเหล่านั้น)
  2. (ที่เกี่ยวข้อง) ตรวจสอบให้แน่ใจว่าเรกคอร์ดลูกต้องมีเรกคอร์ดหลักในแท็บหลัก e (FK ตารางรองต้องมีอยู่เป็นคีย์ในตารางหลัก)
  3. เพื่อเพิ่มประสิทธิภาพของคิวรีที่ต้องการค้นหาระเบียน / แถวเฉพาะในตารางอย่างรวดเร็ว

  4. เพื่อให้แน่ใจว่าข้อมูลมีความสอดคล้องกันโดยการป้องกันไม่ให้แถวที่ซ้ำกันซึ่งแสดงถึงเอนทิตีตรรกะเดียวกันไม่ให้แทรกเข้าไปในตาราง (ซึ่งมักเรียกว่าคีย์ "ธรรมชาติ" และควรประกอบด้วยแอตทริบิวต์ table (เอนทิตี) ซึ่งค่อนข้างคงที่)

เห็นได้ชัดว่าคีย์ใด ๆ ที่ไม่มีความหมายและไม่เป็นธรรมชาติ (เช่น GUID หรือจำนวนเต็มที่สร้างขึ้นโดยอัตโนมัติจะไม่สามารถตอบสนองความพึงพอใจ # 4 ได้ทั้งหมด

แต่บ่อยครั้งที่มีตารางจำนวนมาก (ส่วนใหญ่) คีย์ธรรมชาติโดยสิ้นเชิงที่สามารถให้ # 4 มักจะประกอบด้วยแอตทริบิวต์หลายรายการและกว้างเกินไปหรือกว้างมากจนการใช้ตารางเพื่อวัตถุประสงค์ # 1 # 2 หรือ # 3 จะทำให้ไม่สามารถยอมรับได้ ผลการดำเนินงาน

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

สำหรับ GUID ควรระมัดระวังในการใช้เนื่องจากการใช้ guids ในดัชนีอาจทำให้เกิดการแตกตัวของดัชนีได้ อัลกอริทึมทั่วไปที่ใช้ในการสร้างทำให้ส่วน "สุ่ม" ของ guid อยู่ในตำแหน่งบิตที่สำคัญที่สุด ... สิ่งนี้จะเพิ่มความต้องการสำหรับการจัดเรียงดัชนีปกติ / การทำดัชนีใหม่เมื่อมีการเพิ่มแถวใหม่


ฟังก์ชัน SQL Server newsequentialid () แก้ปัญหาการแตกตัวของดัชนีของ GUIDs (แม้ว่า 24 ไบต์จะยังคงมากเกินไปหากคุณไม่ต้องการความเป็นเอกลักษณ์ส่วนกลาง) โปรดดู msdn.microsoft.com/en-us/library/ms189786.aspx
ErikE

โอ๊ะฉันตั้งใจจะบอกว่า 16 ไบต์
ErikE

8

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

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

สถานที่อื่นใช้ตำแหน่งในต้นไม้เป็นคีย์หลักสำหรับบันทึก ดังนั้นจะมีบันทึกดังต่อไปนี้

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

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

ได้โปรดได้โปรดหากคุณกำลังเขียนโค้ดที่ฉันต้องดูแลโปรดอย่าใช้คีย์อัจฉริยะ


ฉันเห็นด้วยสุดใจ Smartkeys = โง่
Robert C.Barth

2
นี่ไม่ได้หมายความว่ากุญแจธรรมชาตินั้นโง่ แต่จุดที่ดี

4

ฉันเป็นแฟนตัวยงของการเพิ่มอัตโนมัติเป็นคีย์หลัก ฉันรู้อยู่ลึก ๆ ในใจว่านี่คือ cop-out แต่มันทำให้ง่ายต่อการจัดเรียงข้อมูลโดยเมื่อมีการเพิ่ม (ORDER BY ID DESC, f'r instance)

3 คอลัมน์ฟังดูรุนแรงอย่างยิ่งต่อการแยกวิเคราะห์ของมนุษย์

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

การเพิ่มอัตโนมัติสำหรับมนุษย์เรา :-(


4

โดยทั่วไปจะขึ้นอยู่กับ

โดยส่วนตัวแล้วฉันชอบการเพิ่มอัตโนมัติ

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


3

ควรมีอย่างน้อย 3 คอลัมน์ที่ประกอบเป็นคีย์หลัก

ฉันไม่เข้าใจเรื่องนี้

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

Int / BigInt ซึ่งการเพิ่มอัตโนมัติเป็นคีย์หลักที่ดีพอ

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


คีย์หลักจำเป็นต้องไม่ซ้ำกัน แต่ไม่จำเป็นต้องมีค่าคงที่ ดังนั้นคีย์ต่างประเทศที่ประกาศด้วย "ON UPDATE CASCADE" แต่การตั้งสมมติฐานว่าคีย์หลักคงที่จะช่วยลดความซับซ้อนของแอปพลิเคชันต่างๆ นี่เป็นประโยชน์อย่างหนึ่งของคีย์ตัวแทน
Bill Karwin

3

RE GUID ของ

ดูว่านี่จะเป็นเรื่องจริงหรือไม่ ฐานข้อมูลขนาดใหญ่จริงๆโหลดเยอะและเข้าถึงได้รวดเร็ว

ในงานสุดท้ายของฉันซึ่งเรามีฐานข้อมูล 100 ถึง 500 ล้านระเบียนพวกฐานข้อมูลของเราโต้แย้งอย่างรุนแรงกับ GUID และสำหรับตัวเลขทศนิยมที่มีขนาดเหมาะสม พวกเขารู้สึกว่า (ภายใต้ Oracle) ความแตกต่างของขนาดในที่เก็บข้อมูลภายในสำหรับสตริง Guid - เทียบกับค่าทศนิยมจะสร้างความแตกต่างที่เห็นได้ชัดเจนในการค้นหา (คีย์ที่ใหญ่กว่า = ต้นไม้ที่ลึกกว่าเพื่อสำรวจ)

ลักษณะการสุ่มของ GUID ยังช่วยลดปัจจัยการเติมสำหรับหน้าดัชนีลงอย่างมากซึ่งจะเพิ่มการฉีกขาดและ I / O ของดิสก์อย่างมาก


"ลดปัจจัยเติม"? ไม่แน่ใจว่าสิ่งที่อาจหมายถึง Fill-factor คือข้อตกลงเพียงครั้งเดียวซึ่งกำหนดเป็นเปอร์เซ็นต์ของพื้นที่ว่างที่ร้องขอในระดับใบของดัชนี ณ เวลาที่สร้างดัชนี ค่า GUID โดยการแจกแจงลักษณะแบบสุ่มตามความกว้างของระดับใบไม้บนส่วนแทรกในช่องว่างที่เติมปัจจัยให้
Ralph Shillington

1
GUID เป็นสตริงตั้งแต่เมื่อใด GUID ควรจัดเก็บไว้ภายในเป็น 16 ไบต์โดย DBMS ที่เกี่ยวข้อง การจัดเก็บเป็น 32 ไบต์ในการแทนค่าฐานสิบหกจะไม่สามารถรองรับได้! (หรือ 36 มีขีดกลางหรือ 38 พร้อมวงเล็บปีกกา)
ErikE

2

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


2

ฉันใช้รหัสตัวแทนมาโดยตลอด - จำนวนเต็มสร้างอัตโนมัติที่เรียกว่า 'id' ฉันเห็นเหตุผลมากมายในการทำเช่นนี้แม้ว่าจะมีตัวเลือกอื่นที่ชัดเจน:

  • ความสม่ำเสมอ
  • ข้อมูลเป็นอิสระ (ไม่ซ้ำกันไม่ถูกทำลายโดยการเปลี่ยนแปลงรูปแบบ)
  • มนุษย์อ่านได้

... และไม่มีเหตุผลที่สมเหตุสมผลที่จะไม่:

  • ความคลุมเครือในการเข้าร่วม? - ตารางนามแฝงเป็นแนวทางปฏิบัติที่ดีกว่า IMHO
  • ตารางที่เหมาะสมที่สุด? - การลบหนึ่งไบต์ต่อรายการเป็นการเพิ่มประสิทธิภาพก่อนกำหนด IMHO
  • การตัดสินใจต่อโต๊ะ? - ไม่สอดคล้องกันอีกต่อไป
  • ปัญหาการขูดหินปูน? - เอ๊ะ? ทำไม?
  • โครงสร้างข้อมูลตามลำดับชั้น? - นั่นคือเรื่องที่ผิดปกติซึ่งเป็นเรื่องอื่น ๆ ของศาสนา พอจะบอกได้ว่าฉันเป็นแฟนในบางสถานการณ์ในทางทฤษฎี แต่ไม่เคยปฏิบัติ :)

เหตุผลที่สมเหตุสมผลกับสิ่งที่ฉันยังไม่ได้คิดหรือเจอก็ยินดีเสมอ ...


1

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


เขายังคงอยากรู้ว่ามันขึ้นอยู่กับอะไร เมื่อตระหนักถึงสิ่งเหล่านี้แล้วเราจะสามารถเชื่อมั่นในตัวเองเพื่อเลือกได้ ...
Nicholas Leonard

1

ฉันมักจะใช้ตัวเลือก # 1 หรือ # 3 ขึ้นอยู่กับขนาดจำนวนคนที่เชื่อมต่อและสถานการณ์เซิร์ฟเวอร์ฐานข้อมูลหลายตัวหรือไม่

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


1

ฉันใช้เฉพาะ int ที่เพิ่มขึ้นอัตโนมัติหรือ GUID 99% ของเวลาที่ฉันใช้ auto-Increment int เป็นเพียงสิ่งที่ฉันได้รับการสอนให้ใช้เมื่อฉันเรียนรู้เกี่ยวกับฐานข้อมูลเป็นครั้งแรกและไม่เคยมีเหตุผลที่จะไม่ใช้ (แม้ว่าฉันจะรู้เหตุผลว่าทำไม GUID จึงดีกว่า)

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


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

1

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

  • นิยามคีย์หลักไม่ซับซ้อนเกินไปหรือไม่? หลีกเลี่ยงการนำเสนอความซับซ้อนที่ไม่จำเป็นเพื่อทำตาม "แนวทางปฏิบัติที่ดีที่สุด" หรือไม่?
  • มีคีย์หลักที่เป็นไปได้ที่ดีกว่าซึ่งต้องการค่าใช้จ่ายน้อยกว่าสำหรับฐานข้อมูลในการจัดการ (เช่น INTEGER เทียบกับ VARCHAR ฯลฯ ) หรือไม่
  • ฉันแน่ใจอย่างแน่นอนหรือไม่ว่าความไม่ซ้ำกันและค่าคงที่ที่กำหนดไว้ของคีย์หลักของฉันจะไม่เปลี่ยนแปลง?

ข้อสุดท้ายนี้น่าจะเป็นสิ่งที่ดึงให้คนส่วนใหญ่ใช้สิ่งต่างๆเช่น GUID หรือคอลัมน์จำนวนเต็มที่เพิ่มขึ้นเองเนื่องจากอาศัยสิ่งต่างๆเช่นที่อยู่หมายเลขโทรศัพท์ชื่อ / นามสกุล ฯลฯ อย่าตัดทิ้ง สิ่งเดียวที่ไม่แปรเปลี่ยนเกี่ยวกับคนที่ฉันนึกถึงคือ SSN แต่ฉันก็ไม่แน่ใจ 100% เกี่ยวกับคนที่เหลืออยู่ตลอดไป

หวังว่าจะช่วยเพิ่มความกระจ่างได้นะคะ ...


มีบางกรณีในอดีตที่ SSN ไม่ซ้ำกัน
Bill Karwin

1

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


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

1
ฉันคิดเสมอว่าผู้เชี่ยวชาญใช้เครื่องมือที่ดีที่สุดสำหรับงานนี้
Andrew G. Johnson

1

จำนวนเต็มเกือบตลอดเวลา

พวกเขามีเหตุผลที่ดีอื่น ๆ นอกเหนือจากการประมวลผลที่เล็กลง / เร็วขึ้น คุณจะเขียนแบบไหนดี - "404040" หรือ "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"


ตัวหลังอาจเป็นจำนวนเต็มโดยเพิ่มขีดกลางและอยู่ในฐาน 16 แต่ใช่ 404040 ประมวลผลได้เร็วกว่า GUID แบบยาว จากนั้นอีกครั้ง 0 จะประมวลผลได้เร็วกว่าเพราะไม่ต้องการข้อมูลแม้แต่บิตเดียว!
strager

1

มีความเกี่ยวข้องเล็กน้อยเท่านั้น แต่สิ่งหนึ่งที่ฉันเพิ่งเริ่มทำเมื่อเร็ว ๆ นี้เมื่อฉันมีตารางการจำแนกขนาดเล็ก (โดยพื้นฐานแล้วสิ่งที่จะแสดงถึง ENUM ในรหัส) คือฉันจะทำให้คีย์หลักเป็นถ่าน (3) หรือถ่าน (4) จากนั้นฉันสร้างคีย์หลักเหล่านั้นเป็นตัวแทนของค่าการค้นหา

ตัวอย่างเช่นฉันมีระบบการเสนอราคาสำหรับตัวแทนขายภายในของเรา เรามี "หมวดหมู่ค่าใช้จ่าย" ที่ทุกรายการเสนอราคาถูกกำหนดหนึ่งใน ... ดังนั้นฉันจึงมีตารางการค้นหาประเภทที่เรียกว่า 'tCostCategories' โดยที่คีย์หลักคือ 'MTL', 'SVC', 'TRV', 'TAX', 'ODC' คอลัมน์อื่น ๆ ในตารางการค้นหาจะเก็บรายละเอียดเพิ่มเติมเช่นความหมายภาษาอังกฤษปกติของรหัส "วัสดุ" "บริการ" "การเดินทาง" "ภาษี" "ต้นทุนทางตรงอื่น ๆ " และอื่น ๆ

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

1
PartNumber $ 40 MTL 2 อื่น ๆ PartNumber $ 29.99 SVC
3 PartNumber2 $ 150 TRV

ง่ายกว่ามากที่การใช้ int เพื่อแสดงหมวดหมู่แล้วเชื่อมโยง 1, 2, 3 ในทุกบรรทัด - คุณมีข้อมูลอยู่ตรงหน้าคุณและประสิทธิภาพดูเหมือนจะไม่ได้รับผลกระทบเลย (ไม่ใช่ว่าฉัน ' ได้รับการทดสอบอย่างแท้จริง)

เท่าที่ถามจริง ... ฉันชอบ RowGUID uniqueidentifiers ฉันไม่ได้ 100% ในสิ่งนี้ แต่ไม่ใช่ทุกแถวที่มี RowGuid ภายในหรือไม่? ถ้าเป็นเช่นนั้นการใช้ RowGuid จะใช้พื้นที่น้อยกว่า ints (หรืออย่างอื่นสำหรับเรื่องนั้น) ทั้งหมดที่ฉันรู้ก็คือถ้ามันดีพอสำหรับ M $ ที่จะใช้ใน GreatPlains มันก็ดีพอสำหรับฉัน (ฉันควรเป็ดไหม ??)


1

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


1
ใช่คุณทำได้คุณไม่ได้ทำให้ตารางประเภทย่อยมีคุณสมบัติของตัวตน แต่จะได้รับการแทรกค่าตารางประเภทซุปเปอร์ไทป์อย่างชัดเจน โปรดดูstackoverflow.com/questions/2112882/…
ErikE

1

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

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

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

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


โปรดอธิบายตัวอย่างคีย์ธรรมชาติที่น่าเชื่อถือ?
ErikE

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

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

อีกตัวอย่างที่ดีของคีย์ธรรมชาติที่เชื่อถือได้คือ VIN (หมายเลขประจำตัวรถ) ในช่วงหลายปีที่ผ่านมารถทุกคันที่ขายใหม่จะมี VIN ติดอยู่ พวกเขาสามารถไว้วางใจได้ว่าจะไม่เหมือนใครและไม่เปลี่ยนแปลง
Walter Mitty

1

Guids.period.

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


ปรับปรุงเพื่อชี้แจงคำแถลงของฉัน

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

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

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

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

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

แอปล่าสุดของเราผ่านช่วงเวลาของการแทรกที่หนักหน่วงซึ่งกินเวลาประมาณหนึ่งเดือน หลังจากนั้น 90 +% ของข้อความค้นหาจะถูกเลือกสำหรับการรายงานทั้งหมด เพื่อเพิ่มความจุฉันสามารถเปิดเซิร์ฟเวอร์ DB เพิ่มเติมในช่วงเวลาแทรกขนาดใหญ่นี้ และต่อมารวมสิ่งเหล่านี้เป็นฐานข้อมูลเดียวสำหรับการรายงานได้อย่างง่ายดาย การพยายามทำเช่นนั้นกับ INT จะเป็นฝันร้ายอย่างแน่นอน

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


คุณเคยตรวจสอบปัจจัยเติมของดัชนีของคุณหรือไม่? ลักษณะการสุ่มของชีสสวิสของ GUID ทำให้ประสิทธิภาพลดลงอย่างมาก
stephbu

2
"Guids.period": นั่นผิดมาก ควรใช้ GUID ตามความเหมาะสม ดังที่ผู้แสดงความคิดเห็นรายอื่นชี้ให้เห็นว่าอาจทำให้ชีวิตในฐานะโปรแกรมเมอร์ง่ายขึ้น แต่ส่งผลต่อขนาดและประสิทธิภาพโดยรวมของฐานข้อมูล
Mitch Wheat

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

3
GUID อาจใช้ได้สำหรับคีย์หลักแบบลอจิคัล แต่ไม่เคยใช้คอลัมน์ GUID เป็นคีย์การจัดกลุ่มของคุณ - คุณจะจมน้ำตายในการกระจายตัวของดัชนีซึ่งทำให้ประสิทธิภาพแย่ลง .....
marc_s

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

0

นี่เป็นเรื่องที่ซับซ้อนไม่ว่าคุณจะเข้าใจหรือไม่ก็ตาม อาจอยู่ภายใต้หัวข้อในคำถามที่พบบ่อยของ StackOverflow นี้

คำถามประเภทใดที่ฉันไม่ควรถามที่นี่?

หลีกเลี่ยงการถามคำถามที่เป็นเรื่องส่วนตัวโต้แย้งหรือต้องการการอภิปรายเพิ่มเติม นี่คือสถานที่สำหรับคำถามที่สามารถตอบได้!

เรื่องนี้เป็นที่ถกเถียงกันมาหลายปีและจะยังคงถกเถียงกันต่อไปอีกเป็นปี คำแนะนำเพียงอย่างเดียวที่ฉันได้เห็นคือคำตอบนั้นค่อนข้างคาดเดาได้ขึ้นอยู่กับว่าคุณกำลังถามคนที่แต่งตัวประหลาด OO (GUID เป็นวิธีเดียวที่จะไป!) ตัวสร้างแบบจำลองข้อมูล (คีย์ธรรมชาติเป็นวิธีเดียวที่จะไป!) หรือ DBA ที่มุ่งเน้นประสิทธิภาพ (INT เป็นวิธีเดียวที่จะไป!)


ฉันจะไม่ปล่อยให้การอภิปรายยืดเยื้อ ฉันแค่อยากรู้ที่จะเห็นฉันทามติทั่วไป
Perpetualcoder

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