Keuntungan dan kerugian dari kunci basis data GUID / UUID


222

Saya telah bekerja pada sejumlah sistem basis data di masa lalu di mana memindahkan entri di antara basis data akan menjadi jauh lebih mudah jika semua kunci basis data merupakan nilai-nilai GUID / UUID . Saya telah mempertimbangkan untuk menyusuri jalan ini beberapa kali, tetapi selalu ada sedikit ketidakpastian, terutama di seputar kinerja dan URL yang tidak dapat dibaca-lewat-telepon-bisa.

Adakah yang bekerja secara luas dengan GUID dalam database? Keuntungan apa yang akan saya dapatkan dengan pergi ke sana, dan apa kemungkinan jebakannya?


1
Jeff memiliki pos tentang itu " Kunci Utama: ID versus GUID ".
jfs

1
juga dapat menggunakan Hi-Lo untuk klien jarak jauh: stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm
Neil McGuigan


Lokasi yang diperbarui untuk posting Jeff Atwood tentang " Kunci Utama: ID versus GUID ." Terima kasih kepada @jfs untuk referensi.
Adam Katz

Jawaban:


229

Keuntungan:

  • Dapat menghasilkannya secara offline.
  • Membuat replikasi sepele (bukan int, yang membuatnya SANGAT sulit)
  • ORM biasanya menyukai mereka
  • Unik di seluruh aplikasi. Jadi, kita dapat menggunakan PK dari CMS kami (guid) di aplikasi kami (juga guid) dan tahu bahwa kami TIDAK PERNAH akan mendapatkan bentrokan.

Kekurangan:

  • Penggunaan ruang lebih besar, tetapi ruang murah (er)
  • Tidak dapat memesan dengan ID untuk mendapatkan pesanan yang dimasukkan.
  • Dapat terlihat jelek di URL, tapi sungguh, WTF yang Anda lakukan meletakkan kunci DB NYATA di URL !? (Poin ini diperdebatkan dalam komentar di bawah)
  • Sulit melakukan debugging manual, tetapi tidak terlalu sulit.

Secara pribadi, saya menggunakannya untuk sebagian besar PK dalam sistem apa pun dari ukuran yang layak, tetapi saya "dilatih" pada sistem yang direplikasi di semua tempat, jadi kami HARUS memilikinya. YMMV.

Saya pikir data duplikat adalah sampah - Anda bisa mendapatkan data duplikat namun Anda melakukannya. Kunci pengganti biasanya disukai di mana pun saya pernah bekerja. Kami menggunakan sistem seperti WordPress:

  • ID unik untuk baris (GUID / apa pun). Tidak pernah terlihat oleh pengguna.
  • ID publik dihasilkan SEKALI dari beberapa bidang (misalnya judul - jadikan itu-judul-artikel-itu)

UPDATE: Jadi yang ini banyak mendapat +1, dan saya pikir saya harus menunjukkan kelemahan besar GUID PK's: Clustered Indexes.

Jika Anda memiliki banyak catatan, dan indeks berkerumun di GUID, kinerja penyisipan Anda akan SUCK, karena Anda mendapatkan sisipan di tempat acak dalam daftar item (itu intinya), bukan pada akhirnya (yang cepat)

Jadi, jika Anda perlu menyisipkan kinerja, mungkin gunakan INT otomatis masuk, dan hasilkan GUID jika Anda ingin membaginya dengan orang lain (yaitu, perlihatkan kepada pengguna di URL)


184
[WTF yang kamu lakukan memasukkan kunci DB NYATA di URL !?] Tidak yakin mengapa itu mengganggumu. Apa lagi yang akan Anda gunakan? Lihatlah Stack Overflow ... Ini memiliki nilai IDENTITAS di URL di semua tempat, dan berfungsi dengan baik. Menggunakan kunci DB dalam URL tidak mencegah Anda menerapkan keamanan.
Euro Micelli

20
Tidak, tidak, tetapi hal-hal seperti SEO biasanya lebih baik jika tidak ada kunci di dalamnya - terutama sesuatu selama GUID. Tentu saja, itu dapat dikerjakan dengan mudah, jadi saya pikir itu sedikit pernyataan yang berlebihan
Nic Wise

7
Jawaban yang bagus, alangkah baiknya jika Anda juga menambahkan informasi tentang kerugian kinerja dalam menggunakan GUID; misalnya bergabung, menyortir, dan mengindeks oleh mereka semua akan lebih lambat daripada menggunakan bilangan bulat. Panduan memang luar biasa, tetapi harganya sangat mahal karena kinerja sangat penting.
Dokter Jones

