Apakah tabel khusus ini memerlukan kunci pengganti?

13

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.

masukkan deskripsi gambar di sini

country_code adalah kode negara standar ISO 3166-1 A3 , Anda dapat melihatnya di olimpiade.

masukkan deskripsi gambar di sini

currency_code adalah kode mata uang 3-karakter standar IS0 417 , Anda dapat melihatnya di papan layar pertukaran mata uang internasional.

masukkan deskripsi gambar di sini

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?

Tulains Córdova
sumber

Jawaban:

15

Tidak, mereka tidak. Kunci-kunci itu pasti cukup bagus!

Mereka unik, tidak jarang akan berubah, dan bermakna , yang merupakan langkah lebih dari kunci pengganti. Itu cukup banyak definisi dari PK yang baik.

Pembatasan tentang PK yang tidak dapat diubah dan bilangan bulat bukan bagian dari Model Relasional (Codd) atau standar SQL apa pun (ANSI atau lainnya).

Bobson
sumber
3
Kunci primer juga harus tidak berubah, sesuatu yang kode bandara IATA jelas tidak. Mereka dapat diubah atas kehendak IATA.
James Snell
3
@JamesSnell - Kode bandara IATA hampir tidak berubah seperti kode negara. Anda sedang berbicara tentang perubahan mungkin sekali setiap dekade, jika itu. Lihat di sini untuk diskusi tentang masalah ini. Ada banyak kode usang yang masih ada karena terlalu banyak kesulitan untuk diubah. Selain itu, untuk itulah pembaruan CASCADE dibuat. Kunci primer yang bisa berubah-ubah adalah sah, jika bukan praktik yang bagus.
Bobson
2
@EricKing Pihak ke-3 ini, kebetulan terdiri dari perwakilan dari semua pihak utama di banyak industri, kemudian standar dibahas selama bertahun-tahun, kemudian memberikan suara hingga konsensus yang wajar telah tercapai. Mereka juga menyetujui mekanisme yang melaluinya perubahan atau penambahan baru dilakukan. Selain itu, daftar kode standar dibuat, bukan atas keinginan, tetapi karena ada kebutuhan untuk membuat daftar kode yang dikontrol, dihormati, disepakati untuk sesuatu, agar dapat beroperasi di seluruh dunia dan berkomunikasi dengan baik di seluruh dunia.
Tulains Córdova
2
@ user61852 - Bisa dibilang standar ini dibuat menjadi kunci utama.
Bobson
3
@ Bobson: "Ada banyak kode usang yang masih ada karena terlalu banyak kesulitan untuk diubah" -> mungkin karena mereka adalah kunci utama?
Maciej
2

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:

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_id       int (PK)|  |country_id     int (PK) |
|iata_airport_code string |  |iso_country_code string |
|icao_airport_code string |  +------------------------+
|faa_identifier    string |  
|address           string |  
|name              string |  
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_id int (PK)     |
|iso_currency_code string |
|name string              |
+-------------------------+

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 :

Sebagian besar negara menggunakan kode ICAO empat karakter , bukan kode IATA, dalam publikasi aeronautika resmi mereka.

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.

Eric King
sumber
1
Jadi standar IATA cukup baik untuk maskapai tetapi tidak untuk Anda?
Tulains Córdova
1
Tentu saja Anda harus bergabung jauh-jauh ke meja bandara ketika Anda ingin mencari bagasi dari London Heathrow, karena Anda tidak dapat melakukannya 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.
Tulains Córdova
1
Kode IATA tidak dapat diubah sehingga tidak dapat dianggap sebagai kandidat PK. Contoh: kode IDL berada di New York, sampai namanya diganti JFK. Kode IDL sekarang di Mississippi.
James Snell
2
@EricKing IATA dan ISO peduli tentang kode yang cukup stabil, unik dan diterima secara universal. Itu bertepatan banyak dengan minat seseorang mendesain meja.
Tulains Córdova
2
@ user61852 - hanya karena ini adalah kode standar tidak berarti sistem maskapai menggunakannya sebagai PK (mungkin Anda memiliki wawasan lebih lanjut di sini?). Memiliki pembaruan berjenjang pada skala besar seperti itu sepertinya ide yang sangat buruk.
JeffO
1

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:

Kunci primer juga harus tidak berubah, sesuatu yang kode bandara IATA jelas tidak. Mereka dapat diubah atas kehendak IATA.

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.

Toni Kostelac
sumber
Itu pemikiran yang valid, tetapi inti dari tabel ini adalah bahwa hanya ada jumlah catatan yang terbatas di setiap tabel. Jika Anda benar-benar memaksudkan ukuran kode , small projectdan biggerperbarui untuk menjelaskan mengapa itu penting.
Bobson
1
Pembatasan tentang PK tidak dapat diubah dan numerik-bilangan bulat bukan bagian dari Model Relasional (Codd) atau standar SQL apa pun (ANSI atau lainnya).
Tulains Córdova
4
Indeks berdasarkan panjang tetap, string pendek (seperti kode ISO) secepat integer. Indeks berdasarkan panjang variabel, string panjang tidak.
Tulains Córdova
Itulah yang saya nyatakan (lihat bagian VARCHAR vs CHAR di atas) saya belum punya kesempatan untuk menguji string pendek panjang tetap vs bilangan bulat numerik tapi saya punya kesempatan untuk melakukannya dengan panjang variabel dan integer
Toni Kostelac
2
Bergabung dengan kinerja adalah pria jerami. Seringkali, menggunakan kunci alami berarti Anda tidak perlu bergabung di tempat pertama.
Mike Sherrill 'Cat Recall'
1

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.

JeffO
sumber
+1 Jawaban bagus. Sebagian besar orang sangat dogmatis dalam masalah ini. Banyak perancang basis data memiliki ego raksasa dan menganggap diri mereka sebagai pemilik basis data dan data. Yang lain melihat OK bahwa pemilik data hanya dapat menggunakannya melalui aplikasi tertentu, karena ia tidak dapat memahaminya. Mereka juga lebih suka membuat ketentuan untuk sesuatu yang mungkin atau mungkin tidak terjadi di masa depan sambil membuat neraka hidup hal-hal yang dilakukan dalam basis harian seperti mengimpor data dan menulis kueri. Juga gagal menghasilkan segala jenis bibliografi kanonik yang mendukung pandangan mereka.
Tulains Córdova
By the way, aturan "Saya menggunakan kunci pengganti sepanjang waktu" tidak dalam Model Relasional (Codd) atau standar SQL. Skema kamus data Oracle menggunakan kunci alami bila memungkinkan dan kunci buatan dalam hal lain. PPDM ( ppdm.org ) juga merekomendasikan pendekatan campuran dan menggunakannya dalam modelnya. ANSI SQL Standard tidak mengatakan apa-apa tentang semua-pengganti. Saya pikir semua pengganti dan semua alami korosif. Beberapa alami dan beberapa pengganti adalah apa yang diajarkan model relasional.
Tulains Córdova