เป็นการดีที่จะมีคีย์หลักจำนวนเต็ม autoincrement เสมอหรือไม่


191

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

นี่ถือว่าเป็นความคิดที่ไม่ดีหรือไม่? มีข้อเสียใด ๆ ในการทำเช่นนี้? บางครั้งฉันก็มีดัชนีหลายอย่างเช่นid, profile_id, subscriptionsที่idเป็นตัวระบุเฉพาะการprofile_idเชื่อมโยงไปยังต่างประเทศidของProfileตาราง ฯลฯ

หรือมีสถานการณ์ที่คุณไม่ต้องการเพิ่มเขตข้อมูลดังกล่าวหรือไม่


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

24
@ArukaJ ประเด็นคือว่ามันรั่วไหลข้อมูลบางอย่างเกี่ยวกับระบบ ตัวอย่างเช่นสมมติว่าฐานข้อมูลมีโพสต์ที่ผู้ใช้เขียนซึ่งแต่ละรายการจะได้รับรหัสตามลำดับ สมมติว่าคุณโพสต์สี่รายการแต่ละรายการจะได้รับ ID: เมื่อ 4:00 (20), 5:00 (25), 20:00 (100) และ 21:00 (200) เมื่อดูที่รหัสคุณจะเห็นว่ามีเพียง 5 โพสต์ที่ถูกเพิ่มระหว่าง 4am และ 5am ในขณะที่ 100 ถูกเพิ่มระหว่าง 8pm ถึง 9pm หากคุณพยายามเลือกเวลาสำหรับการปฏิเสธการโจมตีบริการนั่นอาจเป็นข้อมูลที่มีค่า
Joshua Taylor

29
สำหรับทุกคนที่บ่นเกี่ยวกับ "ปัญหารถถังเยอรมัน" .... หากสิ่งเดียวที่ทำให้ใครบางคนไม่สามารถเข้าถึงข้อมูลพวกเขาไม่ควรเป็นกุญแจสำคัญใน URL ของคุณ ... คุณมีปัญหาใหญ่กว่า GUID กับ Auto INT
Matthew Whited

11
@MatthewWhited ไม่ใช่แค่การแลกเปลี่ยนพารามิเตอร์ใน URL สมมติว่าคุณใช้ไซต์และคุณสร้างเนื้อหา 100 ในเวลาtและสินทรัพย์ 120 ในเวลาt + 60นั้น หากคุณสามารถดูทั้ง ID เหล่านั้น (100 และ 120) ในรูปแบบที่ไม่ได้ทำให้รำลึกถึงตอนนี้คุณรู้จำนวนสินทรัพย์ทั้งหมดที่มีอยู่รวมถึงอัตราที่พวกเขาสร้างขึ้นอย่างคร่าวๆ นี่คือการรั่วไหลของข้อมูล นี่ไม่ใช่สมมุติฐานอย่างหมดจด
Chris Hayes

15
"เป็นการดีหรือไม่ที่จะปฏิบัติตามเสมอ ... " ไม่
brian_o

คำตอบ:


137

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

ข้อเสียที่อาจเกิดขึ้นในทางทฤษฎีรวมถึงดัชนีพิเศษเพื่อรักษาและใช้พื้นที่จัดเก็บพิเศษ ไม่เคยมีเหตุผลเพียงพอที่ฉันจะไม่ใช้


11
นั่นคือสิ่งที่ฉันทำ. คนส่วนใหญ่ใช้ 'id' หรือ 'tablename_id' (เช่น user_id) โดยทั่วไปแล้วอาร์กิวเมนต์จะไม่จำเป็นถ้าจำเป็นต้องใช้คอลัมน์ แต่เป็นวิธีการตั้งชื่อ
GrandmasterB

103
โดยส่วนตัวฉันคิดว่าชื่อตารางควรบ่งบอกถึงส่วนที่เหลือ TableName.idเมื่อเทียบกับTableName.TableName_idเพราะมีอะไรอีกที่idจะอ้างถึง? ถ้าฉันมีฟิลด์ id อื่นในตารางจากนั้นฉันจะใส่คำนำหน้าด้วยชื่อตารางถ้ามันหมายถึงตารางอื่น ๆ
AJJ

10
@ArukaJ คุณพูดถึงคุณกำลังใช้ SQLite ที่จริงแล้วเป็นกรณีพิเศษเล็กน้อยเพราะมันมักจะทำให้คอลัมน์ 'ภายใต้ประทุน' ดังนั้นคุณไม่ได้ใช้พื้นที่เพิ่มเติมเพราะคุณได้รับไม่ว่าคุณต้องการหรือไม่ นอกจากนี้ rowid ของ SQLite จะเป็นจำนวนเต็ม 64 บิตเสมอ หากความเข้าใจของฉันถูกต้องหากคุณกำหนดแถวที่เพิ่มขึ้นอัตโนมัติมันจะเป็นชื่อแทนของแถวภายใน ดังนั้นคุณอาจทำได้ดีอยู่เสมอ! ดูsqlite.org/autoinc.html
GrandmasterB

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

