Kompozit birincil anahtar eklemek için ALTER TABLE


195

Adlı bir masam var provider . Aradım üç sütun var person, place, thing. Yinelenen kişiler, yinelenen yerler ve yinelenen şeyler olabilir, ancak asla yinelenen bir kişi-yer-şey kombinasyonu olamaz.

Bu üç sütunu kullanarak MySQL'deki bu tabloya bileşik birincil anahtar eklemek için NASIL TABLO ALABİLİRİM?

Yanıtlar:


426
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

Birincil anahtar zaten varsa bunu yapmak istersiniz

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);

17
@ David542 Hayır, yok - sadece 1 birincil anahtarınız olabilir.
Adrian Cornish

35
@David: Bileşik bir anahtar olarak adlandırılan birden çok alandan oluşan tek bir birincil anahtardır.
Marc B

3
@ David542 Tabii ki yapabilirsiniz - bu 3 alandan oluşan bileşik bir birincil anahtardır. 3 alanın kombinasyonu benzersiz olmalıdır.
Adrian Cornish


1
SO :) en değerli cevaplardan biri :)
alwbtc

21

@ Adrian Cornish'in cevabı doğru. Ancak, mevcut bir birincil anahtarı atmak için başka bir uyarı daha var. Birincil anahtar başka bir tablo tarafından yabancı anahtar olarak kullanılıyorsa, bırakmaya çalışırken bir hata alırsınız. MySQL'in bazı sürümlerinde hata iletisi hatalı biçimlendirildi (5.5.17 itibariyle bu hata iletisi hala

alter table parent  drop column id;
ERROR 1025 (HY000): Error on rename of
'./test/#sql-a04_b' to './test/parent' (errno: 150).

Başka bir tablo tarafından başvurulan bir birincil anahtarı bırakmak istiyorsanız, önce yabancı anahtarı o tabloya bırakmanız gerekir. Birincil anahtarı yeniden oluşturduktan sonra hala isterseniz, bu yabancı anahtarı yeniden oluşturabilirsiniz.

Ayrıca, bileşik anahtarlar kullanılırken sıra önemlidir. Bunlar

1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
and
2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place);

aynı şey değil. Her ikisi de bu üç alan kümesi üzerinde benzersizliği zorunlu kılar, ancak bir indeksleme açısından bir fark vardır. Alanlar soldan sağa dizine eklenir. Örneğin, aşağıdaki sorguları göz önünde bulundurun:

A) SELECT person, place, thing FROM provider WHERE person = 'foo' AND thing = 'bar';
B) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz';
C) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz' AND thing = 'bar';
D) SELECT person, place, thing FROM provider WHERE place = 'baz' AND thing = 'bar';

B, ALTER deyiminde
birincil anahtar dizini kullanabilir 1 A ALTER deyimi 2'de birincil anahtar dizinini
kullanabilir C her iki dizini kullanabilir
D her iki dizini kullanamaz

A, dizin 2'deki ilk iki alanı kısmi dizin olarak kullanır. A, dizin 1'i kullanamaz çünkü dizinin ara yeri bölümünü bilmez. Yine de, sadece kişi üzerinde kısmi bir dizin kullanabilir.

D kişiyi tanımıyor çünkü her iki endeksi kullanamazsınız.

MySQL dokümanlar bakın burada daha fazla bilgi için.


@All - Aynı için JPA eşdeğerini paylaşabilir misiniz?
Pra_A

17

Sadece BENZERSİZ BİR KISIT isteyebilirsiniz. Özellikle zaten bir yedek anahtarınız varsa. (zaten var olan bir yedek anahtar örneği, AUTO_INCREMENT olan tek bir sütun olabilir)

Aşağıda, Benzersiz Bir Kısıtlama için sql kodu verilmiştir.

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;

Teşekkür ederim, bir kısıtlama istediğim şeydi, bu ilk yazıda ne isteyeceğimi bilmiyordum. Bunu konuya eklediğiniz için teşekkürler.
ZaneDarken

Ben tipik olarak bir yedek anahtar kullanın ...... sonra benzersiz bir kısıtlama ekleyin. Bu şekilde .... "teklik" yolda değişirse, kısıtlamayı değiştirmek, birincil anahtarla uğraşmak gibi bir dram değildir. Ve yabancı anahtarın bu tabloya gönderme yaptığı alt tablolarınız varsa, 3 sütunun tümünü değil, yalnızca yedek anahtarı FK olarak oluşturmanız gerekir. -
granadaCoder


1

@GranadaCoder tarafından sunulan KOMPOZİT BENZERSİZ ANAHTAR'ı kullanmak kesinlikle daha iyidir, ancak biraz zor bir örnek olsa da:

ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);


0

ALTER TABLE table_name DROP PRIMARY KEY,ADD PRIMARY KEY (col_name1, col_name2);

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.