Guid vs INT - Mana yang lebih baik sebagai kunci utama?

97

Saya sudah membaca alasan untuk menggunakan atau tidak Guiddan int.

intlebih kecil, lebih cepat, mudah diingat, menyimpan urutan kronologis. Dan untuk Guid, satu-satunya keuntungan yang saya temukan adalah unik. Dalam hal apa a Guidakan lebih baik daripada dan intdan mengapa?

Dari apa yang saya lihat, inttidak memiliki kekurangan kecuali oleh batas angka, yang dalam banyak kasus tidak relevan.

Mengapa tepatnya Guiddiciptakan? Saya benar-benar berpikir itu memiliki tujuan selain berfungsi sebagai kunci utama dari sebuah tabel sederhana. (Adakah contoh aplikasi nyata yang menggunakan Guidsesuatu?)

(Guid = UniqueIdentifier) ​​ketik pada SQL Server

BrunoLM
sumber
1
Daripada kunci primer , saya pikir maksud Anda kunci pengganti yaitu kunci yang bukan kunci alami (yang terakhir adalah kunci yang kami gunakan di dunia nyata). Mungkin maksud Anda adalah indeks berkerumun.
onedaywhen
Juga ingat perbedaan antara (Utama) KUNCI dan INDEKS.
Allan S. Hansen
1
Juga dibahas pada SO: stackoverflow.com/questions/11033435/…
Jon of All Trades
2
" inttidak memiliki kelemahan kecuali oleh batas angka, yang dalam banyak kasus tidak relevan.": sebenarnya, dalam konteks ini INT vs GUID, batas atas dari yang ditandatangani, 32-bit INTsepenuhnya tidak relevan mengingat bahwa batas atas dari yang ditandatangani , 64-bit BIGINTjauh melampaui hampir semua kegunaan (bahkan lebih jika Anda mulai penomoran pada batas bawah; dan hal yang sama berlaku untuk INT) dan masih setengah dari ukuran GUID (8 byte, bukan 16) dan berurutan.
Solomon Rutzky

Jawaban:

89

Ini telah ditanyakan di Stack Overflow di sini dan di sini .

Posting Jeff menjelaskan banyak tentang pro dan kontra menggunakan GUID.

GUID Pro

  • Unik di setiap tabel, setiap basis data, dan 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
  • Sebagian besar skenario replikasi memerlukan 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 ( where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • GUID yang dihasilkan harus sekuensial parsial untuk kinerja terbaik (misalnya, newsequentialid()pada SQL Server 2005+) dan untuk memungkinkan penggunaan indeks berkerumun

Jika Anda yakin tentang kinerja dan Anda tidak berencana untuk mereplikasi atau menggabungkan catatan, kemudian gunakan int, dan atur peningkatan otomatis ( seed identitas dalam SQL Server ).

CoderHawk
sumber
20
Kontra lain dari pendekatan GUID adalah bahwa Anda tidak dapat menggunakannya sebagai pengidentifikasi untuk pengguna akhir Anda. Apakah Anda benar-benar berharap pengguna Anda memberi tahu Anda di telepon bahwa mereka memiliki masalah dengan Pesanan "BAE7DF4-DDF-3RG-5TY3E3RF456AS10"? :)
Brann
3
Jika Anda tidak menggunakan pengurutan berurutan, dan kunci utama Anda berkerumun (defaul SQL Server) maka semua sisipan data Anda akan secara acak tersebar di seluruh tabel, yang menyebabkan fragmentasi besar-besaran data Anda. Itu dengan asumsi bahwa data biasanya akan dimasukkan dalam semacam urutan, seperti kronologis.
datagod
6
Sequential guids hanya berurutan sampai instance SQL dimulai kembali. Maka nilai pertama kemungkinan besar akan lebih rendah daripada yang sebelumnya karena cara nilai root dihasilkan, menyebabkan semua jenis masalah lagi.
mrdenny
20
@Rann Idealnya Anda tidak akan diberikan nilai PK Anda kepada pengguna akhir di tempat pertama. Saya tahu itu agak umum untuk dilakukan, dan itu adalah sesuatu yang saya sendiri telah lakukan di masa lalu sebelum saya belajar untuk tidak melakukannya. Tetapi karena itu tidak boleh dilakukan, alasan tertentu untuk lebih memilih INT daripada GUID bukanlah alasan yang valid.
Solomon Rutzky
2
@ChadKuehn Memilih UNIQUEIDENTIFIERlebih INTkarena INTmemiliki batas atas adalah penalaran agak miskin sejak berada tak terbatas, sementara cukup benar, bukan praktis manfaat. Anda dapat dengan mudah menggandakan kapasitas efektif INTdengan memulainya di batas bawah (-2,14 miliar) alih-alih pada 1. Atau, jika 4,3 miliar penuh tidak cukup, maka mulailah dengan BIGINTyang masih hanya 8 byte sebagai dibandingkan dengan 16 untuk GUID, dan ini seqeuential.
Solomon Rutzky
18

