Haruskah saya menggunakan beberapa kunci utama kolom atau menambahkan kolom baru?


15

Desain basis data saya saat ini menggunakan kunci utama beberapa kolom untuk menggunakan data yang ada (yang akan menjadi unik) alih-alih membuat kolom tambahan yang menetapkan setiap entri sebagai kunci sewenang-wenang. Saya tahu bahwa ini diperbolehkan, tetapi bertanya-tanya apakah ini adalah praktik yang mungkin ingin saya gunakan dengan hati-hati dan mungkin dihindari (seperti halnya goto di C).

Jadi apa saja kerugian yang mungkin saya lihat dalam pendekatan ini atau alasan saya mungkin ingin kunci kolom tunggal?


2
Saya tidak tahu, saya pikir ini akan lebih baik pada SO.
FrustratedWithFormsDesigner

2
@FrustratedWithFormsDesigner Bisa pergi ke SO, tapi saya pikir itu bekerja di sini juga, karena fokus pertanyaan tampaknya pada "apa pro dan kontra dari pendekatan ini" daripada "bagaimana saya melakukan X?".
Adam Lear

@Anna Lear ♦: Ini adalah "pro dan kontra" tentang keputusan desain yang akan memiliki dampak langsung dan pasti pada pengkodean, jadi saya pikir SO akan menjadi tempat yang lebih baik.
FrustratedWithFormsDesigner

Jawaban:


8

Biasanya ketika Anda memiliki tabel dengan kunci utama multi-kolom, itu adalah hasil dari tabel bergabung (banyak-ke-banyak) yang menjadi terangkat menjadi entitasnya sendiri (dan dengan demikian layak mendapatkan kunci primer itu sendiri). Ada banyak yang akan berpendapat bahwa setiap tabel bergabung HARUS menjadi entitas secara default, tapi itu diskusi untuk hari lain.

Mari kita lihat hubungan hipotesa banyak ke banyak:

Siswa * --- * Kelas

(Siswa dapat berada di beberapa kelas, suatu Kelas dapat memiliki beberapa siswa).

Di antara kedua tabel tersebut akan ada tabel persimpangan yang disebut StudentClass (atau ClassStudent tergantung bagaimana Anda menulisnya). Terkadang, Anda ingin melacak hal-hal seperti ketika siswa di kelas. Jadi, Anda akan menambahkannya ke tabel StudentClass. Pada titik ini, StudentClass telah menjadi entitas yang unik ... dan harus diberi nama untuk mengenalinya seperti misalnya Pendaftaran.

Siswa 1 --- * Pendaftaran * --- 1 Kelas

(seorang siswa dapat memiliki banyak Pendaftaran, masing-masing Pendaftaran adalah untuk satu kelas (atau sebaliknya, suatu Kelas dapat memiliki banyak Pendaftaran, masing-masing Pendaftaran adalah untuk satu Siswa).

Sekarang Anda dapat menanyakan hal-hal seperti, berapa banyak siswa yang terdaftar di kelas Chemistry 101 tahun terakhir ini? Atau kelas apa yang didaftarkan oleh siswa John Doe ketika menghadiri Acme University? Ini dimungkinkan tanpa kunci primer yang terpisah, tetapi begitu Anda memiliki kunci primer untuk pendaftaran, kueri yang lebih mudah adalah dari pendaftaran ini (berdasarkan id), berapa banyak siswa yang menerima nilai kelulusan?

Penentuan apakah suatu entitas layak mendapat PK bermuara pada seberapa banyak permintaan (atau manipulasi) yang akan Anda lakukan untuk entitas itu. Katakanlah misalnya, Anda ingin melampirkan tugas yang diselesaikan untuk siswa di kelas. Tempat logis untuk melampirkan entitas ini (Tugas) akan berada di entitas Pendaftaran. Memberikan pendaftaran itu sendiri adalah kunci utama akan membuat kueri Penugasan lebih sederhana.


1
Jadi, Anda akan menambahkannya ke tabel StudentClass. Pada titik ini, StudentClass telah menjadi entitas yang unik ... dan harus diberi nama untuk mengenalinya seperti misalnya Pendaftaran. Ini hal yang sangat sederhana, tetapi ada banyak manfaat dalam melakukan ini!
Botis

8

Masuk akal memiliki kolom id terpisah. Ketika Anda ingin mendapatkan sesuatu dari tabel database Anda, lebih mudah dilakukan:

SELECT whatever FROM table WHERE id=13

dari SELECT apapun DARI tabel WHERE col1 = 'val1' AND col2 = 'val2' AND col3 = 'val3'

Misalnya, dalam aplikasi web itu diterjemahkan ke url yang tampak seperti ini:

www.somewebsite.com/somepage.php?id=13

atau seperti ini:

www.somewebsite.com/somepage.php?col1=val1&col2=val2&col3=val3

4
Dan jauh lebih mudah untuk menambahkan tabel terkait ketika Anda dapat menautkan pada sebuah Id, daripada beberapa kolom
CaffGeek

3
Maaf, pada titik ini saya harus -1, karena A) ini bukan hitam dan putih. Menambahkan kolom ID disertai dengan negatif seperti di mana dan kapan Anda menghasilkan ID baru itu. Selain itu, ini dapat menghasilkan gabungan atau SELECTpertanyaan tambahan . Dan, B) , saya tidak tahu bagaimana ini sebenarnya menyebabkan semua jenis persyaratan URL (kecuali jika Anda bekerja dengan kerangka kerja yang buruk). URL saya tidak memiliki string kueri apa pun ?id=13, apalagi ?col1=val1&col2=val2&col3=val3.
Nicole

