คีย์หลักควรไม่เปลี่ยนรูปหรือไม่


26

คำถามล่าสุดใน StackOverflowเจ็บใจอภิปรายเกี่ยวกับการเปลี่ยนรูปของคีย์หลัก ฉันคิดว่ามันเป็นกฎที่คีย์หลักควรจะไม่เปลี่ยนรูป หากมีโอกาสที่บางวันจะมีการอัปเดตคีย์หลักฉันคิดว่าคุณควรใช้คีย์ตัวแทน อย่างไรก็ตามมันไม่ได้อยู่ในมาตรฐาน SQL และคุณสมบัติ "cascade update" ของ RDBMS บางตัวอนุญาตให้เปลี่ยนคีย์หลักได้

ดังนั้นคำถามของฉันคือ: มันยังคงเป็นวิธีที่ไม่ดีที่จะมีคีย์หลักที่อาจมีการเปลี่ยนแปลง? ข้อเสียถ้ามีมีคีย์หลักที่ไม่แน่นอนคืออะไร?

คำตอบ:


25

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

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


7
ทำไมคุณ " ต้องการคีย์หลักให้ไม่เปลี่ยนรูปถ้ามันเชื่อมโยงกับคีย์ต่างประเทศ"? ตามที่ OP ได้กล่าวไว้ RDBMS ส่วนใหญ่จะมีคุณสมบัติการปรับปรุง "cascade"
Thanatos

1
@Tanatos ส่วนใหญ่ (อันที่จริงทั้งหมดที่ฉันได้พบ) rdbms จะไม่อนุญาตให้ใช้คีย์หลักที่ไม่แน่นอน แต่ยังมีการปรับปรุงเรียงซ้อน คีย์หลักในภูมิปัญญา dba ที่เป็นที่ยอมรับโดยทั่วไปไม่ควรมีข้อมูลใด ๆ เป็นเพียงตัวระบุเรคคอร์ดที่ไม่ซ้ำกัน (ดังนั้นแม้จะไม่ได้เป็นประทับเวลา
jwenting

5
@ jwenting: เรากำลังพูดถึงสิ่งเดียวกันหรือไม่? "rdbms ส่วนใหญ่จะไม่อนุญาตให้ใช้คีย์หลักที่ไม่แน่นอน" รวมถึงอะไร MySQL และ PostgreSQL ต่างก็อนุญาตให้มีคีย์หลักที่ไม่แน่นอนและให้เกียรติการอัพเดทแบบต่อเนื่อง…เพราะฉันคิดว่า SQL มาตรฐานบอกว่าควร นอกจากนี้ "ภูมิปัญญา dba ที่ยอมรับกันโดยทั่วไป"? ฉันได้พบกับ DBA มากมายที่โต้เถียงกับกุญแจตัวแทนและอีกมากมายที่โต้เถียงกับคีย์ธรรมชาติ
Thanatos

2
@Tanatos โต้แย้งในความโปรดปรานของ"ตารางทั้งหมดจะต้องมีตัวแทน"ขาดการอ้างอิงบรรณานุกรมพวกเขาอ้างว่า "ภูมิปัญญา DBA ยอมรับโดยทั่วไป" แต่พวกเขาไม่เคยอ้างหนังสือ หนังสือ Canonical บอกว่าคุณควรใช้ตัวแทนถ้า: A. ไม่มีรหัสธรรมชาติอยู่, B. หมายเลขหลายคอลัมน์มีจำนวนเกิน 3 คอลัมน์หรือ, C. คุณจะเปลี่ยนรหัสตลอดเวลา ดังนั้น: โดยธรรมชาติเมื่อมันเข้าที่พอดีตัวแทนจะเกิดขึ้นเมื่อธรรมชาติไม่เหมาะสม
Tulains Córdova

4
@ user61852: อะไรนะ
Guffa

15

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

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


15

ใช่ในความคิดของฉันคีย์หลักควรจะไม่เปลี่ยนรูป

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


จุดที่ดีเกี่ยวกับข้อผิดพลาดในการป้อนข้อมูล
Tim Goodman

richeym ดูเหมือนว่าคุณกำลังทำกรณีที่ปุ่มต้องไม่เปลี่ยนไม่ได้: ผู้ใช้อาจต้องการเปลี่ยนพวกเขา
nvogel

4
@dportas - ประเด็นของฉันคือฉันชอบ PK ที่ไม่เปลี่ยนรูปดังนั้นควรใช้คีย์ตัวแทนแทนแม้ว่าฉันคิดว่ามีคีย์ที่ชัดเจนที่สามารถรับได้จากข้อมูลตาราง (เช่นอีเมลชื่อผู้ใช้)
richeym

2

กลไกการแคชระหว่างฐานข้อมูลและผู้ใช้จะสูญเสียประสิทธิภาพหากเปลี่ยนคีย์หลัก


2

ทำไมไม่ เพราะคุณต้องการกำจัดคอลัมน์?

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

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

คอมพิวเตอร์ไม่ต้องการความหมายใด ๆ สำหรับคีย์ IMHO กุญแจสำหรับคอมพิวเตอร์ปล่อยให้คนไขส่วนที่เหลือของข้อมูล


1
"กุญแจสำหรับคอมพิวเตอร์ให้คนไขส่วนที่เหลือของข้อมูล" +1 ดี

2

ไม่ใช่วิธีปฏิบัติที่ไม่ดีที่จะมีคีย์ซึ่งค่าอาจมีการเปลี่ยนแปลง

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

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

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


3
ISBN เป็นความกว้างคงที่ยกเว้นเมื่อไม่มี (ดู ISBN-10 เทียบกับ ISBN-13)
CVn

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

1

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


1

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


0

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

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

  • สร้างรีจิสทรีใหม่ในตาราง Books
  • ชี้การอ้างอิงทั้งหมดจาก ISBN เก่าไปยัง ISBN ใหม่ (*)
  • และในที่สุดลบรีจิสตรีเก่าออกจาก Table Books

(*) นี่อาจเป็นเรื่องที่ไม่สำคัญที่จะค้นหาการอ้างอิงทั้งหมดสำหรับโมเดลฐานข้อมูลที่ใช้ Foreign Keys แต่บางรุ่นขาดไป

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

เราเปลี่ยนเป็น

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

ที่InternalBookIdใหม่อาจเป็นค่าตัวเลขได้ด้วยตนเอง

ข้อเสียเกี่ยวกับมัน

  • มันเพิ่มเขตข้อมูลใหม่ที่ใช้พื้นที่ / ทรัพยากรเพิ่มเติม

  • มันอาจต้องมีการเขียนทั้งโมเดลใหม่

  • รุ่นใหม่อาจอธิบายตนเองน้อยลง

มืออาชีพ

  • ช่วยให้การกลายพันธุ์ "คีย์หลัก"
  • อนุญาตให้วางหรือปรับโครงสร้างใหม่ "คีย์หลัก" ตัวอย่างเช่นการเปลี่ยนหนังสือเป็น ISBN-13 นั้นง่ายมาก ๆ เพียงแค่วางคอลัมน์ที่เก่ากว่าและสร้างใหม่

ตารางใหม่:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.