Bileşik birincil anahtarlar doğru şekilde nasıl oluşturulur - MYSQL


182

İşte birlikte çalıştığım yoğun bir kurulumun kaba bir şekilde basitleştirilmesi. table_1ve table_2her ikisinde de kimlik olarak otomatik artan yedek birincil anahtarlar bulunur. infohem table_1ve hakkında bilgi içeren bir tablodur table_2.

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

Ben birincil anahtar yapmanız gerekip gerekmediğine karar çalışıyorum infogelen kimlikleri kompozit table_1ve table_2. Bunu yapacak olsaydım, bunlardan hangisi en anlamlı?
(bu örnekte ID 11209 ile ID 437'yi birleştiriyorum)

INT(9)11209437 (bunun neden kötü olduğunu hayal edebiliyorum)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

Veya başka bir şey?

Bu bir MYSQL MYISAM DB birincil anahtar olarak kullanmak için iyi olur mu?


Yanıtlar:


344

Bileşik (çok sütunlu) bir anahtar kullanırdım.

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

Bu şekilde t1ID ve t2ID değerlerini ilgili tablolara da işaret eden yabancı anahtarlar olarak kullanabilirsiniz.


2
Oh vay bu yüzden bir kompozit anahtar nasıl yapılır! sanırım konsepti tamamen yanlış anlıyorum. Teşekkür ederim!! Yani böyle bir şey tamamen indeksleme amaçlı o zaman doğru mu? Bu kompoziti kullanarak bir kayda başvuramayacağım gibi, yine de bir UPDATE info ... WHERE t1ID=11209 AND t2ID=437?
filip

2
doğru. Her iki sütun da benzersiz olması gerektiğinden, t1ID = 11209 muhtemelen yeterli olacaktır.
AlexCuse

39
Her iki sütunun birleşimi benzersizdir, ancak t1ID = 11209 için herhangi bir sayıda t2ID olabilir.
e18r

21

Ben "bilgi" tablosunun birincil anahtar diğer tablolardan iki değer bir bileşik yapmak olmaz.

Diğerleri nedenleri daha iyi ifade edebilir, ancak gerçekten iki bilgi parçasından oluşan bir sütuna sahip olmak yanlış hisseder. Herhangi bir nedenle ikinci tablodaki kimliğe göre sıralamak isterseniz ne olur? Her iki tablodan bir değerin kaç kez bulunduğunu saymak isterseniz ne olur?

Bunları her zaman iki ayrı sütun olarak tutardım. Mysql iki sütunlu primay anahtar kullanabilirsiniz ... PRIMARY KEY (id_a, id_b) ... ama ben iki sütunlu benzersiz bir dizin kullanmayı ve bir otomatik artış birincil anahtar alanı olan tercih ederim.


1
Farklı sütunları tutmak konusunda kesinlikle haklısınız. İki sütunlu benzersiz bir dizine sahip olabileceğinizin farkında değildim ve bence bu benim için iyi bir seçenek olabilir. Yine de neden Birincil Anahtarı otomatik artış olarak tutmayı tercih edeceğinizi sorabilir miyim?
filip

3
Gerçekten zorlayıcı nedenlerim yok ve bunun benim ve meslektaşlarım arasındaki bir tartışma noktası olduğuna inanıyorum, çünkü daha az sütuna sahip olmak daha ekonomik. Tek bir yabancı anahtar üzerine birleştirme yazmayı daha kolay buluyorum. Bazen bu tabloların önemi "İki tablo arasındaki eşlemeler" orijinal tablolar kadar önemli hale gelir ve birincil anahtarı diğer tablolarda yabancı anahtar sütunu haline gelir.
wmorse

teşekkür ederim. Söylediklerinin çok mantıklı olduğunu düşünüyorum ve iki sütunlu benzersiz bir dizin + otomatik artış birincil anahtar olarak deneyeceğim
filip

1
Sanırım başımın üstünden bir ilişki tablosu oluşturmak istiyorsun. pazar yeri, para birimi ve sağlayıcı diyelim, bir sağlayıcı YALNIZCA bir pazar yerinde bulunabilir, bu nedenle ilişki tablonuz sadece tek bir para birimi sağlayabilir, böylece kompozit (id_market, id_provider) Bu bağlantı bir kez, aynı pazarı ve sağlayıcıyı tekrar eklemeye çalışmak başarısız olur, yani benzersizdir, o zaman id_currency, yani para biriminin tüm tablodaki tekil olduğu anlamına gelen ikinci bir sütununuz olur mu?
Christopher Thomas

1
Bu konuyu daha sonra gören herkes için, bunun kötü uygulama olmasının nedeni, veritabanı tasarımının çok temel bir prensibini ihlal etmesidir. 1. Normal Form, her bilgi parçasının kendi sütununa sahip olmasını gerektirir. Bunu ihlal etmek için neredeyse hiçbir neden yoktur ve veritabanı yapınızı normalleştirmenin birçok faydası vardır.
smcjones

15

sözdizimi CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)örneğin:

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

