Haruskah kunci primer tidak berubah?

26

Sebuah pertanyaan baru - baru ini tentang stackoverflow memicu diskusi tentang ketidakmampuan kunci primer. Saya telah berpikir bahwa itu adalah semacam aturan bahwa kunci utama harus tidak berubah. Jika ada kemungkinan suatu hari kunci primer akan diperbarui, saya pikir Anda harus menggunakan kunci pengganti. Namun itu tidak dalam standar SQL dan beberapa fitur "pembaruan kaskade" RDBMS memungkinkan kunci utama untuk berubah.

Jadi pertanyaan saya adalah: apakah masih merupakan praktik yang buruk untuk memiliki kunci utama yang dapat berubah? Apa kontra jika memiliki kunci primer yang bisa berubah?

Vincent Malgrat
sumber

Jawaban:

25

Anda hanya perlu kunci utama agar tidak berubah jika dikaitkan dengan kunci asing, atau jika digunakan sebagai pengidentifikasi di luar basis data (misalnya dalam URL yang menunjuk ke halaman untuk item).

Di sisi lain, Anda hanya perlu memiliki kunci yang bisa berubah jika membawa beberapa informasi yang mungkin berubah. Saya selalu menggunakan kunci pengganti jika catatan tidak memiliki pengidentifikasi sederhana dan tidak dapat diubah yang dapat digunakan sebagai kunci.

Guffa
sumber
7
Mengapa Anda " membutuhkan kunci utama agar tidak berubah jika dikaitkan dengan kunci asing"? Seperti yang disebutkan OP, sebagian besar RDBMS memiliki fitur pembaruan "cascade".
Thanatos
1
@Thanatos sebagian besar (pada kenyataannya semua yang saya temui) rdbms's tidak akan mengizinkan kunci primer yang dapat berubah namun memiliki pembaruan yang mengalir. Kunci utama, dalam kebijaksanaan dba yang diterima secara umum, tidak boleh mengandung informasi, hanya menjadi pengidentifikasi catatan yang unik (jadi bukan stempel waktu, rentang catatan yang ditangguhkan darinya, dll.).
jwenting
5
@jwenting: Apakah kita membicarakan hal yang sama? "Kebanyakan rdbms tidak akan mengizinkan kunci primer yang bisa diubah" termasuk apa? MySQL dan PostgreSQL keduanya memungkinkan kunci primer bisa berubah, dan menghormati pembaruan berjenjang ... seperti yang saya pikir standar SQL mengatakan mereka harus. Juga, "kebijaksanaan dba diterima secara umum"? Saya telah bertemu banyak DBA yang menentang kunci pengganti, dan banyak yang menentang kunci alami.
Thanatos
2
@Thanatos Argumen yang mendukung "semua tabel harus memiliki pengganti" kekurangan referensi bibliografi, mereka mengutip "kebijaksanaan dba yang diterima secara umum" tetapi mereka tidak pernah mengutip buku. Buku kanonik mengatakan Anda harus menggunakan pengganti jika: A. tidak ada kunci alami, B. kunci multikolom melebihi 3 kolom, atau, C. Anda akan selalu mengubah kunci. Jadi: alami ketika mereka cocok, pengganti ketika alami tidak cocok.
Tulains Córdova
4
@ user61852: Apa?
Guffa
15

Kunci utama harus terdiri dari tupel apa pun yang diperlukan untuk menentukan keunikan. Apakah data dapat berubah atau tidak tidak relevan. Hanya keunikan catatan yang penting. Itu adalah desain konseptual dari database.

Ketika kita bergerak ke ranah implementasi, maka hal paling aman untuk dilakukan adalah cukup menggunakan kunci pengganti.

Chris Holmes
sumber
15

Ya, menurut saya kunci utama harus tidak berubah.

Bahkan jika ada kunci kandidat yang jelas, saya selalu menggunakan kunci pengganti. Dalam beberapa kesempatan saya belum melakukan ini, saya hampir selalu menyesalinya. Dan tidak peduli seberapa kekal menurut Anda kuncinya, Anda tidak dapat melindungi terhadap kesalahan entri data - memberi tahu pengguna bahwa mereka tidak dapat mengedit sedikit informasi itu karena itu adalah kunci utama tidak mencuci dengan sedih.

richeym
sumber
Poin bagus tentang kesalahan entri data
Tim Goodman
richeym, sepertinya Anda membuat alasan mengapa kunci TIDAK boleh berubah: pengguna mungkin ingin mengubahnya.
nvogel
4
@dportas - maksud saya adalah saya suka PK tidak dapat diubah, jadi selalu gunakan kunci pengganti bahkan jika saya pikir ada kunci yang jelas yang dapat diturunkan dari data tabel (misalnya email, nama pengguna).
richeym
2

