Berapakah trade off untuk meningkatkan id vs kunci teks lengkap untuk desain kunci asing?

8

Dalam banyak desain basis data relasional ada bidang yang direferensikan di tabel lain.

Misalnya, pertimbangkan tabel pengguna dengan nama pengguna unik dan tabel kedua yang menyimpan data alamat.

Satu tata letak yang mungkin, yang akan saya katakan adalah pendekatan umum, karena saya telah mengamati di sebagian besar perangkat lunak, adalah menggunakan id kenaikan otomatis seperti ini:

Table users
===========
userId int primary auto_increment
userName varchar unique

Table adressdata
==========
userId int references users.userId
adress_type varchar // for example country
address_value varchar // for example US
(you probably also want to put a unique key on (userId,adress_type))

Ini adalah bagaimana saya melakukannya dan bagaimana saya melihatnya dalam banyak kasus.

Cara lain adalah:

Table users
===========
userName varchar primary

Table adressdata
==========
userName varchar references users.userName
adress_type varchar // for example country
address_value varchar // for example US
(you probably also want to put a unique key on (userName,adress_type))

Di sini kami menyimpan nama pengguna lengkap juga di tabel adressdata.

Bagi saya ini memiliki keuntungan sebagai berikut:

  • Anda dapat memilih nama pengguna langsung dari tabel tanpa harus bergabung ke tabel lain. Dalam contoh ini ini dari sudut pandang aplikasi mungkin tidak begitu relevan, tetapi ini hanya contoh.

  • Mungkin lebih mudah untuk skala database dalam lingkungan replikasi master-master, karena tidak ada konflik auto_increment.

Tetapi juga kerugiannya:

  • Persyaratan ruang untuk indeks dan data (tetapi yang lebih relevan mungkin adalah indeks) pada bidang di tabel kedua lebih tinggi.
  • Perubahan nama pengguna perlu disebarkan ke semua tabel, yang lebih memakan sumber daya daripada hanya mengubahnya dalam satu tabel dan membiarkan id seperti apa adanya.

Menurut pendapat saya, jauh lebih mudah untuk bekerja dengan bidang teks dan tidak menggunakan id kenaikan, dan pertukarannya minimal dan dalam sebagian besar aplikasi tidak relevan.

Tentu saja beberapa objek ADALAH diidentifikasi dengan nomor yang bertambah berdasarkan sifatnya (misalnya posting forum harus menerima id yang bertambah karena mungkin tidak ada bidang unik lain seperti judul atau lebih).

Tetapi saya sebelum saya mulai merancang tata letak basis data saya dengan cara yang sangat berbeda, saya ingin tahu apakah ada hal-hal yang tidak saya pikirkan.

  • Apakah ada praktik terbaik?

  • Apakah ada pro / kontra yang tidak saya pikirkan dan efeknya mungkin muncul di waktu kemudian?

  • Bagaimana Anda secara pribadi merancang basis data mengenai poin-poin di atas dan mengapa?

Joe Hopfgartner
sumber

Jawaban:

3

Saya menyarankan untuk menggunakan id dan bukan nama pengguna, karena jika Anda mulai menggunakan nama pengguna sebagai kolom bergabung dalam beberapa tabel, Anda harus ingat untuk memperbarui semuanya.

Kunci asing untuk userstabel, menjadi kunci utama addressdatatabel dan kunci utama harus tetap stabil. Ini adalah praktik yang baik untuk tidak mengubah bidang kunci utama. Kunci primer harus ada saat rekaman dibuat, dan harus tetap tidak berubah selama masa pakai rekaman.

Jika Anda ingin wawasan lebih lanjut Debat kunci utama adalah artikel yang bagus.

stivlo
sumber
2

Saya sangat berada di kamp "jangan gunakan kunci alami". Itu karena saya telah melihat betapa sulitnya pada sistem ketika mereka diperbarui dan hampir semua kunci alami yang melibatkan nama anykind diperbarui.

Database dioptimalkan untuk menggunakan gabungan. Ya, Anda dapat menyimpan beberapa gabungan dengan menggunakan kunci alami tetapi kinerjanya berjalan ketika Anda perlu memperbarui 1.000.000 catatan karena sekelompok kunci alami berubah (atau bahkan tergantung pada apa yang terjadi) dapat menjadi kebuntuan besar.