4
@GrandmasterB: เวอร์ชันปัจจุบันของ SQLite อนุญาตให้สร้างWITHOUT ROWIDตาราง (โดยชัดเจนPRIMARY KEY) เป็นการปรับให้เหมาะสม แต่มิฉะนั้นINTEGER PRIMARY KEYคอลัมน์จะเป็นชื่อแทนสำหรับ rowid
dan04

92

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

หากคุณมีตารางที่ไม่มีคีย์ที่ชัดเจนเขตข้อมูลที่เพิ่มขึ้นอัตโนมัติดูเหมือนจะเป็นความคิดที่ดี select * from blog where body = '[10000 character string]'ท้ายที่สุดคุณไม่ต้องการ คุณต้องการ select * from blog where id = 42แต่ ฉันขอยืนยันว่าในกรณีส่วนใหญ่สิ่งที่คุณต้องการจริงๆคือตัวระบุที่ไม่ซ้ำกัน ไม่ใช่ตัวบ่งชี้เฉพาะตามลำดับ คุณอาจต้องการใช้ตัวระบุที่เป็นสากลแทน

มีฟังก์ชั่นในฐานข้อมูลส่วนใหญ่เพื่อสร้างตัวระบุที่ไม่ซ้ำแบบสุ่ม ( uuidใน mysql, postgres. newidin mssql) สิ่งเหล่านี้ช่วยให้คุณสามารถสร้างข้อมูลไปยังฐานข้อมูลหลาย ๆ เครื่องได้ตลอดเวลาโดยไม่มีการเชื่อมต่อเครือข่ายระหว่างพวกเขาและยังรวมข้อมูลกับศูนย์ความขัดแย้ง สิ่งนี้ช่วยให้คุณสามารถติดตั้งเซิร์ฟเวอร์หลายเครื่องและศูนย์ข้อมูลได้ง่ายขึ้นเช่นด้วยไมโครไซต์

นอกจากนี้ยังเป็นการหลีกเลี่ยงผู้โจมตีที่คาดเดา URL ของหน้าเว็บที่พวกเขาไม่ควรเข้าถึง ถ้ามีhttps://example.com/user/1263ก็คงมี https://example.com/user/1262เช่นกัน สิ่งนี้อาจทำให้ระบบอัตโนมัติของช่องโหว่ความปลอดภัยในหน้าโปรไฟล์ผู้ใช้

นอกจากนี้ยังมีหลายกรณีที่คอลัมน์ uuid ไม่มีประโยชน์หรือเป็นอันตราย สมมติว่าคุณมีเครือข่ายสังคม มีusersโต๊ะและfriendsโต๊ะ ตารางเพื่อนมีสองคอลัมน์ผู้ใช้และฟิลด์การเพิ่มอัตโนมัติ คุณต้องการ3เป็นเพื่อนกับ5ดังนั้นคุณจึงใส่3,5ลงในฐานข้อมูล 1,3,5ฐานข้อมูลเพิ่มรหัสเพิ่มโดยอัตโนมัติและร้านค้า อย่างใดผู้ใช้3คลิกที่ "เพิ่มเพื่อน" - ปุ่มอีกครั้ง คุณสามารถแทรกลงในฐานข้อมูลอีกครั้งฐานข้อมูลเพิ่มรหัสเพิ่มโดยอัตโนมัติและแทรก3,5 2,3,5แต่ตอนนี้3และ5เป็นเพื่อนกันสองครั้ง! นั่นเป็นการสิ้นเปลืองพื้นที่และถ้าคุณคิดเกี่ยวกับมันคอลัมน์เพิ่มอัตโนมัติก็คือ ทั้งหมดที่คุณต้องดูว่าaและbเพื่อนคือการเลือกแถวที่มีสองค่า พวกเขาอยู่ด้วยกันเป็นตัวระบุแถวที่ไม่ซ้ำกัน (คุณอาจต้องการเขียนตรรกะบางอย่างเพื่อให้แน่ใจ3,5และ5,3ซ้ำซ้อน)

ยังคงมีกรณีที่รหัสประจำตัวของมันมีประโยชน์เช่นเมื่อสร้าง url-shortener แต่ส่วนใหญ่ (และแม้กระทั่งกับ shortener URL) id เฉพาะที่สร้างขึ้นแบบสุ่มนั้นเป็นสิ่งที่คุณต้องการใช้แทน

TL; DR: ใช้ UUID แทนการเพิ่มอัตโนมัติหากคุณยังไม่มีวิธีที่ไม่ซ้ำในการระบุแต่ละแถว


26
ปัญหาเกี่ยวกับ UUID คือการใช้พื้นที่มากเกินไปสำหรับตารางส่วนใหญ่ ใช้ตัวระบุที่ไม่ซ้ำกันที่เหมาะสมสำหรับแต่ละตาราง
สตีเฟ่น

49
ทั้งย่อหน้าเกี่ยวกับความไม่เหมือนใครคือ moot - สามารถกำหนดความเป็นเอกลักษณ์ได้ไม่ว่าจะมีหรือไม่มีคีย์หลัก นอกจากนี้ UUID นั้นดีกว่าในด้านทฤษฎี แต่น่ากลัวที่จะใช้เมื่อทำการดีบั๊ก / ทำงาน DBA หรือทำสิ่งใดก็ตามที่ไม่ใช่ "ต่อต้านการโจมตี"

