Bagaimana Anda menyukai kunci utama Anda? [Tutup]

88

Dalam diskusi yang cukup bersemangat di tim saya, saya dibuat untuk memikirkan apa yang disukai kebanyakan orang sebagai kunci utama. Kami memiliki kelompok berikut-

  1. Int / BigInt yang autoincrementnya merupakan primary key yang cukup baik.
  2. Setidaknya harus ada 3 kolom yang membentuk kunci utama.
  3. Id, GUID, dan pengidentifikasi baris yang dapat dibaca manusia semuanya harus diperlakukan secara berbeda.

Apa pendekatan terbaik untuk PK? Akan luar biasa jika Anda bisa membenarkan pendapat Anda. Apakah ada pendekatan yang lebih baik dari yang di atas?

EDIT: Ada yang memiliki sampel / algoritma sederhana untuk menghasilkan pengenal yang dapat dibaca manusia untuk baris yang berskala dengan baik?

Perpetualcoder
sumber
1
Karena ini subjektif, seharusnya wiki komunitas
John Sheehan
2
"Harus ada setidaknya 3 kolom yang membentuk kunci utama"? Apa artinya ini? Bisakah Anda memberikan definisi lebih lanjut? Atau apakah ini bagian dari # 3?
S. Lott
@ S.Lott PK(NEWID(),NEWID(),NEWID());-)
@pst: Mengapa ini menjadi persyaratan? Mengapa harus ada tiga kolom dalam PK? Mengapa satu satu atau empat?
S. Lott
Saya bisa melihat PK tiga kolom terlihat seperti ... LocalID (Auto increment int), GlobalID (GUID), ForeignId (foreign key seperti RolesType), dll. LocalID + ForiegnId bisa menjadi kombinasi kunci gabungan. Panduan ini digunakan untuk situs web / layanan lain. Secara pribadi saya tidak akan melakukan ini, saya hanya akan menggunakan Guid + ForiegnId.
Jerad

Jawaban:

77

Jika Anda akan melakukan sinkronisasi antara database dengan aplikasi yang terkadang terhubung, Anda harus menggunakan GUID untuk kunci utama Anda. Agak merepotkan untuk debugging, jadi selain kasus itu saya cenderung tetap berpegang pada ints autoincrement itu.

Autoincrement int harus menjadi default Anda, dan tidak menggunakannya harus dibenarkan.

Bramha Ghosh
sumber
3
GUID tidak diperlukan, cukup ubah langkah ke 10 atau 20 atau berapa pun server yang mungkin perlu Anda sinkronkan di masa mendatang.
Robert C. Barth
44
Setidaknya 90% dari waktu, GUID tidak diperlukan dan membuang-buang ruang.
Jonathan Leffler
8
Saya benar-benar merasa GUID terlalu berlebihan. Tidak pernah merasa perlu memiliki GUID sebagai kunci utama saya.
Cyril Gupta
7
Atau, daripada membuang-buang ruang dan mempertaruhkan benturan dengan GUID, buat kunci gabungan dari kunci utama asli dan pengenal kecil, dengan pengenal kecil berbeda untuk setiap sumber sinkronisasi.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
5
Toko tempat saya bekerja menggunakan GUID untuk segala hal, bahkan ketika pengenal publik tersedia, seperti kode negara atau bahasa ISO. Dan bahkan ketika boolean atau CHAR(1)sudah cukup, seperti untuk sex. Tak perlu dikatakan, itu adalah mimpi buruk untuk dikerjakan.
Lumi
56

Saya tidak melihat jawaban yang menunjukkan (apa yang saya anggap) poin yang sangat mendasar - yaitu, kunci utama adalah yang menjamin bahwa Anda tidak akan mendapatkan dua entri dalam tabel untuk entitas dunia nyata yang sama (seperti dimodelkan dalam database). Pengamatan ini membantu menetapkan apa yang baik dan apa pilihan buruk untuk kunci utama.