26
Ingat satu hal, orang sering mengubah halaman, pertanyaan, judul forum. Untuk SEO, BAIK untuk memiliki sesuatu seperti ID kecil di URL sehingga jika judulnya berubah Anda masih tahu ke mana harus meneruskan orang yang datang dari URL TUA. example.com/35/old-and-bustedbaru saja menjadi example.com/35/new-hotnessdan aplikasi Anda cukup memeriksa judulnya dan meneruskan pengguna dengan 301.
Xeoncross

9
Mengindeks GUID itu mahal dan lambat, yang menjadikannya kandidat yang sangat buruk untuk kunci primer.
Matthew James Davis

14

@Matt Sheppard:

Katakanlah Anda memiliki tabel pelanggan. Tentunya Anda tidak ingin pelanggan ada di tabel lebih dari sekali, atau banyak kebingungan akan terjadi di seluruh departemen penjualan dan logistik Anda (terutama jika beberapa baris tentang pelanggan berisi informasi yang berbeda).

Jadi, Anda memiliki pengenal pelanggan yang secara unik mengidentifikasi pelanggan dan Anda memastikan bahwa pengenal tersebut diketahui oleh pelanggan (dalam faktur), sehingga pelanggan dan orang layanan pelanggan memiliki referensi umum jika mereka perlu berkomunikasi. Untuk menjamin tidak ada rekaman pelanggan yang digandakan, Anda menambahkan kendala keunikan ke tabel, baik melalui kunci utama pada pengidentifikasi pelanggan atau melalui batasan NOT NULL + UNIK pada kolom pengidentifikasi pelanggan.

Selanjutnya, untuk beberapa alasan (yang tidak dapat saya pikirkan), Anda diminta untuk menambahkan kolom GUID ke tabel pelanggan dan menjadikannya sebagai kunci utama. Jika kolom pengidentifikasi pelanggan sekarang dibiarkan tanpa jaminan keunikan, Anda meminta masalah di masa mendatang di seluruh organisasi karena GUID akan selalu unik.

Beberapa "arsitek" mungkin memberi tahu Anda bahwa "oh, tapi kami menangani kendala keunikan pelanggan nyata di tingkat aplikasi kami!". Baik. Mode mengenai bahasa pemrograman tujuan umum dan (terutama) kerangka kerja tingkat menengah berubah sepanjang waktu, dan umumnya tidak akan pernah menyiarkan database Anda. Dan ada peluang yang sangat bagus bahwa Anda pada suatu saat perlu mengakses database tanpa melalui aplikasi yang ada. == Masalah. (Tapi untungnya, Anda dan "arsitek" sudah lama pergi, jadi Anda tidak akan ada di sana untuk membersihkan kekacauan itu.) Dengan kata lain: Tetap menjaga batasan yang jelas dalam database (dan di tingkatan lain, juga, jika Anda memiliki waktu).

Dengan kata lain: Mungkin ada alasan bagus untuk menambahkan kolom GUID ke tabel, tapi tolong jangan tergoda untuk membuat itu menurunkan ambisi Anda untuk konsistensi dalam informasi nyata (== non-GUID).


1
Dengar dengar! Sukai halaman perbandingan SQL Anda btw. Sangat bermanfaat. Satu-satunya hal yang saya lewatkan adalah changelog.
Henrik Gustafsson

3
Saya pikir jawaban ini membutuhkan beberapa klarifikasi: ini mengasumsikan bahwa UUID tidak pernah digunakan sebagai kunci utama. Saya tidak tahu dari mana asumsi ini berasal, tetapi saya belum melihat sistem yang tidak memungkinkan Anda untuk menggunakannya. Saya tahu ini adalah jawaban lama, saya kira keuntungan menggunakan UUID dalam sistem terdistribusi tidak dipahami secara luas saat itu (?).
mentega

12