11
อีกสถานการณ์หนึ่งเมื่อ UUIDs ดีกว่า: การใช้การดำเนินการ idempotent PUT เพื่อให้คุณสามารถลองร้องขอได้อย่างปลอดภัยโดยไม่ต้องแนะนำแถวที่ซ้ำกัน
yurez

21
ในจุด "การคาดเดา URL" การมี ID ที่ไม่ซ้ำกัน (เรียงตามลำดับหรืออย่างอื่น) ไม่ได้หมายความถึงการเปิดเผย ID นั้นแก่ผู้ใช้แอปพลิเคชัน
Dave Sherohman

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

60

ปุ่มเลือกอัตโนมัติมีข้อได้เปรียบเป็นส่วนใหญ่

แต่ข้อเสียที่เป็นไปได้บางประการอาจเป็น:

  • หากคุณมีรหัสธุรกิจคุณจะต้องเพิ่มดัชนีที่ไม่ซ้ำกันในคอลัมน์นั้นด้วยเพื่อบังคับใช้กฎทางธุรกิจ
  • เมื่อถ่ายโอนข้อมูลระหว่างสองฐานข้อมูลโดยเฉพาะอย่างยิ่งเมื่อข้อมูลอยู่ในตารางมากกว่าหนึ่งตาราง (เช่นข้อมูลหลัก / รายละเอียด) มันไม่ได้ตรงไปข้างหน้าเนื่องจากลำดับจะไม่ซิงค์ระหว่างฐานข้อมูลและคุณจะต้องสร้างตารางที่เท่าเทียมกันก่อน คีย์ธุรกิจเป็นการจับคู่เพื่อทราบว่า ID ใดจากฐานข้อมูลต้นทางสอดคล้องกับ ID ใดในฐานข้อมูลเป้าหมาย แต่นั่นไม่ควรเป็นปัญหาเมื่อทำการถ่ายโอนข้อมูลจาก / ไปยังตารางที่แยกได้
  • องค์กรหลายแห่งมีเครื่องมือการรายงานโฆษณาแบบกราฟิกจุดและคลิกลากและวาง เนื่องจากรหัสประจำตัวอัตโนมัติไม่มีความหมายผู้ใช้ประเภทนี้จะพบว่ามันยากที่จะเข้าใจข้อมูลนอกเหนือจาก "แอพ"
  • หากคุณปรับเปลี่ยนรหัสธุรกิจโดยบังเอิญคุณจะไม่สามารถกู้คืนแถวนั้นได้เนื่องจากคุณไม่มีสิ่งที่มนุษย์จะระบุได้อีกต่อไป ที่ก่อให้เกิดความผิดพลาดในแพลตฟอร์ม BitCoin ครั้ง
  • นักออกแบบบางคนเพิ่ม ID ลงในตารางการเข้าร่วมระหว่างสองตารางเมื่อ PK ควรประกอบด้วย ID ต่างประเทศสองรายการ เห็นได้ชัดว่าหากตารางการเข้าร่วมอยู่ระหว่างสามตารางขึ้นไปดังนั้น ID autoincremental ก็สมเหตุสมผล แต่คุณต้องเพิ่มคีย์ที่ไม่ซ้ำกันเมื่อใช้กับการรวมกันของ FK เพื่อบังคับใช้กฎเกณฑ์ทางธุรกิจ

นี่คือส่วนบทความ Wikipediaเกี่ยวกับข้อเสียของกุญแจตัวแทน


13
การตำหนิข้อบกพร่องของ mt.gox สำหรับกุญแจตัวแทนดูเหมือนว่าค่อนข้างน่าสงสัย ปัญหาคือพวกเขารวมเขตข้อมูลทั้งหมดในคีย์ผสมของพวกเขาแม้ฟิลด์ไม่แน่นอน / อ่อน
CodesInChaos

6
ข้อเสีย "สังคม" ของการใช้คีย์การเพิ่มอัตโนมัติคือบางครั้ง "ธุรกิจ" สันนิษฐานว่าจะต้องไม่มีช่องว่างและต้องการทราบว่าเกิดอะไรขึ้นกับแถวที่หายไปที่เกิดขึ้นเมื่อการแทรกล้มเหลวเกิดขึ้น (การย้อนกลับธุรกรรม)
Rick Ryker

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

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

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

20

เพื่อที่จะตรงกันข้ามไม่คุณไม่จำเป็นต้องมี AutoInc PK ที่เป็นตัวเลขเสมอไป

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

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

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

เมื่อคุณมีค่าจำนวนน้อยที่ค่อนข้างคงที่ให้ใช้ค่าที่เหมาะสมกับผู้ใช้ระบบ เหตุใดจึงใช้ 1,2,3 เมื่อคุณสามารถใช้ L, C, H โดยที่ L, H และ C แสดงถึงชีวิตรถยนต์และบ้านในบริบท "ประเภทนโยบาย" ประกันภัยหรือกลับไปที่ตัวอย่าง VIN วิธีการใช้ "TO" "สำหรับโตโยต้า รถยนต์ Toyata ทุกคันมี VIN ที่เริ่มต้น "เป็น" มันเป็นเรื่องที่ผู้ใช้จะจำได้น้อยลงทำให้มีโอกาสน้อยที่พวกเขาจะแนะนำการเขียนโปรแกรมและข้อผิดพลาดของผู้ใช้และอาจเป็นตัวแทนที่ใช้งานได้สำหรับคำอธิบายแบบเต็ม เพื่อเขียนและสร้างได้เร็วขึ้น

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

