Cara benar membuat kunci primer komposit - MYSQL


182

Ini adalah penyederhanaan berlebihan dari pengaturan yang intens yang saya kerjakan. table_1dan table_2keduanya memiliki kunci primer pengganti auto-increment sebagai ID. infoadalah tabel yang berisi informasi tentang keduanya table_1dan table_2.

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

Saya mencoba memutuskan apakah saya harus membuat kunci utama infogabungan ID dari table_1dan table_2. Jika saya melakukan ini, manakah di antara ini yang paling masuk akal?
(dalam contoh ini saya menggabungkan ID 11209 dengan ID 437)

INT(9)11209437 (saya bisa membayangkan mengapa ini buruk)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

Atau sesuatu yang lain?

Apakah ini baik-baik saja untuk menggunakan ini sebagai Kunci Utama pada MYSQL MYISAM DB?


Jawaban:


343

Saya akan menggunakan kunci komposit (multi-kolom).

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

Dengan cara ini Anda dapat memiliki t1ID dan t2ID sebagai kunci asing yang menunjuk ke tabel masing-masing juga.


2
Oh wow begitu ITULAH bagaimana Anda membuat kunci komposit! Sepertinya saya sudah benar-benar salah paham konsep. Terima kasih!! Jadi sesuatu seperti ini sepenuhnya untuk keperluan pengindeksan lalu benar? Seperti pada saya tidak akan dapat merujuk catatan dengan menggunakan komposit ini, saya masih harus melakukannya UPDATE info ... WHERE t1ID=11209 AND t2ID=437?
filip

2
benar. Meskipun karena kedua kolom harus unik, di mana t1ID = 11209 mungkin akan cukup.
AlexCuse

39
@AlexCuse kombinasi kedua kolom adalah unik, tetapi untuk t1ID = 11209 mungkin ada sejumlah t2IDs.
e18r

21

Saya tidak akan membuat kunci utama tabel "info" sebagai gabungan dari dua nilai dari tabel lain.

Yang lain dapat mengartikulasikan alasan dengan lebih baik, tetapi rasanya salah memiliki kolom yang terdiri dari dua bagian informasi. Bagaimana jika Anda ingin mengurutkan ID dari tabel kedua karena beberapa alasan? Bagaimana jika Anda ingin menghitung berapa kali nilai dari salah satu tabel hadir?

Saya akan selalu menyimpan ini sebagai dua kolom berbeda. Anda dapat menggunakan kunci utama dua kolom di mysql ... KUNCI UTAMA (id_a, id_b) ... tapi saya lebih suka menggunakan indeks unik dua kolom, dan memiliki bidang kunci primer kenaikan otomatis.


1
Anda benar tentang menjaga kolom yang berbeda. Saya tidak menyadari bahwa Anda dapat memiliki indeks unik dua kolom dan saya pikir itu mungkin pilihan yang baik bagi saya. Bisakah saya bertanya mengapa Anda masih lebih memilih untuk menjaga Kunci Primer sebagai peningkatan otomatis?
filip

3
Saya tidak punya alasan yang kuat, dan saya mengakui ini adalah titik pertikaian antara saya dan beberapa rekan saya, karena lebih ekonomis memiliki kolom yang lebih sedikit. Saya merasa lebih mudah untuk menulis gabungan pada satu kunci asing. Kadang-kadang pentingnya tabel ini "Pemetaan antara dua tabel" menjadi sama pentingnya dengan tabel asli, dan kunci primernya menjadi kolom kunci asing di tabel lain.
buruk

Terima kasih. Saya pikir apa yang Anda katakan sangat masuk akal dan saya akan mencobanya sebagai indeks unik dua kolom + kunci primer kenaikan otomatis
filip

1
Saya kira alasan dari atas kepala saya adalah bahwa Anda ingin membuat tabel hubungan. Anda memiliki tiga tabel, katakanlah pasar tempat, mata uang dan penyedia, penyedia HANYA bisa ada di pasar tempat SEKALI, sehingga tabel hubungan Anda hanya dapat memberikan mata uang tunggal, sehingga Anda akan komposit (id_market, id_provider) yang berarti Anda hanya dapat membuat koneksi itu sekali, mencoba menambahkan lagi pasar dan penyedia yang sama bersama-sama akan gagal, yang berarti mereka unik, maka Anda akan memiliki kolom kedua, katakanlah id_currency, artinya mata uang itu tunggal di seluruh tabel, apakah itu masuk akal?
Christopher Thomas