Jika Anda menyinkronkan data Anda dengan sumber eksternal, GUID persisten bisa jauh lebih baik. Contoh cepat tempat kami menggunakan GUID adalah alat yang dikirim ke pelanggan untuk merayapi jaringan mereka dan melakukan kelas penemuan otomatis tertentu, menyimpan catatan yang ditemukan, dan kemudian semua catatan pelanggan diintegrasikan ke dalam basis data pusat kembali pada akhir kita. Jika kita menggunakan integer, kita akan memiliki 7.398 "1", dan akan jauh lebih sulit untuk melacak "1" yang mana.

TML
sumber
3
GUID benar-benar bagus sebagai pengidentifikasi eksternal, dan saya akan menyimpan indeks yang tidak berkerumun sebagai "kunci eksternal" saya masih akan menyimpan int sebagai "kunci internal" yang merupakan dasar untuk indeks berkerumun dan hubungan kunci asing. Jika ada sesuatu yang melewati batas arsitektur (mis. Berkomunikasi dengan aplikasi lain) saya sangat menghargai memiliki sesuatu yang tidak dapat digabungkan.
Greg
15

Saya telah menggunakan pendekatan hibrida dengan sukses. Tabel berisi KEDUA idkolom integer kunci utama kenaikan-otomatis DAN guidkolom. The guiddapat digunakan sebagai diperlukan untuk global unik mengidentifikasi baris dan iddapat digunakan untuk query, menyortir dan identifikasi manusia baris.

bajingan
sumber
3
Nilai apa yang diberikan GUID jika idsudah cukup bagi manusia untuk mengidentifikasi satu baris?
Martin Smith
6
ID mengidentifikasi baris dalam tabel ini. GUID (setidaknya dalam teori) mengidentifikasi baris ini di mana saja di alam semesta yang diketahui. Dalam proyek saya, masing-masing ponsel Android memiliki salinan identik dari tabel pada database SQLite lokal. Baris dan GUID-nya masing-masing dihasilkan di Android. Kemudian, ketika Android disinkronkan ke database back-end, baris lokalnya ditulis ke tabel back-end tanpa takut bertentangan dengan baris yang dibuat dari ponsel Android lainnya.
rmirabelle
2
@ MartinSmith Saya telah menggunakan pendekatan ini sendiri dan bekerja dengan cukup baik. GUID hanyalah kunci alternatif, dengan indeks NonClustered, dan diteruskan dari aplikasi, tetapi hanya berada di tabel utama. Semua tabel terkait terkait melalui INTPK. Saya merasa aneh bahwa pendekatan ini tidak jauh lebih umum mengingat ini adalah yang terbaik dari kedua dunia. Sepertinya kebanyakan orang lebih memilih untuk menyelesaikan masalah dengan cara yang sangat absolut, tidak menyadari bahwa PK tidak perlu menjadi GUID agar aplikasi tetap menggunakan GUID untuk keunikan dan / atau portabilitas global.
Solomon Rutzky
1
@rabelabelle Saya telah memikirkan pendekatan ini dan ragu-ragu, tetapi jawaban Anda meyakinkan saya. Pada dasarnya saya berada dalam situasi di mana saya perlu memiliki pengidentifikasi unik untuk item pekerjaan (yang dapat masuk melalui jaringan dari mana saja), tetapi saya tidak ingin pulang-pergi ke database terlebih dahulu. GUID adalah solusi yang bagus untuk ini, tetapi saya membayangkan GABUNGAN akan menjadi jauh lebih lambat jika saya tidak memiliki kunci kunci berurutan.
easuter
1
@uteras saya setuju dengan tidak menambahkan bidang ID "hanya untuk kepentingan itu", seperti dalam tabel "jembatan" banyak-ke-banyak di mana PK harus merupakan gabungan dari dua FK yang terkait. Tapi ini bukan trade-off karena bidang ID tidak hanya untuk kepentingan itu. Mengizinkan sistem untuk bekerja secara efisien adalah cukup penting ;-). DAN, saya berpendapat bahwa dalam kasus Anda, karena GUID dibuat secara eksternal, itu tidak dijamin unik, meskipun secara pragmatis. Tetapi tanggung jawab untuk integritas data adalah alasan yang cukup untuk membuat GUID menjadi kunci alternatif dan ID menjadi PK dalam kasus Anda :)
Solomon Rutzky
1

Beberapa praktik terbaik di luar sana masih menyebutkan bahwa Anda harus menggunakan tipe data yang mengakomodasi dengan sedikit memori yang memungkinkan seluruh rangkaian nilai yang akan Anda gunakan. Misalnya, jika Anda menggunakannya untuk menyimpan jumlah pengusaha dalam bisnis kecil dan Anda tidak mungkin mencapai 100, maka tidak ada yang akan menyarankan menggunakan nilai bigint sementara int (bahkan smallint) akan melakukannya.

Tentu saja, kelemahannya seperti "Katakan tidak pada skalabilitas!"