ฉันใช้ AutoInc PKs ฉันแค่ฝึกสมองและมองหาทางเลือกที่ดีกว่าก่อน ศิลปะการออกแบบฐานข้อมูลกำลังสร้างบางสิ่งที่มีความหมายซึ่งสามารถสอบถามได้อย่างรวดเร็ว การมีผู้เข้าร่วมจำนวนมากเกินไปจะขัดขวางสิ่งนี้

แก้ไขกรณีที่สำคัญอีกอย่างหนึ่งที่คุณไม่จำเป็นต้องใช้ Autogenerated PK คือกรณีของตารางที่แสดงถึงจุดตัดของอีกสองตาราง ในการยึดติดกับ Car analogy, A Car มีอุปกรณ์เสริม 0..n, แต่ละอุปกรณ์สามารถพบได้ในรถยนต์หลายคัน ดังนั้นเพื่อแสดงสิ่งนี้คุณสร้างตาราง Car_Accessory ที่มี PK จากรถยนต์และอุปกรณ์เสริมและข้อมูลอื่น ๆ ที่เกี่ยวข้องเกี่ยวกับลิงค์วันที่เป็นต้น

สิ่งที่คุณไม่ต้องการ (โดยปกติ) คือ AutoInc PK ในตารางนี้ - จะสามารถเข้าถึงได้ผ่านทางรถยนต์เท่านั้น "บอกฉันว่ามีอุปกรณ์เสริมอะไรบ้างในรถคันนี้" หรือจากอุปกรณ์เสริม "บอกอุปกรณ์ที่มีอุปกรณ์นี้"


4
> รถยนต์ Toyata ทุกคันมี VIN ที่เริ่มต้น "เป็น" นั่นไม่เป็นความจริง พวกเขาเริ่มต้นด้วย "JT" ถ้าทำในญี่ปุ่น Toyotas ที่สร้างโดยชาวอเมริกันมี VINs ที่แตกต่างกันอย่างสิ้นเชิงen.wikibooks.org/wiki/…
Monty Harder

17
Don't create a second, meaningless primary key; it's wasteful and may cause errors.อย่างไรก็ตามหากวิธีการที่คุณสร้างความไม่เหมือนใครสำหรับบันทึกนั้นเป็นการรวมกันของ 6 คอลัมน์การเข้าร่วมทั้ง 6 ตลอดเวลานั้นเป็นข้อผิดพลาดที่เกิดขึ้นเองได้ง่าย ข้อมูลมี PK โดยธรรมชาติ แต่คุณดีกว่าด้วยการใช้idคอลัมน์และข้อ จำกัด ที่ไม่ซ้ำใครของ 6 คอลัมน์เหล่านั้น
แบรด

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

2
@Monty ฉันไม่ดีคุณพูดถูก ความจำที่ใช้ไม่ได้มันเป็นเวลา 20 ปีแล้วที่ฉันได้ออกแบบระบบการจัดการยานพาหนะ ไม่มี VIN ไม่ใช่คีย์หลัก :) ฉันใช้ AutoInc Asset_ID IIRC ซึ่งนำไปสู่บางสิ่งที่ฉันลืม ตารางที่เป็นตัวเชื่อมโยงสำหรับความสัมพันธ์แบบหลายต่อหลายอย่างที่คุณเชื่อมโยงพูดอุปกรณ์เสริมสำหรับรถยนต์ (เช่นซันรูฟ) รถยนต์จำนวนมากมีอุปกรณ์เสริมมากมายดังนั้นคุณต้องมีตาราง "Car_Accessory" ซึ่งมี Car_ID และ Accessory_ID แต่ไม่จำเป็นต้องใช้ Car_Accesory_ID AutoInc PK
mcottle

7
มันวิเศษจริงๆที่มี "คีย์ธรรมชาติ" ไม่กี่อันที่ไม่เปลี่ยนรูปแบบอย่างแท้จริง SSN หรือไม่? ไม่พวกเขาสามารถเปลี่ยนได้ มันหายาก แต่มันสามารถเกิดขึ้นได้ ชื่อผู้ใช้? Nope ในที่สุดใครบางคนจะมีเหตุผลทางธุรกิจที่ถูกต้องในการเปลี่ยนแปลง VIN มักเป็นตัวอย่างของตำราเรียน แต่ก็มีไม่มากนัก แม้ที่อยู่บ้านสามารถเปลี่ยนแปลงได้เนื่องจากการเปลี่ยนชื่อถนน
Erik Funkenbusch

12

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

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


3
คุณไม่ควรใช้รหัส "ธรรมชาติ" เป็นคีย์หลักหากพวกเขารับประกันว่าจะไม่เปลี่ยนแปลงอย่างแน่นอน ตัวอย่างเช่นคุณไม่ควรใช้หมายเลขใบขับขี่เป็นคีย์หลักเพราะหากบุคคลได้รับใบขับขี่ใหม่คุณจะต้องอัปเดตไม่เพียง แต่ตารางนั้น แต่ตารางใด ๆ ที่มีคีย์ต่างประเทศอ้างอิงอยู่ด้วย!
ekolis

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

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