Mengapa tidak ada yang menyebutkan kinerja? Ketika Anda memiliki banyak gabungan, semua berdasarkan pada GUID jahat ini kinerjanya akan menembus lantai, sudah ada di sana :(


1
Bisakah Anda menguraikan ini seperti saya dalam situasi di mana saya perlu memperkenalkan UUID (atau serupa), tetapi saya khawatir tentang menggunakannya sebagai Primary Key.
JoeTidee

1
UUID hanya 4 kali ukuran bilangan bulat ... (jika database Anda memiliki jenis UUID)
Jasen

11

GUIDs dapat menyebabkan Anda banyak masalah di masa depan jika mereka digunakan sebagai "penyeimbang", membiarkan data yang digandakan masuk ke tabel Anda. Jika Anda ingin menggunakan GUID, harap pertimbangkan untuk tetap mempertahankan batasan UNIQUE pada kolom lain.


11
Inilah inti masalahnya: Memperkenalkan GUID membuat setiap baris menjadi unik. Tetapi bagian non-artifisial dari barisan tiba-tiba dapat berisi duplikat (beberapa versi kebenaran).
Troels Arvin

8
+1 untuk memberi kompensasi. Aku mengerti maksudmu, tapi itu diungkapkan dengan buruk.
Stefano Borini

11

Keuntungan utama adalah bahwa Anda dapat membuat id unik tanpa terhubung ke database. Dan id adalah unik secara global sehingga Anda dapat dengan mudah menggabungkan data dari database yang berbeda. Ini tampak seperti keuntungan kecil tetapi telah menyelamatkan saya banyak pekerjaan di masa lalu.

Kerugian utama adalah sedikit lebih banyak penyimpanan yang dibutuhkan (bukan masalah pada sistem modern) dan id tidak benar-benar dapat dibaca manusia. Ini bisa menjadi masalah saat debugging.

Ada beberapa masalah kinerja seperti fragmentasi indeks. Tapi itu mudah dipecahkan (sisir dengan jimmy nillson: http://www.informit.com/articles/article.aspx?p=25862 )

Sunting menggabungkan kedua jawaban saya untuk pertanyaan ini

@Matt Sheppard Saya pikir maksudnya Anda dapat menduplikasi baris dengan GUID berbeda sebagai kunci utama. Ini adalah masalah dengan segala jenis kunci pengganti, bukan hanya GUID. Dan seperti yang dia katakan, ini mudah dipecahkan dengan menambahkan batasan unik yang bermakna pada kolom non-kunci. Alternatifnya adalah dengan menggunakan kunci alami dan mereka yang memiliki masalah nyata ..


Saya tahu tentang sisir pengarah dan itu membantu menyelesaikan masalah pengindeksan (kinerja INSERT). " Kerugian utama adalah penyimpanan yang sedikit lebih dibutuhkan " Apakah ini akan memukul kinerja karena ukuran file database yang besar?
Amit Joshi

8

Satu masalah kecil lainnya untuk dipertimbangkan dengan menggunakan GUIDS sebagai kunci utama jika Anda juga menggunakan kolom itu sebagai indeks berkerumun (praktik yang relatif umum). Anda akan menerima pukulan pada sisipan karena sifat panduan tidak memulai secara berurutan, sehingga mereka akan terbagi menjadi halaman, dll ketika Anda memasukkan. Hanya sesuatu yang perlu dipertimbangkan jika sistem akan memiliki IO tinggi ...


6

primary-keys-ids-versus-guids

Biaya GUID sebagai Kunci Utama (SQL Server 2000)

Mitos, GUID vs Autoincrement (MySQL 5)

Ini benar-benar yang Anda inginkan.

Pro UID

  • Unik di setiap tabel, setiap basis data, setiap server
  • Mengizinkan penggabungan catatan dengan mudah dari database yang berbeda
  • Mengizinkan distribusi database dengan mudah di beberapa server
  • Anda dapat membuat ID di mana saja, alih-alih harus bolak-balik ke database
  • Kebanyakan skenario replikasi membutuhkan kolom GUID

Kontra GUID

  • Ini adalah kekalahan 4 kali lebih besar dari nilai indeks 4 byte tradisional; ini dapat memiliki implikasi kinerja dan penyimpanan yang serius jika Anda tidak berhati-hati
  • Tidak praktis untuk debug (di mana userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • GUID yang dihasilkan harus secara berurutan parsial untuk kinerja terbaik (misalnya, new followingentialid () pada SQL 2005) dan untuk memungkinkan penggunaan indeks berkerumun

1

Ada satu hal yang tidak benar-benar diatasi, yaitu menggunakan ID acak (UUIDv4) sebagai kunci primer akan merusak kinerja indeks kunci primer . Ini akan terjadi apakah meja Anda dikelompokkan di sekitar kunci.

RDBM biasanya memastikan keunikan kunci primer, dan memastikan pencarian dengan kunci, dalam struktur yang disebut BTree, yang merupakan pohon pencarian dengan faktor percabangan besar (pohon pencarian biner memiliki faktor percabangan 2). Sekarang, ID integer berurutan akan menyebabkan sisipan terjadi hanya satu sisi pohon, meninggalkan sebagian besar simpul daun tidak tersentuh. Menambahkan UUID acak akan menyebabkan insersi membelah node daun di seluruh indeks.

Demikian juga jika data yang disimpan sebagian besar temporal, sering terjadi bahwa data terbaru perlu diakses dan digabungkan dengan yang paling banyak. Dengan UUID acak, polanya tidak akan mendapat manfaat dari ini, dan akan memukul lebih banyak baris indeks, sehingga membutuhkan lebih banyak halaman indeks dalam memori. Dengan ID berurutan jika data terbaru paling dibutuhkan, halaman indeks panas akan membutuhkan lebih sedikit RAM.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.