Guid vs INT - คีย์ไหนดีกว่ากัน?


97

ผมเคยถูกอ่านไปรอบ ๆ เหตุผลที่จะใช้หรือไม่และGuidint

intมีขนาดเล็กลงเร็วขึ้นและง่ายต่อการจดจำตามลำดับเวลา และสำหรับGuidข้อได้เปรียบเดียวที่ฉันพบคือมันไม่เหมือนใคร ในกรณีGuidใดจะดีกว่าintและทำไม?

จากสิ่งที่ฉันเห็นintไม่มีข้อบกพร่องยกเว้นโดยการ จำกัด จำนวนซึ่งในหลายกรณีไม่เกี่ยวข้อง

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

(Guid = UniqueIdentifier) ​​พิมพ์บน SQL Server


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

ยังจำความแตกต่างระหว่าง (หลัก) KEY และ INDEX
Allan S. Hansen

1
ยังกล่าวถึงใน SO: stackoverflow.com/questions/11033435/ …
Jon of All Trades

2
" intไม่มีข้อบกพร่องยกเว้นโดย จำกัด จำนวนซึ่งในหลายกรณีไม่เกี่ยวข้อง": จริง ๆ แล้วในบริบทของ INT vs GUID นี้ขีด จำกัด สูงสุดของการลงนาม 32- บิตINTนั้นไม่เกี่ยวข้องทั้งหมดเนื่องจากขีด จำกัด สูงสุดของการเซ็นชื่อ 64- บิตBIGINTนั้นดีกว่าการใช้งานเกือบทุกอย่าง (ยิ่งถ้าคุณเริ่มนับเลขที่ขีด จำกัด ล่างและเหมือนกันก็ใช้INT) และยังคงมีขนาดครึ่งหนึ่งของ GUID (8 ไบต์แทน 16) และเรียงตามลำดับ
โซโลมอน Rutzky

คำตอบ:


89

นี้ได้รับการถามในกองมากเกินที่นี่และที่นี่

โพสต์ของ Jeffอธิบายเกี่ยวกับข้อดีข้อเสียของการใช้ GUID เป็นอย่างมาก

ข้อดีของ GUID

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

ข้อด้อยของ GUID

  • มันใหญ่กว่าค่าดัชนี 4 ไบต์แบบเดิมถึง 4 เท่า สิ่งนี้อาจมีประสิทธิภาพที่ร้ายแรงและความหมายของพื้นที่จัดเก็บหากคุณไม่ระวัง
  • ยุ่งยากในการแก้ไขข้อบกพร่อง ( where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • GUID ที่สร้างขึ้นควรเรียงตามลำดับบางส่วนเพื่อประสิทธิภาพที่ดีที่สุด (เช่นnewsequentialid()บน SQL Server 2005+) และเพื่อให้สามารถใช้ดัชนีแบบคลัสเตอร์ได้

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


20
ข้อเสียอีกอย่างหนึ่งของแนวทางของ GUID คือคุณไม่สามารถใช้เป็นตัวระบุสำหรับผู้ใช้ปลายทางของคุณได้ คุณคาดหวังให้ผู้ใช้ของคุณบอกคุณทางโทรศัพท์ว่าพวกเขามีปัญหากับคำสั่ง "BAE7DF4-DDF-3RG-5TY3E3RF456AS10" หรือไม่ :)
Brann

3
หากคุณไม่ได้ใช้ guids ต่อเนื่องและคีย์หลักของคุณคือคลัสเตอร์ (SQL Server defaul) ดังนั้นข้อมูลของคุณทั้งหมดจะถูกกระจายแบบสุ่มทั่วทั้งตารางซึ่งจะทำให้ข้อมูลของคุณกระจัดกระจาย นั่นคือการสันนิษฐานว่าข้อมูลจะถูกแทรกตามลำดับปกติเช่นตามลำดับเหตุการณ์
datagod

6
ลำดับ guids เป็นลำดับเท่านั้นจนกว่าจะเริ่มอินสแตนซ์ SQL จากนั้นค่าแรกจะมีค่าต่ำกว่าค่าก่อนหน้าเนื่องจากวิธีการที่สร้างค่ารากทำให้เกิดปัญหาทุกประเภทอีกครั้ง
mrdenny

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

2
@ChadKuehn เลือกUNIQUEIDENTIFIERมากกว่าINTเพราะINTมีขีด จำกัด บนเป็นเหตุผลที่ค่อนข้างยากจนตั้งแต่เป็นที่ไร้ขีด จำกัด ในขณะที่ความจริงพอไม่ได้เป็นในทางปฏิบัติได้รับประโยชน์ คุณสามารถเพิ่มขีดความสามารถที่มีประสิทธิภาพเป็นสองเท่าได้อย่างง่ายดายINTโดยเริ่มต้นที่ขีด จำกัด ล่าง (-2.14 พันล้าน) แทนที่จะเป็น 1 หรือถ้า 4.3 พันล้านเต็มไม่เพียงพอจากนั้นเริ่มต้นด้วยตัวBIGINTที่ยังเหลือเพียง 8 ไบต์เท่านั้น เทียบกับ 16 สำหรับ GUID และเป็นประโยชน์
โซโลมอน Rutzky

18

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


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

15

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


3
GUID ให้คุณค่าอะไรถ้าidมนุษย์มีเพียงพอในการระบุแถวแล้ว?
Martin Smith เมื่อ