10

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

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

คำตอบมากมายที่นี่แนะนำว่าควรใช้คีย์เฉพาะที่มีอยู่ ถ้ามันมี 150 ตัวอักษรล่ะ? ฉันไม่คิดอย่างนั้น

ตอนนี้ประเด็นหลักของฉัน:

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

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

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

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


จากประสบการณ์ส่วนตัวฉันเห็นด้วยอย่างสุดใจกับคำตอบครึ่งหลังของคุณ คุณจะต้องใช้คีย์ที่ไม่ซ้ำกันทั่วโลกมากน้อยกว่าที่คุณต้องการดัชนีที่รวดเร็วและกะทัดรัด หากคุณต้องการให้สร้างตาราง GlobalEntities ด้วย ID ที่สร้างอัตโนมัติและคอลัมน์ UUID จากนั้นเพิ่ม ExGlobalEntityId foreign key ไปยังตารางลูกค้า หรือใช้แฮชของค่าบางค่า
Drunken Code Monkey

8

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

ลองดูตัวอย่างที่ไม่จำเป็นต้องใช้

คุณมีตารางสำหรับบทความนี้มีคีย์หลัก int idและคอลัมน์ varchar titleที่ชื่อว่า

นอกจากนี้คุณยังมีตารางเต็มรูปแบบของบทความหมวดidคีย์หลัก int, namevarchar

แถวหนึ่งในตารางบทความมีidจำนวน 5 ส่วนและtitle "วิธีปรุงห่านด้วยเนย" คุณต้องการเชื่อมโยงบทความนั้นกับแถวต่อไปนี้ในตารางหมวดหมู่ของคุณ: "Fowl" ( id : 20), "Goose" ( id : 12), "Cooking" ( id : 2), "Butter" (id: 9) .

ตอนนี้คุณมี 2 ตาราง: บทความและหมวดหมู่ คุณสร้างความสัมพันธ์ระหว่างสองคนได้อย่างไร

คุณสามารถมีตารางที่มี 3 คอลัมน์: id (คีย์หลัก), article_id (คีย์ต่างประเทศ), category_id (คีย์ต่างประเทศ) แต่ตอนนี้คุณมีสิ่งที่ชอบ:

| id | a_id | c_id |
| 1 | 5 | 20 |
| 2 | 5 | 12 |
| 3 | 5 | 2 |

ทางออกที่ดีกว่าคือการมีคีย์หลักที่ประกอบด้วย 2 คอลัมน์

| a_id | c_id |
| 5 | 20 |
| 5 | 12 |
| 5 | 2 |

สิ่งนี้สามารถทำได้โดยการทำ:

create table articles_categories (
  article_id bigint,
  category_id bigint,
  primary key (article_id, category_id)
) engine=InnoDB;

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

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

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


7

หรือมีสถานการณ์ที่คุณไม่ต้องการเพิ่มเขตข้อมูลดังกล่าวหรือไม่

แน่ใจ

ก่อนอื่นมีฐานข้อมูลที่ไม่มี autoincrements (เช่น Oracle ซึ่งแน่นอนว่าไม่ใช่หนึ่งใน contenders ที่เล็กที่สุด) นี่ควรเป็นข้อบ่งชี้แรกที่ทุกคนไม่ชอบหรือต้องการพวกเขา

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


9
(ไม่ใช่ผู้ใช้ Oracle ดังนั้นโปรดให้อภัยคำถาม แต่) Oracle ไม่ใช้ Sequence ในลักษณะเดียวกับที่คนอื่นใช้ Autoincrement / Identity การที่ออราเคิลบอกว่าไม่ได้มีการจัดประเภทข้อมูลอัตโนมัติเป็นเพียงแค่เซมาติค
แบรด

นั่นเป็นเพียงจุดเล็ก ๆ ส่วนหลักคือ ID ที่รันไม่เหมาะสมสำหรับทุกตารางดังนั้นการคุ้นเคยกับการตบรหัสอัตโนมัติในทุก ๆ ตารางอาจไม่ใช่วิธีที่ฉลาดที่สุด
AnoE

ไม่มีสองคีย์หลักมีเพียงหนึ่งคีย์หลักและส่วนที่เหลือทั้งหมดจะถูกเรียกว่าคีย์ผู้สมัครหากพวกเขาสามารถทำหน้าที่เป็นคีย์หลักมากเกินไป ..
rahul Tyagi