Saya hanya akan menggunakan kunci alami dalam dua kondisi:

  1. jika kuncinya dijamin tidak akan berubah (pikirkan nomor VIN mobil) dan
  2. jika itu tidak akan digunakan kembali (bahkan hal-hal unik seperti nomor telepon dan email bukanlah kandidat untuk PK karena mereka digunakan kembali ketika seseorang berhenti menggunakannya).

Dan tentu saja terlalu banyak kunci alami yang seharusnya unik tidak. Jika Anda khawatir tentang replikasi, Anda dapat menggunakan GUID.

HLGEM
sumber
1

Artikel Wikipedia tentang kunci Pengganti memiliki beberapa bit menarik yang tersebar:

  • " Atribut yang secara unik mengidentifikasi suatu entitas dapat berubah, yang mungkin membatalkan validitas dari kunci alami, majemuk. " Misalnya, pembatasan pada nama pengguna dapat membatalkan kunci yang ada saat menggunakan kunci alami user namesedangkan ini tidak akan mempengaruhi kunci sintetis.
  • " Kunci pengganti tidak berubah saat baris ada. " Dengan demikian, Anda tidak perlu (secara manual atau otomatis) membuat perubahan kunci ke tabel referensi.
  • " Nilai-nilai kunci pengganti yang dihasilkan tidak memiliki hubungan dengan makna dunia nyata dari data yang disimpan dalam satu baris. " Ini dapat membuat audit sulit.

Saya percaya bahwa pembaca yang penuh perhatian dapat menemukan poin tambahan untuk dipertimbangkan.


sumber
Jawaban yang bagus. Banyak kunci alami memiliki kecenderungan untuk berubah. Ini membuatnya tidak cocok untuk kunci yang dapat dirujuk sebagai kunci asing. Ada banyak alasan yang tepat untuk mengubah userid pengguna.
BillThor
1

Saya akan memposting dari pengalaman saya yang mungkin akan sangat berbeda dengan apa yang mungkin disarankan oleh berbagai DBA. Saya sebagian besar berorientasi pada campuran kinerja dan rawatan ketika merancang database untuk berbagai proyek.

Saya tidak akan pernah menggunakan kunci alami untuk kunci primer. Apalagi jika saya menggunakan MySQL / InnoDB. Saya masih belum melihat adanya manfaat dalam menggunakan kunci alami, biasanya yang saya lihat adalah implikasi kinerja jika tidak ada. Saya berani "tidak pernah, hanya" hanya karena kunci alami digunakan untuk membuat babi kinerja untuk proyek saya. Pengganti (integer) selalu merupakan pilihan yang lebih baik. Beberapa mungkin tidak setuju, tetapi kita hidup di dunia di mana kinerja memainkan peran atas teorinya.

Ketika datang ke BERGABUNG, saya tidak mencoba menghindarinya dengan cara apa pun, tetapi saya cenderung mengoptimalkannya. Saya mencoba menyalahgunakan indeks berkerumun InnoDB (kunci primer) sebanyak mungkin. Jika GABUNGAN dilakukan melalui PK, maka mereka sangat cepat. Saya juga cenderung menghindari FK di mana mereka tidak masuk akal. Jujur, saya tidak akan terlalu peduli tentang integritas data ketika datang untuk menghubungkan pengguna dan informasi alamat mereka. Saya akan memberlakukannya saat menautkan faktur ke item ke pengguna. Terlalu sering menggunakan FK adalah kerja keras dan mimpi buruk untuk dipertahankan setelah Anda mereferensikan semuanya, berpikir itu adalah desain yang bagus untuk menjaga hubungan di semua tempat. Di beberapa titik waktu, hal-hal perlu diubah dan ketika MySQL mulai mengeluh dengan kesalahan 150 terus-menerus, Anda hanya ingin pulang.

Anda juga menyebutkan replikasi dan menghindari bentrokan karena sifat auto_increments. Saya memiliki proyek di mana kami memiliki sejumlah database yang menyimpan informasi penjualan produk, jumlah database bervariasi. Setiap hari database direplikasi ke satu "master" database yang kami gunakan untuk menjalankan laporan. Cara saya menghindari bentrokan PK adalah dengan membuat kunci primer majemuk dari bagian auto_increment dan bagian INT lainnya yang menunjukkan lokasi dari mana catatan itu berasal. Dengan begitu saya bisa melacak dari mana barang-barang itu berasal dan saya tidak kehilangan apa pun (produk memiliki ID yang sama, hanya pengidentifikasi lokasi yang diubah).

NB
sumber