Disambiguasi kolom/kendala kunci asing
Dengan asumsi Anda mengacu pada batasan kunci asing , jawaban singkatnya adalah Anda hanya tidak menggunakannya .
Dan inilah yang panjang:
Kami terbiasa menyebut kolom sebagai kunci asing ke tabel lainnya. Terutama selama proses normalisasi, frasa seperti "user_purchase.i_id
adalah kunci asing untuk items
meja" akan sangat umum. Meskipun itu cara yang benar-benar valid untuk menggambarkan hubungan, itu bisa menjadi sedikit kabur saat kita mencapai tahap implementasi.
Misalkan Anda telah membuat tabel Anda tanpa FOREIGN KEY
klausa:
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
);
Perhatikan bahwa, dari segi relasi, kunci asing kolom masih diterapkan . Ada kolom yang mereferensikan user
tabel (id
) dan satu lagi yang mereferensikan items
tabel (i_id
) -- mari kita beri name
kolom ke samping sejenak. Perhatikan data berikut:
user user_purchase items
| id username | | id i_id | | i_id name price |
| 23 john | | 55 10 | | 10 chocolate bar 3.42 |
| 55 mary | | 70 10 | | 33 mobile phone 82.11 |
| 70 fred | | 70 33 | | 54 toothpaste 8.67 |
| 55 10 | | 26 toy car 6.00 |
| 70 26 |
Relasinya ada. Ini diimplementasikan melalui user_purchase
tabel, yang menyimpan informasi tentang siapa membeli apa . Jika kami meminta database untuk laporan yang relevan, kami akan melakukan:
select * from user_purchase p
join user u on (p.id=u.id)
join items i on (p.i_id=i.i_id)
Dan begitulah cara kami menggunakan relasi dan kunci asing kolom terlibat.
Sekarang, bagaimana jika kita melakukannya:
insert into user_purchase (id,i_id) values (23,99)
Rupanya, ini adalah entri yang tidak valid. Meskipun ada pengguna dengan id=23
, tidak ada item dengan i_id=99
. RDBMS akan membiarkan hal itu terjadi, karena tidak ada yang tahu lebih baik . Belum.
Di situlah kunci asing batasan ikut bermain. Dengan menentukan FOREIGN KEY (i_id) REFERENCES items(i_id)
di user_purchase
definisi tabel, kami pada dasarnya memberikan RDBMS aturan untuk diikuti:entri dengan i_id
nilai yang tidak terkandung dalam items.i_id
kolom tidak dapat diterima . Dengan kata lain, sementara kunci asing kolom mengimplementasikan referensi , kunci asing batasan menegakkan integritas referensial .
Namun, perhatikan bahwa select
di atas tidak akan berubah, hanya karena Anda mendefinisikan batasan FK. Jadi, Anda jangan gunakan batasan FK, RDBMS melakukannya, untuk melindungi data Anda.
Redundansi
Tanyakan pada diri sendiri:Mengapa Anda menginginkan itu? Jika dua kunci asing memiliki tujuan yang sama, redundansi pada akhirnya akan membuat Anda dalam masalah. Perhatikan data berikut:
user_purchase items
| id i_id name | | i_id name price |
| 55 10 chocolate bar | | 10 chocolate bar 3.42 |
| 70 10 chocolate bar | | 33 mobile phone 82.11 |
| 70 33 mobile phone | | 54 toothpaste 8.67 |
| 55 10 toothpaste | | 26 toy car 6.00 |
| 70 26 toy car |
Apa yang salah dengan gambar ini? Apakah pengguna 55
membeli dua batang cokelat, atau sebatang cokelat dan pasta gigi? Ambiguitas semacam ini dapat menyebabkan banyak upaya untuk menjaga agar data tetap sinkron, yang tidak diperlukan jika kita hanya menyimpan salah satu kunci asing. Faktanya, mengapa tidak membuang name
kolom sama sekali, karena tersirat oleh relasi.
Tentu saja, kita dapat mengatasi ini dengan menerapkan kunci asing komposit, dengan menyetel PRIMARY KEY(i_id,name)
untuk items
tabel (atau mendefinisikan UNIQUE(i_id,name)
indeks, itu tidak terlalu penting) dan kemudian mengatur FOREIGN KEY(i_id,name) REFERENCES items(i_id,name)
. Dengan cara ini, hanya pasangan (i_id,nama) yang ada di items
tabel akan valid untuk user_purchase
. Terlepas dari kenyataan bahwa Anda masih akan memiliki satu kunci asing , pendekatan ini sama sekali tidak perlu, asalkan i_id
kolom sudah cukup untuk mengidentifikasi item (tidak bisa mengatakan hal yang sama untuk name
kolom...).
Namun, tidak ada aturan yang melarang penggunaan beberapa kunci asing ke sebuah tabel. Faktanya, ada keadaan yang menuntut pendekatan seperti itu. Pertimbangkan person(id,name)
tabel dan parent(person,father,mother)
satu, dengan data berikut:
person parent
| id name | | person father mother |
| 14 John | | 21 14 59 |
| 43 Jane | | 14 76 43 |
| 21 Mike |
| 76 Frank |
| 59 Mary |
Jelas, ketiga kolom parent
tabel adalah kunci asing untuk person
. Tidak untuk relasi yang sama , meskipun, tetapi untuk tiga yang berbeda :Karena orang tua seseorang juga orang, dua kolom yang sesuai harus merujuk ke tabel yang sama person
melakukan. Namun, perhatikan bahwa ketiga bidang tidak hanya dapat tapi juga harus rujuk person
yang berbeda s dalam parent
yang sama baris, karena tidak ada orang tua sendiri dan ayah tidak ada ibunya juga.