7

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

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

  • เมื่อรหัสที่เพิ่มขึ้นจะเป็นข้อมูลที่มากเกินไปสำหรับผู้โจมตีที่อาจเกิดขึ้น การใช้คอลัมน์ข้อมูลประจำตัวสำหรับบริการข้อมูล "สาธารณะ" ทำให้คุณเสี่ยงต่อ "ปัญหารถถังเยอรมัน"; หากมีรหัส id 10234 อยู่เหตุผลว่าเรคคอร์ด 10233, 10232 ฯลฯ นั้นมีอยู่กลับไปอย่างน้อย 1,0001 เรคคอร์ดแล้วจากนั้นก็ง่ายต่อการตรวจสอบเร็กคอร์ด 1001, 101 และ 1 เพื่อหาว่าคอลัมน์ข้อมูลประจำตัวของคุณเริ่มต้นที่ใด V4 GUID ที่ประกอบด้วยข้อมูลแบบสุ่มส่วนใหญ่จะทำลายพฤติกรรมที่เพิ่มขึ้นนี้โดยการออกแบบดังนั้นเพียงเพราะมี GUID หนึ่งตัว GUID ที่สร้างขึ้นโดยการเพิ่มหรือลดจำนวนไบต์ของ GUID นั้นไม่จำเป็นต้องทำให้ยากขึ้นสำหรับผู้โจมตีที่จะใช้บริการ สำหรับการดึงบันทึกเดียวเป็นเครื่องมือการถ่ายโอนข้อมูล มีมาตรการรักษาความปลอดภัยอื่น ๆ ที่สามารถ จำกัด การเข้าถึงได้ดีขึ้น แต่สิ่งนี้ช่วยได้
  • ใน M: M ตารางตัวอ้างอิงโยง Gimme แบบนี้ แต่ฉันเคยเห็นมาก่อน หากคุณมีความสัมพันธ์แบบกลุ่มต่อกลุ่มระหว่างสองตารางในฐานข้อมูลของคุณโซลูชัน go-to คือตารางตัวอ้างอิงโยงที่มีคอลัมน์คีย์ต่างประเทศอ้างอิงถึง PK ของแต่ละตาราง PK ของตารางนี้ควรเป็นคีย์ผสมของสองคีย์ต่างประเทศเสมอเพื่อรับพฤติกรรมดัชนีในตัวและเพื่อให้แน่ใจว่ามีการอ้างอิงที่ไม่ซ้ำใคร
  • เมื่อคุณวางแผนที่จะแทรกและลบจำนวนมากในตารางนี้เป็นจำนวนมาก อาจเป็นข้อเสียที่ใหญ่ที่สุดในคอลัมน์ข้อมูลประจำตัวเป็น hoopla พิเศษที่คุณต้องผ่านเมื่อทำการแทรกแถวจากตารางหรือแบบสอบถามอื่นที่คุณต้องการรักษาค่าคีย์ของตารางต้นฉบับ คุณต้องเปิด "การแทรกตัวตน" (แต่ทำใน DBMS ของคุณ) จากนั้นตรวจสอบให้แน่ใจด้วยตนเองว่ากุญแจที่คุณใส่ไม่ซ้ำกันและเมื่อคุณทำการนำเข้าเสร็จแล้วคุณต้องตั้งค่าตัวนับใน ข้อมูลเมตาของตารางเป็นค่าสูงสุดที่มีอยู่ หากการดำเนินการนี้เกิดขึ้นมากในตารางนี้ให้พิจารณาชุดรูปแบบ PK อื่น
  • สำหรับตารางกระจายคอลัมน์ Identity ใช้งานได้ดีสำหรับฐานข้อมูลอินสแตนซ์เดี่ยวคู่ failover และสถานการณ์อื่น ๆ ที่อินสแตนซ์ฐานข้อมูลเดียวมีอำนาจ แต่เพียงผู้เดียวใน schema ข้อมูลทั้งหมดในเวลาที่กำหนด อย่างไรก็ตามมีขนาดใหญ่มากที่คุณสามารถไปและยังมีคอมพิวเตอร์เครื่องหนึ่งที่เร็วพอ การจัดส่งบันทึกการจำลองแบบหรือธุรกรรมสามารถให้สำเนาเพิ่มเติมแบบอ่านอย่างเดียวได้ แต่มีข้อ จำกัด ในระดับของโซลูชันนั้นเช่นกัน ไม่ช้าก็เร็วคุณจะต้องมีเซิร์ฟเวอร์อย่างน้อยสองอินสแตนซ์สำหรับจัดการข้อมูลแทรกจากนั้นซิงโครไนซ์ซึ่งกันและกัน เมื่อสถานการณ์นั้นมาถึงคุณจะต้องการเขตข้อมูล GUID แทนที่จะเป็นส่วนเพิ่มเนื่องจาก DBMS ส่วนใหญ่จะมีการกำหนดค่าล่วงหน้าเพื่อใช้ส่วนของ GUID ที่พวกเขาสร้างเป็นตัวระบุเฉพาะอินสแตนซ์จากนั้นสร้างตัวระบุส่วนที่เหลือแบบสุ่ม หรือเพิ่มขึ้น ไม่ว่าในกรณีใด
  • เมื่อคุณต้องบังคับใช้ความเป็นเอกลักษณ์ในหลาย ๆ ตารางในฐานข้อมูลเป็นเรื่องปกติในระบบบัญชีเช่นการจัดการบัญชีแยกประเภท (มีแถวสำหรับเครดิตหรือเดบิตของทุกบัญชีที่เกิดขึ้นดังนั้นมันจึงใหญ่มากอย่างรวดเร็ว) เป็นลำดับของตารางแต่ละตารางแสดงเดือนละหนึ่งปฏิทิน / ปี. สามารถสร้างมุมมองเพื่อเชื่อมต่อเข้าด้วยกันเพื่อการรายงาน เหตุผลนี่เป็นตารางที่ใหญ่มาก ๆ แต่การตัดมันทำให้การบำรุงรักษาของ DB นั้นง่ายขึ้น อย่างไรก็ตามมันนำเสนอปัญหาของวิธีการจัดการการแทรกลงในหลายตาราง (ช่วยให้คุณสามารถเริ่มการทำธุรกรรมการทำธุรกรรมในเดือนถัดไปในขณะที่ยังคงปิดการใช้งานล่าสุด) โดยไม่ต้องจบลงด้วยคีย์ที่ซ้ำกัน อีกครั้ง GUID แทนที่จะเป็นคอลัมน์จำนวนเต็มข้อมูลประจำตัวเป็นวิธีการแก้ปัญหาแบบไปสู่เนื่องจาก DBMS ได้รับการออกแบบมาเพื่อสร้างสิ่งเหล่านี้ในลักษณะที่ไม่ซ้ำกันอย่างแท้จริง

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