Mekanisme cache di antara basis data dan pengguna akan kehilangan efektivitas jika kunci primer berubah.

spoulson
sumber
2

Kenapa tidak? Karena Anda ingin menghilangkan kolom?

Hanya karena persyaratan menyebut tiga kolom menjadi unik, bukan berarti harus menjadi kunci utama. Anda mungkin berpikir bahwa aturan itu akan bertahan selamanya (Ingat selama pertemuan itu ketika manajer departemen pinhead bersumpah tidak akan pernah berubah? Anda tahu, yang baru saja dipecat.), Tetapi tidak.

Saya tidak dibayar untuk setiap pembaruan kaskade yang saya terapkan dan bonus jika saya mengkodekannya sendiri.

Komputer tidak memerlukan makna apa pun untuk kunci; IMHO, kunci untuk komputer, biarkan orang-orang mengacaukan sisa data.

JeffO
sumber
1
"Kunci untuk komputer, biarkan orang mengacaukan sisa data." +1, bagus.
2

Bukan praktik yang buruk untuk memiliki kunci yang nilainya dapat berubah.

Properti kunci yang baik termasuk stabilitas. Kekekalan ideal tetapi bukan prasyarat. Memperkenalkan kunci buatan demi ketidakberdayaan adalah praktik buruk.

Ambil contoh Nomor Buku Standar Internasional (ISBN) . Ini sangat stabil tetapi tidak berubah: kadang penerbit buku membuat kesalahan dan - horor! - Nomor ISBN duplikat dapat terjadi. Apakah ini berarti ISBN tidak boleh diterima sebagai kunci kandidat dalam basis data yang terkomputerisasi? Tentu saja tidak. Salah satu kelebihan ISBN adalah memiliki sumber tepercaya yang akan menyelesaikan masalah bagi semua pengguna secara global.

Ada beberapa kelengkapan lain dari ISBN kunci yang baik yang tidak memiliki kekurangan kunci integer otomatis yang tidak berarti, misalnya keakraban (semua orang dalam perdagangan buku tahu atau terbiasa dengan ISBN), dapat diverifikasi (ISBN dicetak pada semua buku modern), dapat divalidasi dengan mengacu pada DBMS (ISBN adalah lebar tetap dan termasuk checksum), dll.

suatu hari nanti
sumber
3
ISBN lebar tetap, kecuali bila tidak (lihat ISBN-10 vs ISBN-13).
CVn
Jadi, bagaimana Anda merekomendasikan penanganan ISBN rangkap? Di semua RDBMS yang saya ketahui, Anda harus memiliki batasan UNIK di lapangan untuk menggunakannya sebagai kunci utama.
Wildcard
1

Segala sesuatu yang mungkin bisa berubah harus. Ini membantu untuk memastikan kebenaran dan membantu ketika Anda ingin membuat aplikasi Anda multithreaded.

dash-tom-bang
sumber
1

Ya, kunci utama harus tidak berubah, bersamaan dengan menjadi non-null dan unik. Namun, saya belum menemukan database yang menegakkan ketidakmampuan kunci primer sehingga Anda mungkin dapat melanjutkan dan mengubah nilainya jika Anda benar-benar menginginkannya.

Bob Jarvis - Pasang kembali Monica
sumber
0

Seperti beberapa komentar sudah mengatakannya, salah satu solusinya adalah menggunakan kunci utama baru

Misalnya (mengikuti contoh @onedaywhen), katakanlah ada tabel Buku yang menyimpan daftar buku dan kami "menggunakan" untuk menentukan ISBN sebagai kunci utama. Namun, beberapa penulis melakukan kesalahan dengan mengetikkan ISBN yang salah sehingga, mereka meminta untuk mengubah ISBN, itu melibatkan tugas-tugas berikutnya:

  • buat registri baru di tabel Buku
  • arahkan semua referensi dari ISBN lama ke ISBN baru. (*)
  • Dan akhirnya, hapus registry lama dari tabel Books.

(*) ini mungkin sepele untuk menemukan semua referensi untuk model database yang menggunakan Kunci Asing tetapi beberapa model tidak memilikinya.

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

Kami mengubahnya sebagai

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

Di mana InternalBookId baru bahkan bisa menjadi nilai autonumerik.

Kontra tentang hal itu:

  • itu menambah bidang baru yang menggunakan lebih banyak ruang / sumber daya.

  • bisa mengharuskan untuk menulis ulang seluruh model.

  • model baru bisa kurang menjelaskan diri.

Sang profesional

  • Memungkinkan untuk mengubah "kunci utama".
  • Memungkinkan untuk bahkan menjatuhkan atau refactoring "kunci utama", misalnya, untuk mengubah Buku ke ISBN-13 sangat sederhana untuk menjatuhkan kolom yang lebih lama dan untuk membuat yang baru

Meja baru:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
magallanes
sumber