yukarıdaki örnek tablo oluştururken yazıyorsanız işe yarar örneğin:

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

bu kısıtlamayı mevcut bir tabloya eklemek için aşağıdaki sözdizimini izlemeniz gerekir

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

8

Zaten bir tablo oluşturduğunuzu varsayalım, şimdi birleşik birincil anahtar yapmak için bu sorguyu kullanabilirsiniz

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

5

Kişisel tasarım tercihlerinin yanı sıra, bileşik birincil anahtarları kullanmak istediği durumlar da vardır. Tablolar, benzersiz bir kombinasyon sağlayan iki veya daha fazla alana sahip olabilir ve yabancı anahtarlarla zorunlu olmayabilir.

Örnek olarak, her ABD eyaletinde bir dizi benzersiz Kongre bölgesi vardır. Birçok eyalette ayrı ayrı bir CD-5 bulunabilse de, 50 eyaletin hiçbirinde asla birden fazla CD-5 bulunmayacaktır veya bunun tersi de geçerlidir. Bu nedenle, Massachusetts CD-5 için bir otonum alanı oluşturmak gereksizdir.

Veritabanı dinamik bir web sayfası kullanıyorsa, iki alanlı bir kombinasyonda sorgulamak için kod yazmak, otomatik numaralandırılmış bir anahtarı ayıklamak / yeniden göndermek yerine çok daha kolay olabilir.

Orijinal soruyu cevaplamasam da, Adam'ın doğrudan cevabını kesinlikle takdir ediyorum.


4

Kompozit birincil anahtarlar, bir olgu tablosuyla çoktan çoğa ilişki oluşturmak istediğiniz yerdir. Örneğin, içinde bir dizi özellik içeren bir tatil kiralama paketiniz olabilir. Öte yandan, mülk, kendi başına veya diğer mülklerle birlikte bir dizi kiralık paketin bir parçası olarak da mevcut olabilir. Bu senaryoda, bir özellik / paket olgu tablosu ile özellik ve kiralama paketi arasındaki ilişkiyi kurmak. Bir özellik ve bir paket arasındaki ilişki benzersiz olacaktır, yalnızca özellik tablosu ile property_id ve / veya paket tablosu ile package_id kullanarak katılabilirsiniz. Her ilişki benzersizdir ve auto_increment anahtarı, başka hiçbir tabloda bulunmayacağından gereksizdir. Dolayısıyla bileşik anahtarı tanımlamak cevaptır.


1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);

1

@AlexCuse Bunu cevabınıza yorum olarak eklemek istedim ancak yorumlara yeni satırlar eklemek için birden fazla başarısız girişimde bulunduktan sonra vazgeçtim.

Bununla birlikte, t1ID tablo_1 içinde benzersizdir, ancak bu INFO tablosunda da benzersiz değildir.

Örneğin:

Tablo_1'de :
Kimlik Alanı
1 A
2 B

Tablo_2'de :
Kimlik Alanı
1 X
2 Y

INFO o zaman
şunları içerebilir : t1ID t2ID alanı
1 1 bazı
1 2 veri
2 her birinde 1
1 2 2 satır

INFO tablosunda bir satırı benzersiz bir şekilde tanımlamak için hem t1ID hem de t2ID'ye ihtiyacınız var


Kompozit anahtarı denir
Pavel P

1
@PavelP cevabım wrt Alex'in "Her iki sütun da benzersiz olması gerektiğinden, t1ID = 11209 muhtemelen yeterli olacaktır." ... Bileşik anahtar kullanmanın doğru olduğunu kabul ediyorum, ancak tam eşleşmeyi tanımlamak için hem t1ID hem de t2ID'ye ihtiyacınız olacak ... Umarım şimdi açıktır.
17'de sactiw
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.