1
มีบางกรณีที่คุณยังสามารถต้องการ ID ในตาราง M: N (ใช้คอลัมน์ID, ID_M, ID_N) เนื่องจากการแนบคุณสมบัติกับอินสแตนซ์ของความสัมพันธ์ M: N ของคุณ
miroxlav

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

1
@miroxlav - ฉันจะยืนยันว่าหากตารางมีข้อมูลเมตาเพิ่มเติมเพียงพอเกี่ยวกับความสัมพันธ์ที่แยก PK นอก FK สองรายการนั้นเป็นความคิดที่ดีมันไม่ใช่ตารางอ้างอิงโยงอีกต่อไปจริงๆ มันเป็นเอนทิตีของตัวเองที่เกิดขึ้นเพื่ออ้างอิงอีกสองคน
KeithS

@Voo - ถูกต้อง V4 GUID ไม่รับประกันว่าจะถูกเข้ารหัสแบบสุ่มไม่ซ้ำใคร (เหมือน GUID ทั้งหมด) อย่างไรก็ตามหมายเลขหางของเครื่องบินขับไล่ไอพ่นของสหรัฐไม่ได้ถูกสร้างขึ้นจากข้อมูล / อัลกอริธึมแบบสุ่มของการเข้ารหัส สิ่งที่คุณกำลังมองหาคือโดเมนที่มีประชากรเบาบาง V4 GUID มีข้อมูลสุ่ม 112 ไบต์สามารถระบุเร็กคอร์ด 5e33 โดยไม่ซ้ำกัน
KeithS

เพื่อให้ได้ตัวเลขนั้นในมุมมองผู้ชายผู้หญิงและเด็กทุกคนบนโลก (ทั้ง 7 พันล้านคน) สามารถมี 741 ล้านล้านรายการและจุดข้อมูล IDed ใน DB ของเราและเราจะใช้ GUID เดียวต่อพันล้านที่มีอยู่ Big Data ในฐานะอุตสาหกรรมระดับโลกนั้นไม่ได้อยู่ใกล้กับความรู้ในระดับนี้มากนัก แม้จะมีรูปแบบสำหรับการสร้าง GUID แล้วยังมีแหล่งข้อมูลอื่น ๆ ของเอนโทรปีที่เกี่ยวข้องเช่นลำดับที่ข้อมูลเข้าสู่ระบบและได้รับการกำหนด GUID
KeithS

7

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

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

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

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


6

ในขณะที่คนอื่น ๆ ทำกรณีสำหรับคีย์หลักที่เพิ่มขึ้นฉันจะทำให้มันสำหรับ GUID:

  • มันรับประกันว่าจะไม่ซ้ำกัน
  • คุณสามารถมีการเดินทางไปยังฐานข้อมูลน้อยลงสำหรับข้อมูลในแอปพลิเคชันของคุณ (สำหรับตารางประเภทเช่นคุณสามารถจัดเก็บ GUID ในแอปพลิเคชันและใช้เพื่อดึงข้อมูลเรคคอร์ดถ้าคุณใช้ข้อมูลประจำตัวคุณจำเป็นต้องค้นหาฐานข้อมูลตามชื่อและฉันได้เห็นแอปพลิเคชันจำนวนมากที่ทำสิ่งนี้เพื่อรับ PK และหลังจากนั้นก็สอบถามอีกครั้งเพื่อรับรายละเอียดทั้งหมด)
  • มันมีประโยชน์สำหรับการซ่อนข้อมูล www.domain.com/Article/2 ให้ฉันรู้ว่าคุณมีสองบทความเท่านั้นในขณะที่ www.domain.com/article/b08a91c5-67fc-449f-8a50-ffdf2403444a บอกอะไรฉันไม่ได้
  • คุณสามารถรวมระเบียนจากฐานข้อมูลต่าง ๆ ได้อย่างง่ายดาย
  • MSFT ใช้ GUIDS เพื่อระบุตัวตน

แก้ไข: จุดซ้ำ


5
-1 GUID / UUID ไม่รับประกันว่าจะไม่ซ้ำกันและไม่ซ้ำกัน 100% GUID ยังคงมีความยาว จำกัด ดังนั้นในบางจุดคุณอาจเสี่ยงต่อการซ้ำซ้อนแม้ว่าจะไม่น่าเป็นไปได้สูง จุดของคุณเกี่ยวกับการเดินทางไปยังฐานข้อมูลน้อยเกินไปก็ไม่ถูกต้องด้วยเหตุใดคุณจึงไม่สามารถจัดเก็บ ID หลักในแอปพลิเคชันอย่างที่คุณสามารถทำได้ด้วยปุ่ม GUID
Niklas H

