Latar Belakang
Saya punya tabel ini
+-------------------------+ +------------------------+
|Airport | |Country |
|-------------------------| |------------------------|
|airport_code string (PK) | |country_code string (PK)|
|address string | |name string |
|name string | +------------------------+
+-------------------------+
+-------------------------+
|Currency |
|-------------------------|
|currency_code string (PK)|
|name string |
+-------------------------+
airport_code adalah kode bandara IATA (International Air Transport Association) , Anda dapat melihatnya di tag bagasi Anda saat bepergian dengan pesawat.
country_code adalah kode negara standar ISO 3166-1 A3 , Anda dapat melihatnya di olimpiade.
currency_code adalah kode mata uang 3-karakter standar IS0 417 , Anda dapat melihatnya di papan layar pertukaran mata uang internasional.
Pertanyaan
Apakah PK alami ini cukup baik?
Apakah menggunakan standar yang dihormati dunia, yang diterima oleh seluruh industri cukup baik untuk PK?
Apakah tabel ini perlu pengganti tidak peduli apa?
sumber
Saya pikir perlu adalah kata yang sangat kuat, dan dalam arti yang ketat, tabel mungkin tidak perlu kunci pengganti .
Namun, jika itu adalah basis data saya, saya mungkin akan menambahkan kunci pengganti. Saya mungkin tidak ingin desain database saya bergantung pada sekelompok pihak ketiga (IATA, ISO), terlepas dari seberapa stabil standar mereka. Atau, saya mungkin tidak ingin bergantung pada standar tertentu sama sekali (adakah standar kode mata uang lainnya? Saya tidak tahu). Saya mungkin akan memodelkan meja saya dengan kunci pengganti seperti:
Dengan kata lain, kecuali kode standar industri itu secara inheren penting untuk aplikasi saya, saya tidak akan menggunakannya sebagai PK dari tabel saya. Itu hanya label. Sebagian besar tabel saya yang lain mungkin akan memiliki kunci pengganti, dan pengaturan ini akan menambah konsistensi pada model data saya. Biaya 'menambahkan' kunci pengganti minimal.
Pembaruan berdasarkan pada beberapa komentar:
Tanpa mengetahui konteks dari tabel contoh, tidak mungkin untuk mengetahui seberapa penting hal-hal seperti IATA Airport Codes bagi aplikasi menggunakan database. Jelas, jika kode IATA sangat penting bagi pusat dan digunakan secara luas di seluruh aplikasi, mungkin merupakan keputusan yang tepat, setelah analisis yang tepat, untuk menggunakan kode sebagai PK tabel.
Namun, jika tabel tersebut hanyalah tabel pencarian yang digunakan di beberapa sudut aplikasi, kepentingan relatif dari kode IATA mungkin tidak membenarkan tempat yang menonjol dalam infrastruktur database. Tentu, Anda mungkin harus membuat tambahan bergabung dalam beberapa pertanyaan di sana-sini, tetapi upaya itu mungkin sepele dibandingkan dengan upaya yang diperlukan untuk melakukan penelitian untuk memastikan bahwa Anda sepenuhnya memahami implikasi membuat kode IATA sebagai bidang kunci utama. Dalam beberapa kasus, saya tidak hanya tidak peduli, tetapi saya tidak mau harus peduli dengan kode IATA. @James Snell berkomentar di bawah ini adalah contoh sempurna dari sesuatu yang saya mungkin tidak ingin khawatir tentang mempengaruhi PK dari tabel saya.
Selain itu, konsistensi dalam desain juga penting. Jika Anda memiliki database dengan lusinan tabel yang semuanya telah secara konsisten merancang kunci pengganti, dan kemudian beberapa tabel pencarian yang menggunakan kode pihak ketiga sebagai PK, yang memperkenalkan inkonsistensi. Itu sama sekali tidak buruk, tetapi membutuhkan perhatian ekstra dalam dokumentasi dan semacamnya yang mungkin tidak diperlukan. Mereka mencari tabel demi kebaikan, hanya menggunakan kunci pengganti untuk konsistensi baik-baik saja.
Pembaruan berdasarkan penelitian lebih lanjut:
Ok, rasa ingin tahu menggigit saya dan saya memutuskan untuk melakukan penelitian pada kode bandara IATA untuk bersenang-senang, dimulai dengan tautan yang disediakan dalam pertanyaan.
Ternyata, kode IATA tidak seuniversal dan otoritatif seperti yang ditanyakan oleh mereka. Menurut halaman ini :
Selain itu, kode IATA dan kode ICAO berbeda dari kode Pengidentifikasi FAA , yang merupakan cara lain untuk mengidentifikasi lapangan udara.
Maksud saya dalam mengemukakan ini bukanlah untuk memulai perdebatan tentang kode mana yang lebih baik atau lebih universal atau lebih otoritatif atau lebih komprehensif, tetapi untuk menunjukkan dengan tepat mengapa mendesain struktur basis data Anda di sekitar pengidentifikasi pihak ke-3 yang sewenang-wenang bukanlah sesuatu yang akan saya pilih untuk dilakukan , kecuali ada alasan bisnis khusus untuk melakukannya .
Dalam hal ini, saya merasa database saya akan lebih terstruktur, lebih stabil, dan lebih fleksibel, dengan melepaskan kode IATA (atau pihak ke-3, kode yang berpotensi berubah) sebagai kandidat kunci utama dan menggunakan kunci pengganti. Dengan melakukan itu, saya dapat melupakan setiap jebakan potensial yang mungkin muncul karena pemilihan kunci utama.
sumber
select * from baggage where airport_code = 'LHR'
, artinya database hanya dapat digunakan untuk membuang aplikasi, yang sangat sempit dan eksklusif. pendekatan, khususnya ketika pemilik bisnis adalah orang yang membayar untuk database, dan oleh karena itu memilikinya. Anda juga harus menulis kode untuk melakukan hal-hal biasa seperti mengimpor data dari satu database ke yang lain untuk menghindari tabrakan PK.Meskipun memiliki kunci pengganti di bidang baik-baik saja dan tidak ada yang salah dengan sesuatu yang perlu dipertimbangkan mungkin ukuran halaman indeks itu sendiri.
Karena ini adalah basis data relasional, Anda akan melakukan banyak penggabungan dan memiliki kunci pengganti dari tipe numerik mungkin membuatnya lebih mudah pada basis data untuk ditangani yaitu ukuran halaman indeks akan lebih kecil dan dengan demikian lebih cepat untuk mencari melalui. Jika ini adalah proyek kecil, itu tidak masalah dan Anda akan bertahan tanpa masalah, namun semakin besar aplikasi semakin Anda ingin mengurangi kemacetan.
Memiliki BIGINT, INT, SMALLINT, TINYINT atau tipe data bilangan bulat apa pun dapat menyelamatkan Anda dari masalah.
Hanya 2 sen saya
MEMPERBARUI:
Proyek kecil - digunakan oleh beberapa, bahkan mungkin beberapa lusin orang. Skala kecil, proyek demo, proyek untuk penggunaan pribadi, sesuatu untuk ditambahkan ke portofolio ketika menyajikan keahlian Anda tanpa pengalaman, dan sejenisnya.
Proyek besar - digunakan oleh ribuan, puluhan ribu, jutaan pengguna setiap hari. Sesuatu yang Anda bangun untuk perusahaan nasional / internasional dengan basis pengguna yang besar.
Biasanya yang terjadi adalah beberapa catatan terpilih sering dipilih, dan server menyimpan hasil untuk akses cepat, tetapi setiap sekarang dan kemudian Anda perlu mengakses beberapa catatan yang kurang digunakan, pada titik mana server harus memasukkan ke dalam indeks halaman. (dalam contoh di atas dengan nama bandara, orang sering menerbangkan maskapai domestik, katakanlah Chichago -> Los Angeles, tetapi seberapa sering orang terbang dari Boston -> Zimbabwe)
Jika VARCHAR digunakan itu berarti spasi tidak seragam, kecuali data selalu panjang yang sama (pada titik mana nilai CHAR lebih efektif). Ini membuat pencarian indeks lebih lambat, dan dengan server sudah sibuk menangani ribuan dan ribuan pertanyaan per detik sekarang ia harus membuang waktu melalui indeks yang tidak seragam, dan melakukan hal yang sama lagi pada gabungan (yang lebih lambat daripada pilih reguler pada tabel yang tidak dioptimalkan, ambil DW sebagai contoh di mana ada sesedikit mungkin gabungan untuk mempercepat pengambilan data). Juga jika Anda menggunakan UTF yang dapat mengacaukan mesin database juga (saya telah melihat beberapa kasus).
Secara pribadi, dari pengalaman saya sendiri, indeks yang terorganisir dengan benar dapat meningkatkan kecepatan bergabung dengan ~ 70%, dan melakukan bergabung pada kolom integer dapat mempercepat bergabung dengan sebanyak ~ 25% (tergantung pada data) . Ketika tabel-tabel utama mulai tumbuh dan tabel-tabel ini digunakan padanya, apakah Anda lebih suka datatype integer menempati kolom yang memiliki beberapa byte vs memiliki bidang VARCHAR / CHAR yang akan menempati lebih banyak ruang. Itu datang untuk menghemat ruang disk, meningkatkan kinerja dan struktur keseluruhan dari database relasional.
Juga, seperti yang disebutkan James Snell:
Jadi dengan mempertimbangkan hal ini, apakah Anda lebih suka memperbarui 1 catatan yang terikat ke angka, vs harus memperbarui satu catatan itu ditambah semua catatan dalam tabel tempat Anda bergabung.
sumber
small project
danbigger
perbarui untuk menjelaskan mengapa itu penting.Jika Anda mengambil pendekatan "Saya menggunakan kunci pengganti sepanjang waktu", Anda bisa mem-bypass jenis kekhawatiran ini. Itu mungkin bukan hal yang baik karena penting untuk memberikan data Anda beberapa pemikiran, tetapi tentu saja menghemat banyak waktu, tenaga dan usaha. Jika ada orang yang menyetujui konsepsi ini, contoh-contoh yang tercantum tentu memenuhi syarat karena dibutuhkan "tindakan kongres" yang dekat untuk melakukan perubahan.
Permintaan ad hoc dari database dengan kunci alami ini tentu sangat membantu. Membuat tampilan yang melakukan hal yang sama dengan memasukkan tabel pencarian dapat bekerja dengan baik. Database modern melakukan pekerjaan yang jauh lebih baik dengan jenis barang ini sampai pada titik di mana mungkin tidak masalah.
Ada beberapa kasus khusus untuk AS, di mana standar diubah secara drastis: Kode pos diperluas dari 5 - 9 digit, singkatan Negara menjadi 2 huruf yang konsisten dan menghilangkan periode (Ingat ketika Illinois sedang sakit?), Dan sebagian besar dunia harus berurusan dengan Y2K. Jika Anda memiliki aplikasi waktu nyata dengan data yang tersebar di seluruh dunia yang berisi milyaran catatan, pembaruan berjenjang bukanlah ide terbaik, tetapi bukankah kita semua bekerja di tempat yang menghadapi tantangan seperti itu? Dengan dataset itu, Anda dapat mengujinya sendiri dan memberikan jawaban yang lebih difinitif.
sumber