2
@renesis: Situs ini memiliki pertanyaan dan pengguna unik, yang ada di URL. Meskipun, ini agak kasus khusus, karena data tertentu tidak berubah.
Michael K

1
@ Retesis, sebagian besar (mungkin semua) db modern memiliki tipe kolom integer auto_increment yang dapat menghasilkan ID secara otomatis dan aman, dan melaporkannya kembali melalui kueri sql atau panggilan fungsi perpustakaan. Atau di lingkungan terdistribusi, Anda menggunakan hash acak besar. Beberapa DB bahkan akan membuat kolom id tersembunyi untuk Anda jika Anda belum memilikinya di tabel.
GrandmasterB

@Michael - Saya tidak mengatakan ID tidak pernah ada di URL. Tentu mereka. Jika Anda memiliki URL yang mewakili deretan data, maka ya, data itu mungkin harus memiliki ID unik. Kecuali beberapa bagian lain dari URL sudah menyediakan bagian-bagian lain dari multi-key. @GrandmasterB Tidak satu pun dari dua perusahaan tempat saya bekerja (lebih dari 6 tahun), yang keduanya menggunakan MySQL (satu juga mendukung Oracle dan SQL Server) dapat menggunakan peningkatan otomatis, atau hash acak besar.
Nicole

8

Pada dasarnya Anda bertanya apakah Anda harus menggunakan kunci pengganti atau alami (dalam kasus Anda kedengarannya seperti kunci alami komposit ). Inilah artikel yang bagus: http://www.agiledata.org/essays/keys.html

Saya lebih suka kunci pengganti karena mereka menyederhanakan administrasi selama kehidupan DB (Anda tidak perlu khawatir tentang implikasi kunci mengubah makna, yang seharusnya tidak pernah terjadi tetapi tidak dalam sistem nyata di mana manusia terlibat). Namun , jika ada banyak tabel "pencarian" di DB (yaitu tabel yang pada dasarnya adalah kunci: pasangan nilai), maka kunci pengganti bisa menjadi rumit karena Anda harus menggabungkan tabel tersebut ke dalam kueri untuk mendapatkan hasil yang bermakna.

Misalnya, katakanlah Anda memiliki dua entitas: Alamat, dan Negara.

  • Hubungannya adalah: Alamat * ----- 1 Negara
  • Entitas Negara pada dasarnya adalah kunci: pasangan nilai (mis. AS: Amerika Serikat, CA: Kanada, MX: Meksiko, dll ...)
  • Untuk menanyakan struktur ini untuk semua Alamat di AS:

select * from Address where CountryCode = 'US'

  • Untuk melakukan permintaan yang sama dengan kunci pengganti:

select Address.* from Address join Country on Address.CountryID = Country.ID where Country.Code = 'US'

Saya merasa nyaman mengamanatkan kunci alami untuk tabel pencarian dan mengganti kunci untuk yang lainnya, jika saya cukup yakin bahwa kunci alami tidak akan terlalu sering berubah, jika pernah.


5

Itu tergantung pada bagaimana Anda mengakses data. Jika Anda melakukan banyak pencarian kunci-parsial (di mana Anda memilih catatan berdasarkan katakan saja dua dari tiga kunci) maka Anda ingin menyimpan kunci multi-bagian. OTOH, jika Anda memiliki banyak hubungan 1: 1 dengan tabel lain, mungkin lebih masuk akal untuk memiliki kunci pengganti.


1

Saya ingin selalu memiliki kunci utama pengganti untuk setiap tabel. Tetapi tidak ada banyak alasan "keras" untuk menegakkan ini yang telah saya dengar.

Satu waktu yang pernah saya alami kunci multi-kolom menggigit saya adalah dengan ORM. Kadang-kadang saya akan mengalami masalah dengan kunci primer beberapa kolom menggunakan Linq To Entities.


1

Tidak pernah mengatakan tidak pernah, tetapi bergabung dalam 4 kolom itu menyebalkan. Semakin banyak kolom yang Anda miliki dengan data cerdas, semakin besar peluang nilai-nilai itu dapat berubah. Basis data dapat disiapkan untuk menjaga integritas referensi dengan pembaruan cascading.

Anda selalu dapat membuat indeks lain untuk menangani nilai unik.

Kinerja mungkin diabaikan dalam kebanyakan kasus, tetapi Anda dapat menguji pertanyaan Anda dengan dan tanpa kunci surragate.


0

Saya merasa sulit untuk datang dengan alasan yang baik untuk mengamanatkan kunci yang terpisah, tetapi seperti yang Anda katakan, banyak orang memasukkannya.

Saya tidak menemukan ini membantu (terutama dengan penyimpanan) ketika berhadapan dengan tabel fakta / detail. Contoh kanonik tabel fakta penjualan dengan (customer_key, store_key, product_key) dengan kuantitas tidak masuk akal untuk memiliki kunci tingkat rekor.


0

Memiliki PK menjadi int autoincrement mengurangi kerumitan jika Anda menemukan bahwa kunci komposit Anda sebenarnya memiliki duplikat.


0

Ada diskusi yang bagus pada tahun 2002 tentang Ask Tom . Ini khusus Oracle, tetapi diskusi yang lebih luas relevan dengan basis data apa pun yang Anda gunakan.

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.