Haruskah setiap meja memiliki pengganti tunggal / kunci primer buatan?

33

Saya mengerti satu manfaat dari pengganti / kunci buatan secara umum - mereka tidak berubah dan itu bisa sangat nyaman. Ini benar apakah mereka satu atau beberapa bidang - selama mereka 'buatan'.

Namun, kadang-kadang tampaknya merupakan masalah kebijakan untuk memiliki bidang bilangan bulat yang bertambah secara otomatis sebagai kunci utama dari setiap tabel. Apakah ini selalu merupakan ide terbaik untuk memiliki kunci bidang tunggal dan mengapa (atau mengapa tidak)?

Untuk lebih jelas, pertanyaan ini bukan tentang buatan vs alami - tetapi tentang apakah semua kunci buatan harus bidang tunggal

Jack Douglas
sumber
1
lihat juga dba.stackexchange.com/a/112632/1396
Jack Douglas

Jawaban:

28

Saya akan mengatakan tidak, tidak selalu, tetapi sebagian besar waktu ya. .

Ini adalah beberapa keadaan di mana Anda tidak memerlukan pengganti atau kunci buatan:

  • Tabel persimpangan murni . Jika tidak ada risiko persimpangan menjadi target kunci asing dan jika ada sedikit atau tidak ada risiko persimpangan menarik atribut independen (yaitu sesuatu selain FK ke dua tabel induk) maka Anda bisa lolos dengan menggunakan kombinasi FK sebagai PK dengan keyakinan yang adil.
  • Tabel pencarian dengan kunci bisnis statis . Jika Anda memiliki
    tabel pencarian dengan kunci bisnis unik yang ditetapkan secara eksternal untuk
    bisnis Anda dan yang tidak memiliki peluang untuk berubah untuk
    tujuan praktis apa pun , maka menggunakan kunci bisnis secara langsung dapat membuat
    segalanya lebih sederhana. Contohnya mungkin daftar
    kode negara bagian atau provinsi atau daftar nomor standar ANSI, dll.
  • Tabel yang berisi data yang dikonsolidasikan dari berbagai sumber independen . Jika sistem Anda memiliki banyak sumber data yang harus disatukan menjadi satu tabel, katakan di kantor pusat, maka terkadang Anda memerlukan kunci majemuk yang menyertakan nilai kunci sistem sumber dan kode yang menunjukkan apa sistem sumber itu.

Ada juga beberapa situasi di mana kunci pengganti bilangan bulat tua monoton yang setia tidak ideal. Anda dapat memiliki kunci yang merupakan pengganti alfanumerik. Ini dapat mencakup:

  • Situasi di mana Anda perlu menggabungkan data dari berbagai sumber independen. Untuk menghindari tabrakan kunci, Anda mungkin menggunakan GUID dan bukannya kunci IDENTITAS.
  • Situasi di mana Anda dipaksa untuk menggunakan representasi kunci non-numerik. Katakanlah Anda memiliki basis data plat nomor. Kunci Anda bisa berupa nilai alfanumerik alih-alih angka murni.
  • Situasi di mana beberapa persyaratan eksternal memaksa Anda untuk menerapkan kompresi pada nilai kunci Anda. Alih-alih menggunakan 10 digit untuk int32 Anda dapat menggunakan enam basis 36 digit.

Kenapa sebagian besar waktu ya? Jawaban paling mendasar untuk pertanyaan itu adalah benar-benar neraka jika Anda perlu mengubah nilai kunci utama pada tabel apa pun. Karena hampir semua hal yang dapat dilihat atau disentuh oleh pengguna dapat dibuktikan dengan pembaruan di beberapa titik, menggunakan nilai kunci yang terlihat mengundang banyak sekali. Menggunakan kunci pengganti akan membuat Anda tidak jatuh ke dalam perangkap ini.

Karena itu, ingatlah bahwa ada ruang untuk YAGNI dalam menerapkan konsep ini. Anda tidak perlu memaksakan tabel kode dengan kunci IDENTITAS ke setiap sudut dan celah skema Anda, kalau-kalau seseorang memutuskan bahwa simbol untuk jenis kelamin laki-laki di meja karyawan Anda perlu diubah dari M ke X atau sesuatu yang konyol.

Joel Brown
sumber
"Menggunakan kunci pengganti akan membuat Anda tidak jatuh ke dalam perangkap ini" Pertanyaannya bukan tentang pengganti vs alami, tetapi tentang pengganti bidang tunggal vs multi-bidang.
Jack Douglas
Seperti yang telah Anda akui dalam komentar atas jawaban Anda sendiri, kami berada di wilayah "setuju untuk tidak setuju" dalam hal apa yang bijaksana dalam desain basis data. Mengingat hasil edit Anda, saya tidak akan membuat perbedaan antara kunci pengganti dan alami, jadi poin kedua saya terlambat topik. Poin saya yang lain mengenai kapan seseorang mungkin menyimpang dari pendekatan identitas / urutan klasik masih berdiri.
Joel Brown
Saya tidak mengubah pertanyaan seperti yang Anda lihat dari sejarah, hanya menambahkan penekanan di mana saya pikir itu akan membantu pembaca skim
Jack Douglas
12

Tidak.