1
Bagi siapa pun yang melihat utas ini nanti, harap perhatikan bahwa alasan ini adalah praktik yang buruk adalah karena melanggar prinsip desain database yang sangat dasar. Formulir Normal 1 mengharuskan setiap informasi memiliki kolomnya sendiri. Hampir tidak ada alasan untuk melanggar ini dan banyak manfaat untuk menormalkan struktur database Anda.
smcjones

15

sintaksnya CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)misalnya ::

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

contoh di atas akan berfungsi jika Anda menulisnya saat Anda membuat tabel misalnya:

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

untuk menambahkan batasan ini ke tabel yang sudah ada, Anda harus mengikuti sintaks berikut

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)

8

Misalkan Anda telah membuat tabel sekarang Anda dapat menggunakan kueri ini untuk membuat kunci primer komposit

alter table employee add primary key(emp_id,emp_name);

5

Selain preferensi desain pribadi, ada beberapa kasus di mana seseorang ingin menggunakan kunci primer komposit. Tabel mungkin memiliki dua atau lebih bidang yang memberikan kombinasi unik, dan tidak harus dengan kunci asing.

Sebagai contoh, setiap negara bagian AS memiliki satu set distrik Kongres yang unik. Sementara banyak negara bagian secara individual memiliki CD-5, tidak akan pernah ada lebih dari satu CD-5 di 50 negara bagian, dan sebaliknya. Oleh karena itu, membuat bidang autonumber untuk Massachusetts CD-5 akan menjadi berlebihan.

Jika database menggerakkan halaman web yang dinamis, menulis kode ke kueri pada kombinasi dua bidang bisa jauh lebih sederhana daripada mengekstraksi / mengirim ulang kunci autonumbered.

Jadi, sementara saya tidak menjawab pertanyaan awal, saya tentu menghargai jawaban langsung Adam.


4

Kunci primer gabungan adalah apa yang Anda inginkan di mana Anda ingin membuat hubungan banyak ke banyak dengan tabel fakta. Misalnya, Anda mungkin memiliki paket sewa liburan yang menyertakan sejumlah properti di dalamnya. Di sisi lain, properti juga dapat tersedia sebagai bagian dari sejumlah paket sewa, baik sendiri atau dengan properti lainnya. Dalam skenario ini, Anda membangun hubungan antara properti dan paket sewa dengan tabel fakta properti / paket. Hubungan antara properti dan paket akan unik, Anda hanya akan bergabung menggunakan property_id dengan tabel properti dan / atau package_id dengan tabel paket. Setiap hubungan unik dan kunci auto_increment redundan karena tidak akan ditampilkan di tabel lain. Oleh karena itu mendefinisikan kunci komposit adalah jawabannya.


1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);

1

@AlexCuse Saya ingin menambahkan ini sebagai komentar untuk jawaban Anda tetapi menyerah setelah beberapa kali gagal mencoba menambahkan baris baru dalam komentar.

Yang mengatakan, t1ID unik di table_1 tapi itu tidak membuatnya unik di tabel INFO juga.

Sebagai contoh:

Table_1 memiliki:
Id Field
1 A
2 B

Table_2 memiliki:
Id Field
1 X
2 Y

INFO kemudian dapat memiliki:
t1ID t2ID bidang
1 1 beberapa
1 2 data
2 1 masing-masing
2 2 baris

Jadi dalam tabel INFO untuk mengidentifikasi baris secara unik Anda membutuhkan t1ID dan t2ID


yang disebut kunci komposit
Pavel P

1
@PavelP balasan saya adalah komentar Alex "Meskipun karena kedua kolom harus unik, di mana t1ID = 11209 mungkin akan cukup." ... Saya setuju bahwa menggunakan kunci komposit sudah benar tetapi untuk mengidentifikasi kecocokan yang tepat Anda akan membutuhkan t1ID dan t2ID ... Saya harap sudah jelas sekarang.
sactiw
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.