SQL'de bileşik birincil anahtarı nasıl tanımlayabilirim?


112

SQL'de iki alandan oluşan bir bileşik birincil anahtarı nasıl tanımlayabilirim?

Tabloları ve her şeyi oluşturmak için PHP kullanıyorum. Bir tablo isim yapmak isteyen votingalanlarla QuestionID, MemeberIDve vote. Ve Kompozit birincil anahtar alandan oluşur QuestionIDve MemberID.

Bunu nasıl yapmalıyım?


"Ve Soru Kimliği ve Üye Kimliği birincil anahtarlar olacaktır." (Soru Kimliği, Üye Kimliği) (bileşik) birincil anahtar olacaktır . Tek bir anahtar vardır ve iki sütundan oluşur.
Draemon

Yanıtlar:


229

Sadece açıklama için: bir tablonun en fazla bir birincil anahtarı olabilir. Bir birincil anahtar, bir veya daha fazla sütundan oluşur (bu tablodan). Birincil anahtar iki veya daha fazla sütundan oluşuyorsa, buna bileşik birincil anahtar denir . Aşağıdaki gibi tanımlanır:

CREATE TABLE voting (
  QuestionID NUMERIC,
  MemberID NUMERIC,
  PRIMARY KEY (QuestionID, MemberID)
);

Çift (SoruKimliği, ÜyeKimliği) tablo için benzersiz olmalıdır ve hiçbir değer NULL olamaz. Böyle bir sorgu yaparsanız:

SELECT * FROM voting WHERE QuestionID = 7

birincil anahtarın dizinini kullanacaktır. Ancak bunu yaparsanız:

SELECT * FROM voting WHERE MemberID = 7

bir bileşik dizin kullanmak için "soldan" tüm anahtarların kullanılmasını gerektirdiğinden bu olmayacaktır. Bir dizin alanlar (A, B, C) üzerindeyse ve ölçütleriniz B ve C üzerindeyse, o zaman bu dizin sizin için bu sorgu için bir yarar sağlamaz. Bu nedenle (Soru Kimliği, Üye Kimliği) ve (Üye Kimliği, Soru Kimliği) arasından tabloyu nasıl kullanacağınıza en uygun olanı seçin.

Gerekirse, diğerine bir dizin ekleyin:

CREATE UNIQUE INDEX idx1 ON voting (MemberID, QuestionID);

5
İyi cevap. Sadece açıklığa kavuşturmak gerekirse, Soru Kimliği ve Üye Kimliği ayrı birincil anahtarlar değildir, ancak bunların kombinasyonu benzersiz bir çift / tuple oluşturur.
Peter

5
(MemberID, QuestionID)Sadece indeks eklemenin bir faydası var mı MemberID? Anladığım kadarıyla, ile seçim yaparken dizine alınmış arama alıyorsunuz QuestionIdve ayrıca (QuestionId, MemeberId)tek eksik olan sadece olacaktır MemberId.
swalog

Bu cevabın oldukça eski olduğunu biliyorum ama bir google araması sırasında ortaya çıktığı için ... Metinde, varsayılan indeks (ler) için hangi sütunların kullanıldığı (veya kullanılmadığı) konusunda bir tutarsızlık var gibi görünüyor. Ayrıca, her RDBMS'nin birincil anahtarda otomatik olarak bir dizin oluşturacağını varsayar, ancak herhangi bir standart için gerekli olmadığından, orada bazı köşe durumları olabilir.
2016

Her iki alan da diğer tablolardan basit (ve muhtemelen birincil) anahtarlar olduğundan, örnek bileşik bir anahtar değil bir bileşik anahtarı göstermektedir
guymid

6
CREATE TABLE `voting` (
  `QuestionID` int(10) unsigned NOT NULL,
  `MemberId` int(10) unsigned NOT NULL,
  `vote` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`QuestionID`,`MemberId`)
);
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.