Saya akan mengatakan pasti ada kasus ketika kunci bidang tunggal lebih rendah daripada kunci majemuk, setidaknya untuk tujuan kunci asing . Itu tidak berarti Anda tidak harus memiliki kunci pengganti bidang tunggal juga jika Anda suka, tapi saya pribadi lebih suka kunci yang paling sering digunakan sebagai target kunci asing untuk disebut kunci utama

Saya akan mencoba mengilustrasikan poin saya dalam contoh-contoh berikut, di mana:

  • brand adalah car marque, mis. Ford, Toyota dll
  • dealer adalah dealer fisik, terkait dengan merek (mis. dealer Ford yang hanya menjual Ford)
  • model adalah jenis mobil misalnya Ford Focus, Ford Fiesta dll
  • stock adalah jumlah halaman depan mobil saat ini untuk setiap dealer

Jika kita membuat kunci pengganti bidang tunggal untuk dealerdan modelsebagai berikut:

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

maka dimungkinkan untuk memasukkan baris ke dalam stocktautan yang menghubungkan Ford dealerke model "Toyota". Menambahkan brand_id references branduntuk stockhanya membuat masalah lebih buruk. Di sisi lain jika kita menyimpan kunci asing sebagai bagian dari kunci utama sebagai berikut:

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

sekarang aturan bahwa "Ford" dealer hanya dapat menyediakan mobil "Ford" ditegakkan secara alami oleh model.

Perhatikan bahwa dalam contoh 'kunci komposit', dealer_idmungkin atau mungkin tidak unik, sesuai dengan preferensi. Itu tidak perlu unik (yaitu kunci alternatif), tetapi sangat sedikit yang hilang dengan membuatnya jadi (mungkin ruang penyimpanan kecil) dan itu bisa sangat berguna sehingga cara saya biasanya mengaturnya, misalnya:

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )
Jack Douglas
sumber
3
Membuat kelonggaran untuk ketentuan yang biasa tentang contoh tidak selalu sempurna dari setiap sudut, saya akan mengatakan bahwa jenis desain ini sangat rapuh. Meskipun ada sesuatu yang memuaskan tentang menemukan cara untuk menggunakan DRI untuk menegakkan aturan bisnis, itu juga menghilangkan sebagian kemampuan Anda untuk merespons perubahan. Jika Toyota membeli Ford, atau bahkan jika dealer Ford memutuskan untuk menjual Toyota bekas, aturan bisnis Anda yang digerakkan oleh DRI akan memberi Anda sakit kepala pemeliharaan.
Joel Brown
1
Jadi "aturan bisnis Anda mungkin berubah". Itu berlaku untuk semua aturan bisnis dan akan selalu berpotensi sulit untuk dimodel ulang. Saya biasanya diberi tahu apa aturan bisnisnya - saya tidak memutuskannya sendiri.
Jack Douglas
1
Apakah Anda mengatakan bahwa DRI tidak boleh digunakan sama sekali untuk menegakkan aturan bisnis? Bukankah itu satu-satunya yang dilakukan DRI? - bahkan kunci asing sederhana adalah aturan bisnis yang diberlakukan oleh DRI.
Jack Douglas
4
Tentu saja DRI memberlakukan aturan bisnis. Anda harus memutuskan aturan mana yang akan diberlakukan dalam kode dan mana dalam skema Anda. Perubahan skema hampir selalu lebih sulit daripada perubahan kode. Ada dua jenis aturan bisnis yang bisa masuk ke model data Anda. Satu milik di sana dan satu tidak. Sifat dasar data yang penting bagi bisnis Anda tidak banyak berubah. Cara spesifik di mana Anda beroperasi pada data itu jauh lebih tidak stabil . Aturan seperti mobil yang dimiliki pembuat termasuk dalam model data. Aturan seperti dealer tidak akan pernah menjual dua merek mobil tidak.
Joel Brown
4
"Perubahan skema hampir selalu lebih sulit daripada perubahan kode" IMO sebaliknya benar. Sebenarnya saya tidak setuju dengan hampir semua yang baru saja Anda katakan tetapi saya ragu ada gunanya berdebat dengan Anda, jadi saya akan membiarkannya begitu saja.
Jack Douglas
12

"tergantung"

Ya: Bidang IDENTITAS / AUTONUMBER pengganti baik ketika kunci alami lebar dan non-numerik. Catatan: ini mengasumsikan penyatuan "PK" dan indeks berkerumun yang terjadi secara default di SQL Server dan Sybase dll

Tidak: banyak / banyak tabel ketika 2 kunci induk cukup. Atau ketika kunci alami pendek dan panjang tetap misalnya kode mata uang

Tentu saja, ORM braindead (baca: (n) Hibernate) dapat mengalahkan aturan ini ...

Edit: baca pertanyaan lagi

Tabel banyak / banyak dengan 2 kunci induk pengganti akan memiliki beberapa kolom PK.
Namun, tidak perlu kolom pengganti lain.

Jika sebuah tabel memiliki kunci pengganti (IDENTITAS dll), maka itu tidak perlu beberapa kolom.

Anda dapat memiliki kunci super yang menyertakan pengganti tetapi ini akan untuk menegakkan aturan lain (misalnya subtipe )

gbn
sumber