6
ID ระบุแถวในตารางนี้ GUID (อย่างน้อยในทางทฤษฎี) ระบุแถวนี้ที่ใดก็ได้ในจักรวาลที่รู้จัก ในโครงการของฉันโทรศัพท์มือถือ Android แต่ละเครื่องมีสำเนาที่เหมือนกันของโครงสร้างในฐานข้อมูล SQLite ท้องถิ่น แถวและ GUID ของแต่ละแถวนั้นสร้างขึ้นบน Android จากนั้นเมื่อ Android ถูกซิงโครไนซ์กับฐานข้อมูลส่วนหลังแถวแถวนั้นจะถูกเขียนลงในตารางส่วนหลังโดยไม่ต้องกลัวว่าจะเกิดความขัดแย้งกับแถวที่สร้างจากมือถือ Android อื่น ๆ
rmirabelle

2
@MartinSmith ฉันได้ใช้วิธีการนี้ด้วยตัวเองและใช้งานได้ดี GUID เป็นเพียงคีย์สำรองที่มีดัชนีแบบไม่รวมกลุ่มและส่งผ่านจากแอปพลิเคชัน แต่จะอยู่ในตารางหลักเท่านั้น ตารางที่เกี่ยวข้องทั้งหมดเกี่ยวข้องกันผ่านทางINTPK ฉันคิดว่ามันแปลกที่วิธีการนี้ไม่ได้เกิดขึ้นบ่อยนักเพราะมันเป็นสิ่งที่ดีที่สุดของทั้งสองโลก ดูเหมือนว่าคนส่วนใหญ่เพียงต้องการที่จะแก้ปัญหาในแง่ที่สมบูรณ์แบบมากโดยไม่ทราบว่า PK ไม่จำเป็นต้องเป็น GUID เพื่อให้แอปยังคงใช้ GUID สำหรับเอกลักษณ์และความสะดวกในการพกพาทั่วโลก
โซโลมอน Rutzky

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

1
@ ผู้ใช้ฉันเห็นด้วยกับการไม่เพิ่มเขตข้อมูล ID "เพื่อประโยชน์ของมัน" เช่นในตาราง "สะพาน" หลายต่อหลายคนที่ PK ควรเป็นคอมโพสิตของสอง FK ที่เกี่ยวข้อง แต่ที่นี่ไม่ใช่การแลกเปลี่ยนเนื่องจากฟิลด์ ID ไม่เพียงเพื่อประโยชน์ของมัน การอนุญาตให้ระบบทำงานได้อย่างมีประสิทธิภาพนั้นเป็นสิ่งสำคัญพอสมควร ;-) และฉันขอยืนยันว่าในกรณีของคุณเนื่องจาก GUID นั้นสร้างขึ้นจากภายนอกสิ่งเหล่านั้นไม่ได้รับประกันว่าจะไม่ซ้ำกันแม้ว่าในทางปฏิบัติจะเป็นเช่นนั้น แต่ความรับผิดชอบสำหรับความถูกต้องของข้อมูลนั้นมีเหตุผลเพียงพอที่จะให้ GUID เป็นคีย์สำรองและ ID เป็น PK ในกรณีของคุณ :)
โซโลมอน Rutzky

1

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

แน่นอนข้อเสียเปรียบของเรื่องนี้ก็คือ "ปฏิเสธที่จะปรับขนาดได้!"


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

ฉันรู้ว่าเสียงนี้ชัดเจนมาก แต่ฉันเห็นว่าถูกลืมไปบ่อยครั้ง

สำหรับบริบท: คำตอบส่วนนี้ได้รับการแก้ไขจากวิธีการทางทฤษฎีข้อมูลที่คุณต้องการให้ PK ของคุณเป็นตัวระบุข้อมูลที่ไม่ซ้ำกันสำหรับบันทึก เวลาส่วนใหญ่ที่เราสร้างเมื่อมีอยู่แล้วดังนั้นคำตอบก่อนหน้า

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

ขอบคุณ @VahiD สำหรับคำชี้แจง


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

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

โหวตขึ้นสำหรับการพัฒนาในปีที่ผ่านมา :)
VahiD

1

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


0

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

แค่ความคิดและฉันหวังว่าฉันจำได้อย่างถูกต้อง ขอให้มีความสุขมาก ๆ ในวันนี้!


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

-6

ใช้ทั้งสองอย่าง

ใช้int / Bigintสำหรับคีย์หลักเนื่องจากง่ายต่อการบำรุงรักษาและใช้เป็นความสัมพันธ์กับคีย์ต่างประเทศ

แต่ผูกคอลัมน์กับGUIDเพื่อให้ทุกแถวมีคอลัมน์ที่ไม่ซ้ำกัน


2
การอธิบายเหตุผลของคุณที่อยู่เบื้องหลังข้อเสนอแนะนี้จะไม่ทำร้ายใครฉันแน่ใจ
Andriy M

GUID มีความยาว 36 ตัวอักษรจะอ่านยากในกรณีที่คุณกำลังค้นหากรณีเฉพาะ ..
Abdul Hannan Ijaz

1
เอาล่ะ แต่นั่นไม่ได้อธิบายว่าทำไม OP จึงควรใช้ทั้งคู่intและguidอย่างที่คุณแนะนำในคำตอบของคุณ และนอกจากนี้ผมไม่ได้พูดคุยเกี่ยวกับการอธิบายข้อเสนอแนะของคุณเพียงแค่ให้ฉัน - จุดของฉันคือการที่คุณอาจต้องการที่จะปรับปรุงคำตอบของคุณ คุณทราบหรือไม่ว่าผู้ตอบอีกคนหนึ่งแนะนำให้คุณเหมือนกัน (มากกว่าหรือน้อยกว่า) ในขณะที่คุณ ?
Andriy M

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