Misalnya, dalam tabel nama dan kode negara bagian (AS), nama atau kode tersebut dapat menjadi kunci utama - keduanya merupakan dua kunci kandidat yang berbeda, dan salah satunya (biasanya kode yang lebih pendek) dipilih sebagai kunci utama. Dalam teori dependensi fungsional (dan menggabungkan dependensi - 1NF hingga 5NF - kunci kandidatlah yang lebih penting daripada kunci primer.

Sebagai contoh tandingan, nama manusia umumnya membuat pilihan kunci primer yang buruk. Ada banyak orang yang menggunakan nama "John Smith" atau nama lain yang serupa; bahkan dengan mempertimbangkan nama tengah (ingat: tidak semua orang memilikinya - misalnya, saya tidak), ada banyak ruang untuk duplikasi. Akibatnya, orang tidak menggunakan nama sebagai kunci utama. Mereka menemukan kunci buatan seperti Nomor Jaminan Sosial (SSN) atau Nomor Karyawan dan menggunakannya untuk menunjuk individu.

Kunci utama yang ideal adalah yang pendek, unik, mudah diingat, dan alami. Dari ciri-ciri ini, keunikan adalah wajib; sisanya harus fleksibel karena kendala data dunia nyata.

Oleh karena itu, ketika menentukan kunci utama dari tabel tertentu, Anda harus melihat apa yang diwakili tabel itu. Kumpulan atau kumpulan nilai kolom apa dalam tabel yang secara unik mengidentifikasi setiap baris dalam tabel? Itu adalah kunci kandidat. Sekarang, jika setiap kunci kandidat terdiri dari 4 atau 5 kolom, maka Anda mungkin memutuskan bahwa kunci-kunci tersebut terlalu kaku untuk membuat kunci utama yang baik (terutama karena alasan singkatnya). Dalam keadaan seperti itu, Anda mungkin memperkenalkan kunci pengganti - angka yang dibuat secara artifisial. Sangat sering (tetapi tidak selalu) integer 32-bit sederhana cukup untuk kunci pengganti. Anda kemudian menetapkan kunci pengganti ini sebagai kunci utama.

Namun, Anda masih harus memastikan bahwa kunci kandidat lainnya (untuk kunci pengganti juga merupakan kunci kandidat, serta kunci utama yang dipilih) semuanya dipertahankan sebagai pengenal unik - biasanya dengan menempatkan batasan unik pada kumpulan kolom tersebut.

Kadang-kadang, orang merasa sulit untuk mengidentifikasi apa yang membuat baris unik, tetapi harus ada sesuatu untuk dilakukan, karena hanya mengulangi sepotong informasi tidak membuatnya menjadi lebih benar. Dan jika Anda tidak berhati-hati dan mendapatkan dua (atau lebih) baris yang dimaksudkan untuk menyimpan informasi yang sama, dan Anda kemudian perlu memperbarui informasi, ada bahaya (terutama jika Anda menggunakan kursor) bahwa Anda hanya akan memperbarui satu baris daripada setiap baris, sehingga baris tidak sinkron dan tidak ada yang tahu baris mana yang berisi informasi yang benar.

Ini adalah pandangan garis yang cukup keras, dalam beberapa hal.

Saya tidak memiliki masalah khusus dengan menggunakan GUID saat dibutuhkan, tetapi cenderung besar (seperti pada 16-64 byte), dan terlalu sering digunakan. Seringkali nilai 4-byte yang sangat baik sudah cukup. Menggunakan GUID di mana nilai 4-byte akan cukup menghabiskan ruang disk, dan bahkan memperlambat akses yang diindeks ke data karena ada lebih sedikit nilai per halaman indeks, sehingga indeks akan menjadi lebih dalam dan lebih banyak halaman harus dibaca untuk sampai ke informasi.

Jonathan Leffler
sumber
10
Mengenai sampel Anda dengan nama negara bagian AS, saya lebih suka kunci pengganti terpisah, hanya karena kodenya berada di luar kendali Anda. Jika mereka harus berubah karena alasan apa pun Anda mendapatkan masalah.
Dirk Vollmar
1
(lanjutan) Misalnya, Jerman mengganti sistem kode pos 4-digit dengan sistem 5-digit pada tahun 1990-an setelah penyatuan ulang.
Dirk Vollmar
@divo: Saya adalah pendukung kuat kunci buatan / pengganti, tetapi bahkan saya tidak melihat perubahan kode pos 4 digit menjadi 5 digit sebagai contoh yang baik. Kode pos umumnya tidak digunakan sebagai kunci untuk apa pun. (Kapan terakhir kali Anda harus menanyakan tabel Kode Pos untuk mengetahui sesuatu tentang kode itu? Tidak, ini hampir secara eksklusif digunakan sebagai bagian dari alamat tanpa dirujuk di tabel lain. Saya akan mengatakan saran Anda hampir setara dengan menggunakan kunci pengganti untuk alamat itu sendiri.)
ErikE
@Emtucifor: Ya, mungkin ZIP bukanlah contoh yang sangat praktis, tetapi maksud saya adalah jika bagian dari kunci pengganti Anda berada di luar kendali Anda dan berubah karena alasan apa pun, Anda berada dalam masalah. Pikirkan seseorang yang membuat skema nomor jaminan sosial baru, skema ISSN baru atau - mungkin lebih realistis - perusahaan yang memutuskan untuk membuat sistem id produk baru setelah penggabungan, menetapkan nomor karyawan baru kepada karyawan mereka untuk menyesuaikan pertumbuhan mereka, dll. semua hanya contoh fiksi, tetapi, seperti contoh saya sebelumnya dengan ZIP menunjukkan, terkadang sistem yang mapan mungkin berubah.
Dirk Vollmar
2
Poin pertama Anda benar. Ada nama untuk kendala ini. Ini disebut "integritas entitas". EI mensyaratkan bahwa setiap entitas memiliki identitas yang unik. Kunci utama sering memenuhi persyaratan ini, kecuali jika nomor otomatis digunakan. Dengan autonumber, Anda bisa mendapatkan dua baris yang identik, kecuali autonumber. Ini biasanya melanggar integritas entitas.
Walter Mitty
26

Ini hanya masalah agama karena orang mencari jawaban yang benar secara universal. Fakta bahwa tim Anda dan rangkaian SO ini menunjukkan begitu banyak ketidaksepakatan seharusnya menjadi petunjuk bahwa ada alasan bagus untuk menggunakan semua solusi yang Anda gambarkan, dalam keadaan yang berbeda.

  • Kunci pengganti berguna jika tidak ada atribut atau kumpulan atribut lain dalam tabel yang cocok untuk mengidentifikasi baris secara unik.
  • Kunci alami lebih disukai, jika memungkinkan, untuk membuat tabel lebih mudah dibaca manusia. Kunci natural juga memungkinkan kunci asing dalam tabel dependen untuk memuat nilai riil sebagai pengganti id pengganti. Misalnya ketika Anda perlu menyimpan state(CA, TX, NY) Anda mungkin juga menggunakan char(2)kunci alami daripada int.
  • Gunakan kunci utama majemuk jika sesuai. Jangan menambahkan idkunci pengganti " " jika ada kunci gabungan yang sangat baik (ini terutama berlaku dalam tabel banyak-ke-banyak). Amanat untuk kunci tiga kolom di setiap tabel benar-benar tidak masuk akal.
  • GUID adalah solusi saat Anda perlu mempertahankan keunikan di beberapa situs. Mereka juga berguna jika Anda membutuhkan nilai di kunci utama agar unik, tetapi tidak berurutan atau berurutan.
  • INT vs. BIGINT: tidak umum bahwa tabel memerlukan rentang 64-bit untuk kunci utama, tetapi dengan ketersediaan perangkat keras 64-bit yang meningkat, ini seharusnya tidak menjadi beban, dan memberikan lebih banyak jaminan bahwa Anda tidak akan meluap. INT tentu saja lebih kecil, jadi jika ruangnya mahal, itu bisa memberi sedikit keuntungan.
Bill Karwin
sumber
8
Saya tidak setuju sebanyak mungkin yang bisa dilakukan seseorang. Kunci alami itu mengerikan. Bagaimana jika seseorang ingin mengubah datanya? Oh, kamu tidak bisa. Menulis gabungan pada kunci alami komposit sangat merepotkan. Membawa kunci komposit itu ke semua tabel terkait Anda adalah pemborosan.
Robert C. Barth
2
@Robert: baca tentang "ON UPDATE CASCADE". Tapi saya mengerti apa yang Anda katakan, dan saya setuju yang terbaik adalah menggunakan kunci pengganti sebagian besar waktu, karena atribut dapat berubah dan menjadi tidak unik.
Bill Karwin
2
Kunci utama harus tidak dapat diubah. Pembaruan kaskade hanyalah peretasan jelek untuk keputusan desain yang buruk dalam kasus ini. Kunci alami TIDAK PERNAH disukai. Sama dengan kunci komposit, yang menyebarkan dirinya seperti wabah. Siapapun dengan lebih dari 3 bulan pengalaman pengembangan database akan mengetahui hal ini.
FDCastel
7
@FD: Saya tidak setuju dengan pernyataan tegas Anda, dan saya telah mengembangkan dengan database SQL sejak 1992. Tapi yang pasti benar bahwa kunci pengganti paling baik untuk tetap tidak berubah.
Bill Karwin
20

Saya suka blog The Database Programmer sebagai sumber info semacam ini.

3 kolom untuk kunci utama? Saya akan mengatakan bahwa kolom harus memiliki batasan unik yang sesuai sebagai permintaan aturan bisnis, tetapi saya masih memiliki kunci pengganti yang terpisah. Kunci majemuk berarti logika bisnis masuk ke dalam kunci. Jika logika berubah, seluruh skema Anda kacau.

duffymo
sumber
2
Mereka mengubah tautan mereka, berikut adalah bookmark yang diperbarui: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein
Baru saja mewarisi proyek seperti ini. Dan hal pertama yang ingin mereka lakukan adalah meledakkan skema tersebut. Kunci Pengganti FTW. Logika Bisnis di DB FTL Anda.
Jason
15

Saya suka milik saya yang unik.

Andrew bukan Orang Suci
sumber
11

Sedikit keluar dari topik, tapi saya merasa harus ikut campur dengan ...

Jika kunci utama Anda adalah GUID, jangan menjadikannya indeks berkerumun . Karena GUID tidak berurutan, data akan diatur ulang pada disk selama hampir setiap penyisipan. (Yuck.) Jika menggunakan GUID sebagai kunci utama, mereka harus indeks nonclustered.

Portman
sumber
1
Poin yang sangat bagus - seseorang perlu membedakan antara konsep LOGIS kunci primer (mungkin valid untuk menggunakan GUID untuk itu, terutama jika replikasi terlibat), dan konsep FISIK dari kunci pengelompokan - yang seharusnya TIDAK PERNAH menjadi GUID sejak itu menyebabkan fragmentasi indeks yang berlebihan
marc_s
3
Ini sebenarnya tidak akurat. Data akan disisipkan secara berurutan, yang mengingat sifat acak GUID bisa berakhir di mana saja di seluruh tabel. Jika tidak ada ruang, pemisahan halaman akan terjadi, tetapi tentu saja tidak "mengatur ulang pada disk selama setiap penyisipan" bahkan tidak menutup.
Ralph Shillington
@Ralph, Anda benar, tidak SETIAP penyisipan, tetapi cukup untuk menyebabkan kinerja 20x hit. sql-server-performance.com/articles/per/…
Portman
Fungsi SQL Server newsequentialid () memecahkan masalah fragmentasi indeks dengan GUID (meskipun 24 byte masih sedikit berlebihan jika Anda tidak benar-benar membutuhkan keunikan global). Lihat msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE
10

Saya selalu pergi dengan kunci pengganti. Kunci pengganti (biasanya kolom identitas, peningkatan otomatis, atau GUID) adalah kunci yang tidak ada dalam datanya sendiri. Kunci alami, di sisi lain, adalah kunci yang, dengan sendirinya, secara unik mengidentifikasi barisnya. Sejauh yang bisa saya ceritakan dalam hidup, hampir tidak ada kunci alami yang nyata . Bahkan hal-hal seperti SSN di Amerika Serikat bukanlah kunci alami. Kunci utama komposit menunggu bencana untuk terjadi. Anda tidak dapat mengedit data itu (yang merupakan kelemahan utama dari kunci alami apa pun, komposit atau bukan), tetapi yang lebih buruk adalah dengan kunci komposit, sekarang Anda harus mengabadikan data kunci tersebut ke dalam setiap tabel terkait. Sungguh pemborosan yang besar.

Sekarang, untuk pemilihan kunci pengganti, saya tetap menggunakan kolom identitas (saya kebanyakan bekerja di MS SQL Server). GUID terlalu besar dan Microsoft menyarankan untuk tidak menggunakannya sebagai PK. Jika Anda memiliki beberapa server, yang perlu Anda lakukan hanyalah menambah 10 atau 20 atau berapapun yang menurut Anda jumlah maksimum server yang perlu Anda sinkronkan / luaskan, dan cukup masukkan benih untuk setiap tabel di setiap server berikutnya , dan Anda tidak akan pernah mengalami benturan data.

Tentu saja, karena kenaikan tersebut, saya membuat kolom identitas menjadi BigInt (atau dikenal sebagai [64 bit] panjang).

Melakukan sedikit matematika, bahkan jika Anda membuat kenaikan 100, Anda masih dapat memiliki 92.233.720.368.547.758 (> 92 kuadriliun) baris di tabel Anda.

Robert C. Barth
sumber
9

Menurut saya penggunaan kata "Primer", dalam frase "Primer" Kunci dalam arti yang sebenarnya, menyesatkan.

Pertama, gunakan definisi bahwa "kunci" adalah atribut atau kumpulan atribut yang harus unik di dalam tabel,

Kemudian, memiliki kunci apa pun memiliki beberapa tujuan yang sering kali tidak konsisten.

  1. Untuk digunakan sebagai kondisi gabungan ke satu atau banyak rekaman dalam tabel anak yang memiliki hubungan dengan tabel induk ini. (Mendefinisikan Kunci Asing secara eksplisit atau implisit dalam tabel anak tersebut)
  2. (terkait) Memastikan bahwa catatan anak harus memiliki catatan induk di tab induk; e (Tabel anak FK harus ada sebagai Kunci di tabel induk)
  3. Untuk meningkatkan kinerja kueri yang perlu dengan cepat menemukan rekaman / baris tertentu dalam tabel.

  4. Untuk memastikan konsistensi data dengan mencegah duplikat baris yang mewakili entitas logis yang sama agar tidak dimasukkan ke dalam tabel. (Ini sering disebut kunci "alami", dan harus terdiri dari atribut tabel (entitas) yang relatif tidak berubah.)

Jelas, kunci non-bermakna dan non-alami apa pun (seperti GUID atau bilangan bulat yang dihasilkan secara otomatis sama sekali tidak dapat memenuhi # 4.

Tetapi seringkali, dengan banyak tabel (paling), kunci alami yang dapat memberikan # 4 akan sering terdiri dari beberapa atribut dan terlalu lebar, atau sangat lebar sehingga menggunakannya untuk tujuan # 1, # 2, atau # 3 akan menyebabkan tidak dapat diterima konsekuensi kinerja

Jawabannya sederhana. Gunakan keduanya. Gunakan kunci integral penghasil otomatis sederhana untuk semua Gabungan dan FK di tabel anak lainnya, tetapi pastikan bahwa setiap tabel yang memerlukan konsistensi data (sangat sedikit tabel yang tidak) memiliki kunci unik alami alternatif yang akan mencegah penyisipan baris data yang tidak konsisten. .. Plus, jika Anda selalu memiliki keduanya, maka semua keberatan terhadap penggunaan kunci alami (bagaimana jika berubah? Saya harus mengubah setiap tempat yang dirujuk sebagai FK) menjadi diperdebatkan, karena Anda tidak menggunakannya untuk itu. .. Anda hanya menggunakannya dalam satu tabel yang merupakan PK, untuk menghindari data duplikat yang tidak konsisten ...

Untuk GUID, berhati-hatilah saat menggunakannya, karena menggunakan panduan dalam indeks dapat menghambat fragmentasi indeks. Algoritme paling umum yang digunakan untuk membuatnya menempatkan bagian "acak" dari panduan di posisi bit yang paling signifikan ... Ini meningkatkan persyaratan untuk defragmentasi indeks reguler / Pengindeksan ulang saat baris baru ditambahkan.

Charles Bretana
sumber
Fungsi SQL Server newsequentialid () memecahkan masalah fragmentasi indeks GUID (meskipun 24 byte masih sedikit berlebihan jika Anda tidak benar-benar membutuhkan keunikan global). Lihat msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE
Ups, maksud saya 16 byte.
ErikE
8

Satu hal yang tidak boleh Anda lakukan adalah menggunakan kunci pintar. Itu adalah kunci di mana informasi tentang catatan dikodekan di dalam kunci itu sendiri, dan pada akhirnya akan menggigit Anda.

Saya bekerja di satu tempat, di mana kunci utama adalah ID akun, yang merupakan kombinasi huruf dan angka. Saya tidak ingat secara spesifik, tetapi, misalnya, akun yang memiliki jenis tertentu, akan berada dalam kisaran 600, dan jenis lain, dimulai dengan 400. Itu bagus, sampai pelanggan itu memutuskan untuk meminta keduanya jenis pekerjaan. Atau mengubah jenis pekerjaan yang mereka lakukan.

Tempat lain, menggunakan lokasi di pohon sebagai kunci utama untuk rekaman. Jadi akan ada catatan seperti berikut.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Tentu saja, hal pertama yang diinginkan pelanggan adalah cara memindahkan barang yang ada di pohon. Seluruh rangkaian perangkat lunak mati sebelum itu terjadi.

Tolong, tolong, tolong, jika Anda menulis kode yang harus saya pertahankan, tolong jangan gunakan kunci pintar!

thursdaysgeek
sumber
Saya setuju dengan sepenuh hati. Smartkeys = bodoh.
Robert C. Barth
2
Ini tidak berarti kunci alami itu bodoh. Tapi poin yang bagus.
4

Saya penggemar auto-increment sebagai kunci utama. Saya tahu jauh di lubuk hati saya bahwa ini adalah penolakan, tetapi itu membuatnya sangat mudah untuk mengurutkan data ketika ditambahkan (ORDER BY ID DESC, f'r contoh).

3 kolom terdengar sangat kasar untuk diurai secara manusiawi.

Dan itulah trade-off - seberapa besar kemampuan relasional yang Anda butuhkan, versus membuat TABEL INI DI SINI dapat dipahami oleh manusia yang menginterogasinya (versus prosedur tersimpan atau antarmuka terprogram).

auto-increment adalah untuk kita manusia. :-(

Michael Paulukonis
sumber
4

Umumnya tergantung.

Secara pribadi, saya suka ints autoincrement.

Namun, satu hal yang dapat saya sampaikan kepada Anda adalah jangan pernah mempercayai data dari sumber lain sebagai kunci Anda. Aku bersumpah, setiap kali aku melakukannya, itu selalu menggigitku. Nah, tidak pernah lagi!

BoltBait
sumber
3

Harus ada minimal 3 kolom yang membentuk kunci utama.

Saya tidak mengerti ini.

Apakah Anda berbicara tentang "kunci alami", misalnya "nama dan tanggal lahir"? Kunci alami mungkin ideal jika ada, tetapi sebagian besar kandidat untuk kunci alami tidak unik (beberapa orang dengan nama yang sama) atau tidak konstan (seseorang dapat mengubah namanya).

Int / BigInt yang autoincrementnya merupakan primary key yang cukup baik.

Saya lebih suka Guid. Masalah potensial dengan autoincrement adalah bahwa nilai (misalnya "id pesanan") ditetapkan oleh contoh database (misalnya oleh "database penjualan") ... yang tidak akan berfungsi sepenuhnya (sebagai gantinya Anda mulai membutuhkan kunci gabungan) jika Anda perlu menggabungkan data yang dibuat oleh lebih dari satu contoh database (misalnya dari beberapa kantor penjualan masing-masing dengan database mereka sendiri).

ChrisW
sumber
Kunci utama harus unik, tetapi tidak harus konstan. Karenanya kunci asing dideklarasikan dengan "ON UPDATE CASCADE". Tetapi membuat asumsi bahwa kunci primer konstan membantu menyederhanakan banyak aplikasi. Ini adalah salah satu manfaat kunci pengganti.
Bill Karwin
3

RE GUID

Hati-hati jika ini akan menjadi database yang benar-benar SANGAT SANGAT SANGAT BESAR, banyak beban, dan akses cepat.

Pada pekerjaan terakhir saya, di mana kami memiliki database 100 hingga 500 juta catatan, orang-orang database kami sangat menentang GUID, dan untuk angka desimal yang berukuran tepat. Mereka merasa bahwa (di bawah Oracle) perbedaan ukuran dalam penyimpanan internal untuk string Guid - vs- nilai desimal akan membuat perbedaan yang sangat mencolok dalam pencarian. (Kunci yang lebih besar = pohon yang lebih dalam untuk dilintasi)

Sifat acak GUID juga mengurangi faktor pengisian untuk halaman indeks secara signifikan - ini secara dramatis meningkatkan robekan dan I / O disk.

John Chenault
sumber
"Mengurangi faktor pengisian"? Tidak yakin apa artinya Faktor isian adalah kesepakatan satu kesempatan, yang didefinisikan sebagai persentase ruang kosong yang diminta pada indeks tingkat daun pada saat indeks dibuat. Nilai GUID berdasarkan distribusi sifat acaknya di seluruh luas tingkat daun pada sisipan ke dalam ruang kosong yang disediakan faktor pengisi.
Ralph Shillington
1
Sejak kapan GUID menjadi string? GUID harus disimpan secara internal sebagai 16 byte oleh DBMS yang terhormat. Menyimpan sebagai 32 byte dalam representasi hex tidak masuk akal! (atau 36 dengan tanda hubung, atau 38 dengan tanda kurung kurawal)
ErikE
2

Kolom kenaikan otomatis. Saya dapat membuat kode saya berfungsi mulus dengan SQL Server atau Oracle, satu menggunakan identitas yang lain menggunakan urutan melalui DAL saya, dan saya tidak bisa lebih bahagia. Saya setuju, terkadang GUID diperlukan jika Anda melakukan replikasi atau mengirim data untuk menerimanya nanti setelah pemrosesan.

Otávio Décio
sumber
2

Saya selalu menggunakan kunci pengganti - integer autoincrementing yang disebut 'id'. Saya dapat melihat banyak alasan untuk melakukan ini bahkan ketika opsi lain sudah jelas:

  • Konsistensi
  • Data independen (unik, tidak dihancurkan oleh perubahan format)
  • Dapat dibaca manusia

... dan tidak ada alasan yang masuk akal untuk tidak:

  • Ambiguitas dalam gabungan? - Tabel Aliasing adalah praktik yang lebih baik, IMHO
  • Tabel yang optimal? - Menghapus satu byte per entri adalah pengoptimalan prematur, IMHO
  • Keputusan per meja? - Tidak lagi konsisten
  • Masalah penskalaan? - Eh? Mengapa?
  • Struktur data hierarki? - Itu denormalisasi, topik agama lain. Cukuplah untuk mengatakan bahwa saya adalah penggemar dalam beberapa situasi secara teori, tetapi tidak pernah dalam praktiknya :)

alasan yang masuk akal untuk melawan yang belum saya pikirkan atau temukan selalu disambut ...

jTresidder
sumber
1

Ini adalah klasik "tergantung". Tidak ada jawaban yang tepat untuk setiap proyek. Saya suka hal yang berbeda untuk situasi yang berbeda. Itu tergantung pada apakah saya menggunakan ORM dan apa yang didukungnya. Itu tergantung pada arsitektur keseluruhan (terdistribusi atau tidak, dll). Pilih saja satu yang menurut Anda akan berhasil dan lanjutkan ke perdebatan tentang tab dan spasi.

John Sheehan
sumber
Dia masih ingin tahu BAGAIMANA itu tergantung; hanya dengan kesadaran ini seseorang dapat mempercayai dirinya sendiri untuk memilih ...
Nicholas Leonard
1

Saya cenderung menggunakan opsi # 1 atau # 3 tergantung pada ukuran, jumlah orang yang terhubung, dan apakah itu situasi server database ganda atau tidak.

Opsi # 2 tidak masuk akal bagi saya. Jika salah satu dari ketiganya tidak cukup untuk mengidentifikasi rekaman unik, maka dimungkinkan (tanpa melalui intrik ekstra) dua memiliki dua rekaman muncul dengan nilai yang sama di ketiga kolom. Jika Anda ingin menerapkan keunikan pada kombinasi ketiganya, cukup tambahkan indeks untuk ketiganya.

BIBD
sumber
1

Saya hanya menggunakan int auto-increment atau GUID. 99% dari waktu saya menggunakan int auto-increment. Itu hanya apa yang saya diajarkan untuk digunakan ketika saya pertama kali belajar tentang database dan tidak pernah menemukan alasan untuk tidak menggunakannya (meskipun saya tahu alasan mengapa GUID akan lebih baik).

Saya suka auto increment int karena membantu keterbacaan. Misalnya, saya dapat mengatakan "lihat catatan 129383" dan cukup mudah bagi seseorang untuk masuk dan menemukannya. Dengan GUID yang hampir tidak mungkin dilakukan.

dtc
sumber
2
Mengapa kamu mengatakan itu? Tampaknya banyak orang menggunakan bilangan bulat kenaikan otomatis. Tidak bisa seburuk itu jika itu bekerja dan bekerja dengan baik untuk apa yang Anda butuhkan.
dtc
1

Melewati jawaban definisi dasar, apa yang merupakan kunci utama yang baik sebagian besar diserahkan kepada agama dan argumen ruang istirahat. Jika Anda memiliki sesuatu yang, dan akan selalu, memetakan secara unik ke setiap baris, maka itu akan berfungsi dengan baik sebagai kunci utama. Setelah itu, ada pertimbangan lain:

  • Apakah definisi kunci primer tidak terlalu rumit? Apakah ini menghindari pengenalan kerumitan yang tidak perlu demi mengikuti "praktik terbaik"?
  • Apakah ada kunci primer yang lebih baik yang membutuhkan lebih sedikit overhead untuk ditangani database (yaitu INTEGER vs. VARCHAR, dll)?
  • Apakah saya BENAR-BENAR yakin bahwa keunikan dan ketetapan yang berbeda dari kunci utama saya tidak akan berubah?

Yang terakhir ini mungkin yang menarik kebanyakan orang untuk menggunakan hal-hal seperti GUID atau kolom integer yang bertambah sendiri, karena mengandalkan hal-hal seperti alamat, nomor telepon, nama depan / belakang, dll, jangan dipotong. Satu-satunya perbedaan tentang orang yang dapat saya pikirkan adalah SSN, tetapi kemudian saya bahkan tidak 100% yakin tentang mereka yang tetap unik selamanya.

Semoga ini membantu menambah kejelasan ...

Ed Carrel
sumber
Ada beberapa kasus historis di mana SSN tidak unik.
Bill Karwin
1

Cara saya mendekati kunci primer (dan saya rasa adalah yang terbaik) adalah dengan menghindari pendekatan "default". Ini berarti alih-alih hanya menampar pada bilangan bulat yang bertambah otomatis dan menyebutnya sehari, saya melihat masalah dan berkata "apakah ada kolom atau kelompok kolom yang akan selalu unik dan tidak akan berubah?" Jika jawabannya ya maka saya mengambil pendekatan itu.

Andrew G. Johnson
sumber
Apakah itu berarti Anda 'menghindari auto-incrementing integers kapan pun Anda bisa'? Pemahaman saya adalah bahwa pakar industri menganggap kinerja terbaik pada database skala besar berasal dari PK kolom tunggal dengan tanda tangan minimal, terindeks, dan inkremental.
Hardryv
1
Saya selalu berpikir para ahli menggunakan alat terbaik untuk pekerjaan itu
Andrew G. Johnson
1

Hampir selalu bilangan bulat.

Mereka memiliki alasan bagus lainnya selain lebih kecil / lebih cepat untuk diproses. Mana yang ingin Anda tulis - "404040" atau "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"?

pengguna42092
sumber
Yang terakhir mungkin berupa bilangan bulat, dengan tanda hubung ditambahkan dan di basis 16. Tapi ya, 404040 lebih cepat untuk diproses daripada GUID yang panjang. Kemudian lagi, 0 bahkan lebih cepat diproses karena tidak memerlukan sedikit pun data!
strager
1

Hanya sedikit relevan, tetapi satu hal yang saya mulai lakukan baru-baru ini ketika saya memiliki tabel klasifikasi kecil (pada dasarnya yang akan mewakili ENUM dalam kode) adalah bahwa saya akan membuat kunci utama menjadi char (3) atau char (4). Kemudian saya membuat kunci utama tersebut mewakili nilai pencarian.

Misalnya, saya memiliki sistem kutipan untuk Agen Penjualan internal kita. Kami memiliki "Kategori Biaya" yang setiap item baris kutipan ditetapkan salah satu ... Jadi saya memiliki tabel pencarian jenis yang disebut 'tCostCategories', dengan kunci utama adalah 'MTL', 'SVC', 'TRV', 'TAX', 'ODC'. Kolom lain di tabel pemeta menyimpan lebih banyak detail, seperti arti kode bahasa Inggris normal, "Material", "Layanan", "Perjalanan", "Pajak", "Biaya Langsung Lainnya", dan sebagainya.

Ini sangat bagus karena tidak menggunakan lebih banyak ruang daripada int, dan ketika Anda melihat data sumber, Anda tidak perlu menautkan tabel pencarian untuk mengetahui apa nilainya. Misalnya, baris kutipan mungkin terlihat seperti:

1 PartNumber $ 40 MTL
2 OtherPartNumber $ 29,99 SVC
3 PartNumber2 $ 150 TRV

Jauh lebih mudah menggunakan int untuk mewakili kategori dan kemudian menautkan 1, 2, 3 di semua baris - Anda memiliki datanya tepat di depan Anda, dan kinerjanya tampaknya tidak terpengaruh sama sekali (bukan saya ' telah benar-benar diuji.)

Sejauh pertanyaan sebenarnya ... Saya suka pengidentifikasi unik RowGUID. Saya tidak 100% dalam hal ini, tetapi bukankah semua baris memiliki RowGuid internal ?? Jika demikian, maka menggunakan RowGuid sebenarnya akan memakan lebih sedikit ruang daripada int (atau apa pun dalam hal ini.) Yang saya tahu adalah bahwa jika itu cukup baik untuk M $ untuk digunakan di GreatPlains maka itu cukup baik untuk saya. (Haruskah aku menunduk ??)

Michael Bray
sumber
1

Oh satu lagi alasan saya menggunakan GUID - Saya menggunakan struktur data hierarki. Artinya, saya memiliki tabel 'Perusahaan' dan tabel 'Penjual' yang cocok dengan Kunci Utama. Tetapi saya juga memiliki tabel 'Pabrikan' yang juga 'mewarisi' dari Perusahaan. Bidang yang umum untuk Vendor dan Produsen tidak muncul di tabel tersebut - mereka muncul di Perusahaan. Dalam pengaturan ini, menggunakan int jauh lebih menyakitkan daripada Panduan. Paling tidak, Anda tidak dapat menggunakan kunci utama identitas.

Michael Bray
sumber
1
Ya Anda bisa, Anda hanya tidak membuat tabel subtipe memiliki properti identitas, sebagai gantinya mereka mendapatkan sisipan eksplisit dari nilai tabel supertipe. Silakan lihat stackoverflow.com/questions/2112882/…
ErikE
1

Saya suka kunci alami, kapan pun saya bisa mempercayainya. Saya bersedia membayar harga kinerja yang kecil untuk menggunakan kunci yang masuk akal bagi para ahli di bidangnya.

Untuk tabel yang mendeskripsikan entitas, harus ada kunci alami sederhana yang mengidentifikasi contoh individu dengan cara yang sama seperti yang dilakukan orang-orang materi pelajaran. Jika materi pelajaran tidak memiliki pengenal yang dapat dipercaya untuk salah satu entitas, maka saya akan menggunakan kunci pengganti.

Untuk tabel yang menjelaskan hubungan, saya menggunakan kunci gabungan, di mana setiap komponen mereferensikan entitas yang berpartisipasi dalam hubungan tersebut, dan oleh karena itu baris dalam tabel entitas. Sekali lagi, kinerja yang dicapai untuk menggunakan kunci majemuk umumnya minimal.

Seperti yang ditunjukkan orang lain, istilah "kunci utama" agak menyesatkan. Dalam Model Data Relasional, istilah yang digunakan adalah "kunci kandidat". Mungkin ada beberapa kunci kandidat untuk satu tabel. Logikanya, masing-masing sama bagusnya dengan yang lain. Memilih salah satunya sebagai "utama" dan membuat semua referensi melalui kunci itu hanyalah pilihan yang dapat dibuat oleh desainer.

Walter Mitty
sumber
Tolong jelaskan beberapa contoh kunci alami yang dapat dipercaya?
ErikE
1
"dapat dipercaya" bukanlah properti kunci dengan sendirinya. Sebaliknya, ini berkaitan dengan kunci dalam konteks orang yang menyediakan data. Jika Anda menulis aplikasi untuk dijual kepada seseorang yang benar-benar akan mengelola datanya, Anda harus menebak kunci mana yang dapat dipercaya oleh klien atau tidak. Mengingat banyaknya klien, Anda hampir pasti akan salah menebak untuk sebagian kecil dari klien Anda.
Walter Mitty
Karena itu di atas, berikut adalah contoh kunci yang kami percayai dulu. Kami memiliki database tentang kursus. Ini termasuk buku teks dan materi kursus lainnya tentang kursus, penawaran kursus terjadwal, instruktur yang memenuhi syarat untuk mengajar kursus, prasyarat kursus, biaya kuliah, dan sebagainya. Ketika pengembangan kursus membuat kursus baru, salah satu hal pertama yang mereka lakukan adalah menetapkan kode kursus. Mereka bertanggung jawab untuk memastikan bahwa kode kursus itu unik, dan kursus tidak pernah mengubah kode mereka, setelah ditetapkan. Itu adalah bagian dari data yang diberikan kepada kami.
Walter Mitty
Contoh bagus lainnya dari kunci alami tepercaya adalah VIN (Vehicle Identification Number). Selama beberapa tahun terakhir, setiap kendaraan yang dijual sebagai yang baru memiliki NIK yang terpasang padanya. Mereka dapat dipercaya untuk menjadi unik dan tidak berubah.
Walter Mitty
1

Panduan. Periode.

Jika Anda ingin memperbesar atau ingin menetapkan kunci utama dengan cara lain, mereka akan menjadi teman Anda. Anda dapat menambahkan indeks untuk yang lainnya.


perbarui untuk memperjelas pernyataan saya.

Saya telah mengerjakan banyak jenis situs. Dari penawaran server tunggal kecil hingga yang besar didukung dengan beberapa DB dan server web. Pasti ada aplikasi yang akan baik-baik saja dengan int yang bertambah secara otomatis sebagai kunci utama. Namun, itu tidak sesuai dengan model bagaimana saya melakukan sesuatu.

Saat menggunakan GUID, Anda dapat menghasilkan ID di mana saja. Ini bisa dibuat oleh server jarak jauh, aplikasi web Anda, di dalam database itu sendiri atau bahkan dalam beberapa database dalam situasi multimaster.

Di sisi lain, INT yang bertambah secara otomatis hanya dapat dibuat dengan aman dalam database utama. Sekali lagi, ini mungkin baik-baik saja jika Anda memiliki aplikasi yang akan terkait erat dengan server DB yang mendukung dan penskalaan bukanlah sesuatu yang Anda khawatirkan.

Tentu, penggunaan GUID berarti Anda harus melakukan proses pengindeksan ulang setiap malam. Namun, jika Anda menggunakan apa pun selain INT yang bertambah otomatis, Anda harus tetap melakukannya. Heck, bahkan dengan INT sebagai yang utama, kemungkinan Anda memiliki indeks lain yang perlu dibuat ulang untuk menangani fragmentasi. Oleh karena itu, menggunakan GUID tidak benar-benar menambah masalah lain karena tugas-tugas tersebut perlu dilakukan apa pun.

Jika Anda melihat aplikasi yang lebih besar di luar sana, Anda akan melihat sesuatu yang penting: semuanya menggunakan GUID yang dikodekan Base64 sebagai kuncinya. Alasan untuk ini adalah sederhana, penggunaan GUIDs memungkinkan Anda untuk skala keluar dengan mudah sedangkan bisa ada banyak rintangan untuk melompat melalui ketika mencoba untuk skala keluar INTs.

Aplikasi terbaru kami mengalami periode penyisipan berat yang berlangsung selama sekitar satu bulan. Setelah itu, 90 +% kueri semuanya dipilih untuk pelaporan. Untuk meningkatkan kapasitas, saya dapat menampilkan server DB tambahan selama periode penyisipan yang besar ini; dan kemudian dengan mudah menggabungkannya menjadi satu DB untuk pelaporan. Mencoba melakukan itu dengan INT akan menjadi mimpi buruk yang mutlak.

Sejujurnya, setiap kali Anda mengelompokkan database atau membuat replikasi, server DB akan meminta Anda memiliki GUID di atas meja. Jadi, jika Anda berpikir bahwa sistem Anda mungkin perlu berkembang maka pilihlah yang bagus.

Chris Lively
sumber
Anda pernah memeriksa faktor pengisian indeks Anda? Sifat acak GUID's make 'em swiss cheese - secara dramatis mengurangi keefektifannya.
stephbu
2
"Guids.period": Itu salah sekali. GUID harus digunakan jika sesuai. Seperti yang ditunjukkan oleh pemberi komentar yang lain, mungkin membuat hidup sebagai programmer menjadi mudah, tetapi mempengaruhi ukuran dan kinerja DB secara keseluruhan.
Mitch Wheat
Pada akhirnya, saya dapat menskalakan aplikasi saya di beberapa server database tanpa masalah. Tapi saya rasa kalian bekerja di situs kecil.
NotMe
3
GUID mungkin baik-baik saja untuk kunci primer logis, tetapi TIDAK PERNAH PERNAH menggunakan kolom GUID sebagai kunci CLUSTERING Anda - Anda akan tenggelam dalam fragmentasi indeks yang menyebabkan kinerja BURUK .....
marc_s
Saya pasti tidak akan memberitakan "Guids.period." tentang topik ini - bahkan dalam industri yang penuh dengan 'praktik terbaik', pernyataan semacam itu membuat Anda goyah secara default (terutama dengan pernyataan itu). Apa pun yang menyakitkan untuk ditangani seperti GUID membutuhkan pembenaran yang kuat dan seperti yang dikatakan JL, saya pikir kebanyakan dari kita akan menganggapnya sebagai pilihan terakhir. Seolah-olah Anda memposting tanpa membaca sisa utas.
Hardryv
0

Ini adalah subjek yang kompleks apakah Anda menyadarinya atau tidak. Mungkin termasuk dalam bagian di FAQ StackOverflow ini.

Pertanyaan macam apa yang tidak boleh saya tanyakan di sini?

Hindari mengajukan pertanyaan yang subjektif, argumentatif, atau membutuhkan diskusi yang panjang. Ini adalah tempat untuk pertanyaan yang bisa dijawab!

Ini telah diperdebatkan selama bertahun-tahun dan akan terus diperdebatkan selama bertahun-tahun. Satu-satunya petunjuk dari konsensus yang saya lihat adalah bahwa jawabannya agak dapat diprediksi tergantung pada apakah Anda bertanya kepada seorang OO (GUID adalah satu-satunya cara untuk pergi!), Seorang pemodel data (Kunci alami adalah satu-satunya cara untuk pergi!), atau DBA yang berorientasi pada kinerja (INT adalah satu-satunya cara untuk pergi!).

Shane Delmore
sumber
Saya tidak akan membiarkan pembahasannya berlangsung lama. Saya hanya ingin melihat konsensus umum.
Perpetualcoder
1
Saya katakan ajukan pertanyaan apa pun yang Anda inginkan! Jika tidak, komunitas ini akan menjadi statis dan terkendali seperti wikipedia. Menurut saya, kadang-kadang Anda perlu membiarkan orang bertanya apa pun yang Anda inginkan. Percayai mereka, dan mereka mungkin akan mempercayai diri mereka sendiri!
Nicholas Leonard