Juga, saya tahu ini tidak sepenuhnya terkait, tetapi ada faktor lain tentang ini. Ketika tidak berlebihan, saya biasanya mencoba untuk merekomendasikan untuk menggunakan kunci primer yang tidak diautogenisasi, jika itu masuk akal. Misalnya, jika Anda menyimpan informasi pengemudi, jangan repot-repot membuat kolom autogenerated baru untuk "ID", cukup gunakan nomor lisensi.

Saya tahu ini terdengar sangat jelas, tetapi saya melihat hal itu cukup sering dilupakan.

Untuk konteks: bagian dari jawaban ini dialamatkan dari pendekatan teoretis data, di mana Anda ingin PK Anda menjadi pengidentifikasi data unik untuk catatan. Sebagian besar waktu kita buat itu ketika sudah ada, maka jawaban sebelumnya.

Namun, sangat jarang bahwa Anda dapat memiliki kontrol ketat atas titik data ini, dan karenanya, Anda mungkin perlu melakukan koreksi atau penyesuaian. Anda tidak dapat melakukannya dengan kunci primer (yah, Anda bisa, tetapi itu bisa menyebalkan).

Terima kasih @ VahiD untuk klarifikasi.

Alfa
sumber
menggunakan kunci utama yang bermakna tidak direkomendasikan sama sekali, pertimbangkan skenario di bawah ini, seseorang memasukkan nomor lisensi yang salah dan Anda telah menggunakan id ini dalam 3-4 tabel sebagai kunci asing, bagaimana Anda memperbaiki kesalahan ini? hanya mengedit nomor lisensi tidak cukup dalam hal ini.
VahiD
1
Lucu: Saya membaca komentar Anda dan saya berpikir "ya, tentu saja", lalu kembali untuk membaca jawaban saya dan berpikir "apakah saya mengatakan itu"? Lucu bagaimana hal berubah dalam beberapa tahun. Saya mungkin berasal dari latar belakang yang lebih teoretis, tetapi kecuali Anda memiliki kontrol ketat terhadapnya (jarang) itu tidak memberikan banyak manfaat. Saya akan memperbarui jawabannya.
Alpha
upvote untuk pengembangan di tahun-tahun :)
VahiD
1

Menggunakan ID kenaikan otomatis dapat membocorkan informasi tentang aktivitas bisnis Anda. Jika Anda menjalankan toko dan menggunakan order_iduntuk mengidentifikasi pembelian secara publik, maka siapa pun dapat mengetahui jumlah penjualan bulanan Anda dengan aritmatika sederhana.

golopot
sumber
0

Hal lain dengan cara GUID dihasilkan. mrdenny dengan tepat menunjukkan bahwa walaupun newitialentialid () sedang digunakan, memulai kembali instans menyebabkan nilai baru dimulai dengan "lubang" yang tertinggal dalam pemrosesan sebelumnya. Hal lain yang mempengaruhi GUID "berurutan" adalah kartu jaringan. Jika saya ingat dengan benar, UID NIC digunakan sebagai bagian dari algoritma GUID. Jika NIC diganti, tidak ada jaminan bahwa UID akan menjadi nilai yang lebih tinggi untuk mempertahankan aspek hal-hal yang berurutan. Saya juga tidak yakin bagaimana beberapa NIC dapat mempengaruhi penetapan nilai menggunakan algoritma.

Hanya sebuah pemikiran dan saya harap saya mengingat dengan benar. Semoga hari mu menyenangkan!

bobo8734
sumber
2
Selamat datang di Administrator Database, bobo8734. Bisakah Anda menemukan beberapa sumber untuk komentar ini? Jika Anda tidak yakin dengan mereka, mungkin mereka akan lebih baik disajikan sebagai komentar (ketika Anda memiliki perwakilan untuk itu) daripada jawaban mandiri.
LowlyDBA
-6

Gunakan keduanya

Gunakan int / Bigint untuk Primary Key karena mudah dipelihara dan digunakan sebagai hubungan kunci asing.

Tetapi ikat kolom ke GUID sehingga setiap baris juga memiliki kolom unik

Abdul Hannan Ijaz
sumber
2
Menjelaskan alasan Anda di balik saran ini tidak akan menyakiti siapa pun, saya yakin.
Andriy M
GUID panjangnya 36 karakter akan sulit dibaca jika Anda mencari kasus tertentu ..
Abdul Hannan Ijaz
1
Baiklah, tapi itu tidak menjelaskan mengapa OP harus menggunakan keduanya intdan guid, seperti yang Anda sarankan dalam jawaban Anda. Dan selain itu, saya tidak berbicara tentang menjelaskan saran Anda hanya kepada saya - maksud saya adalah Anda mungkin ingin memperbarui jawaban Anda . Ngomong-ngomong, apakah Anda sadar bahwa penjawab lain telah menyarankan hal yang sama (kurang lebih) dengan Anda ?
Andriy M
Yup saya maksudkan hal yang sama .. keren BTW :)
Abdul Hannan Ijaz