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?
database-design
Covar
sumber
sumber
Jawaban:
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.
sumber
Masuk akal memiliki kolom id terpisah. Ketika Anda ingin mendapatkan sesuatu dari tabel database Anda, lebih mudah dilakukan:
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:
atau seperti ini:
sumber
SELECT
pertanyaan 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
.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.
select * from Address where CountryCode = 'US'
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.
sumber
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.
sumber
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.
sumber
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.
sumber
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.
sumber
Memiliki PK menjadi int autoincrement mengurangi kerumitan jika Anda menemukan bahwa kunci komposit Anda sebenarnya memiliki duplikat.
sumber
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.
sumber