2
Jeff Atwood บอกว่ามันดีกว่าที่ฉันเคยทำได้ blog.codinghorror.com/primary-keys-ids-versus-guids
สามค่าตรรกะ

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

คุณไม่ได้พูดอะไรเกี่ยวกับการสร้าง ID ในแอปพลิเคชัน - คุณเพิ่งเขียนว่า "การจัดเก็บ" แต่ถ้าจำเป็นต้องสร้าง ID นอกฐานข้อมูลใช่แล้ว GUID อาจเป็นคำตอบ
Niklas H

2
ฉันจะเพิ่มพวกเขาขยายขนาดดีขึ้น ฐานข้อมูลขนาดใหญ่ NoSQL อย่างคาสซานดราไม่รองรับแม้แต่ปุ่มเพิ่มอัตโนมัติ
Karl Bielefeldt

2

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

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

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

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


2

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

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

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

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

เนื่องจากเหตุผลเพียงประการเดียวสำหรับการแนะนำคีย์ตัวแทนคือประสิทธิภาพการทำงานให้เราเข้าใจว่าเราต้องการให้มันเป็นนักแสดง หากปัญหาด้านประสิทธิภาพใกล้เคียงกันเราจำเป็นต้องทำให้คีย์ตัวแทนของเราแคบเท่าที่จะเป็นได้ (โดยไม่ได้รับในทางของฮาร์ดแวร์ดังนั้นจำนวนเต็มและไบต์สั้นมักจะหมด) การเข้าร่วมนั้นขึ้นอยู่กับความสูงของดัชนีขั้นต่ำดังนั้นจำนวนเต็ม 4 ไบต์จึงเป็นวิธีแก้ปัญหาตามธรรมชาติ หากปัญหาประสิทธิภาพการทำงานของคุณคืออัตราการแทรกจำนวนเต็ม 4 ไบต์อาจเป็นวิธีแก้ปัญหาตามธรรมชาติ (ขึ้นอยู่กับ internals ของ RDBMS ของคุณ) หากปัญหาประสิทธิภาพการทำงานของคุณสำหรับตารางเป็นการจำลองแบบหรือแหล่งข้อมูลหลายแหล่งกว่าเทคโนโลยีคีย์ตัวแทนอื่น ๆไม่ว่าจะเป็น GUID หรือคีย์สองส่วน (ID โฮสต์ + จำนวนเต็ม) อาจเหมาะสมกว่า ฉันไม่ใช่คนโปรดของ GUIDs แต่พวกเขาสะดวก

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

กรณีพิเศษ

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

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

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


-1

ไม่เพียงเป็นการปฏิบัติที่ไม่ดี แต่จริงๆแล้วมันอธิบายว่าเป็นรูปแบบการต่อต้านในหนังสือ SQL Antipatterns ของ Bill Karwin

ไม่ใช่ทุกโต๊ะที่ต้องการ pseudokey - คีย์หลักที่มีค่าตามอำเภอใจไม่ใช่สิ่งที่มีค่าความหมายสำหรับแบบจำลอง - และไม่มีเหตุผลใดที่จะเรียกมันidเสมอ


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

2
และทำไมสิ่งนี้จึงมีความสำคัญ
ริ้น

3
@gnat เพราะเป็นหนังสือเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดซึ่งตอบคำถามโดยตรง ไม่ชัดเจนหรือ
Pedro Werneck

3
ไม่น้อย การค้นหาโดย Google สำหรับ "หนังสือแนวปฏิบัติที่ดีที่สุดของ sql" แสดงลิงก์เกี่ยวกับ 900K ให้ฉันทำไมรายการนี้ถึงมีค่ามาก
gnat

1
@gnat ฉันจะไม่โต้แย้งตลอดทั้งวัน คุณไม่ชอบคำตอบนั่นคือสิ่งที่ downvote มีไว้สำหรับ
Pedro Werneck

-2

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

ฉันมักจะทำให้ตัวชี้ชื่อฟิลด์ที่ชัดเจนเช่นref_{table}หรือความคิดที่คล้ายกันมากขึ้น

หากไม่จำเป็นต้องชี้ไปที่ระเบียนภายนอกคุณไม่จำเป็นต้องมี ID


ค่าคีย์โรลโอเวอร์หรือไม่
AJJ

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

จำนวนเต็มล้น - en.wikipedia.org/wiki/Integer_overflow
Johnny V

2
หากคุณเพิ่ม / ลบแถวจำนวนมากตัวนับการเพิ่มอัตโนมัติจะล้นในที่สุด
จอห์นนี่ V

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

-2

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


-3

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

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

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

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

UUIDs ฉันไม่ได้ใช้เป็นคีย์หลักเนื่องจากค่าใช้จ่ายในการสร้างและจัดเก็บพวกเขานั้นสูงกว่าการเพิ่มค่าความยาวหนึ่ง UUID ยังคงจัดการกับความขัดแย้งในวันเกิดซึ่งซ้ำซ้อนในทางทฤษฎีสามารถเกิดขึ้นได้


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

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