Tek bir tabloda birden fazla birincil anahtar alabilir miyim?
Tek bir tabloda birden fazla birincil anahtar alabilir miyim?
Yanıtlar:
Tablo, iki veya daha fazla sütundan oluşan birincil anahtar olan Kompozit Birincil Anahtar içerebilir . Örneğin:
CREATE TABLE userdata (
userid INT,
userdataid INT,
info char(200),
primary key (userid, userdataid)
);
Güncelleme: İşte bileşik birincil anahtarların daha ayrıntılı bir açıklamasını içeren bir bağlantı .
Bir tablonun birden fazla aday anahtarı olabilir. Her aday anahtarı BENZERSİZ, birlikte alınan ve aynı zamanda BOŞ DEĞİL olan bir sütun veya sütun kümesidir. Bu nedenle, herhangi bir aday anahtarının tüm sütunları için değer belirtmek, ölçütleri karşılayan bir satır olduğunu veya hiç satır olmadığını belirlemek için yeterlidir.
Aday anahtarlar ilişkisel veri modelinde temel bir kavramdır.
Bir tabloda birden fazla anahtar varsa, aday anahtarlardan birini birincil anahtar olarak atamak yaygın bir uygulamadır. Tablodaki herhangi bir yabancı anahtarın, diğer herhangi bir aday anahtar yerine birincil anahtara başvurmasına neden olmak yaygın bir uygulamadır.
Bu uygulamaları tavsiye ederim, ancak ilişkisel modelde aday anahtarlar arasında birincil anahtar seçilmesini gerektiren hiçbir şey yoktur.
Bu hem ana sorunun hem de @ Kalmi'nin
Otomatik olarak oluşturulan birden çok sütuna sahip olmanın anlamı nedir?
Aşağıdaki kod, bileşik birincil anahtara sahiptir. Sütunlarından biri otomatik olarak artırılır. Bu yalnızca MyISAM'da çalışır. InnoDB bir hata oluşturur " HATA 1075 (42000): Hatalı tablo tanımı; yalnızca bir otomatik sütun olabilir ve bir anahtar olarak tanımlanması gerekir ".
DROP TABLE IF EXISTS `test`.`animals`;
CREATE TABLE `test`.`animals` (
`grp` char(30) NOT NULL,
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`name` char(30) NOT NULL,
PRIMARY KEY (`grp`,`id`)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Which returns:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
(Bunları çok çalışıyorum)
Aday tuşları - Bir tablo satırını benzersiz olarak tanımlamak için gereken minimum sütun birleşimi.
Bileşik tuşlar - 2 veya daha fazla sütun.
Kaynaklar:
https://en.wikipedia.org/wiki/Superkey
https://en.wikipedia.org/wiki/Candidate_key
https://en.wikipedia.org/wiki/Primary_key
https://en.wikipedia.org / wiki / Compound_key
Diğerleri tarafından belirtildiği gibi, çok sütunlu birincil anahtarlara sahip olmak mümkündür. Bununla birlikte, bir anahtar tarafından kullanılmayan bazı fonksiyonel bağımlılıklarınız varsa, normalleştirmeyi düşünmelisiniz. , ilişkinizi .
Misal:
Person(id, name, email, street, zip_code, area)
A arasında fonksiyonel bir bağımlılık olabilir, id -> name,email, street, zip_code and area
ancak genellikle a zip_code
ile ilişkilidir area
ve bu nedenle arasında dahili bir fonksiyonel bağımlılık vardır.zip_code -> area
.
Bu nedenle, kişi başka bir tabloya bölmeyi düşünebilir:
Person(id, name, email, street, zip_code)
Area(zip_code, name)
Böylece üçüncü normal formla tutarlıdır .
Birincil Anahtar, Mantıksal Model ile bağlantılı olarak "Birincil" ve bilinçaltı çağrışım nedeniyle çok talihsiz bir gösterimdir. Böylece kullanmaktan kaçınırım. Bunun yerine, Fiziksel Modelin Yedek Anahtarına ve Mantıksal Modelin Doğal Anahtarlarına başvuruyorum.
Her Varlık için Mantıksal Modelin, varlık için bir Anahtar içeren en az bir "iş özelliği" setine sahip olması önemlidir. Boyce, Codd, Date vd. İlişkisel Modelde bunlara Aday Anahtarlar olarak atıfta bulunur. Bu varlıklar için tablolar oluşturduğumuzda, Aday Anahtarları bu tablolarda Doğal Anahtar olur. Kullanıcılar yalnızca bu Doğal Anahtarlar aracılığıyla tablolardaki satırları benzersiz bir şekilde tanımlayabilir; yedek anahtarlar her zaman kullanıcılardan gizlenmelidir. Bunun nedeni, Yedek Anahtarların ticari bir anlamı olmamasıdır.
Ancak, tablolarımız için Fiziksel Model çoğu durumda Yedek Anahtar olmadan verimsiz olacaktır. Kümelenmemiş bir dizin için kapsanmayan sütunların (genel olarak) yalnızca kümelenmiş dizine Anahtar Arama yoluyla bulunabileceğini unutmayın (bir an için yığın olarak uygulanan tabloları yoksay). Mevcut Doğal Anahtar (lar) ımız geniş olduğunda, bu (1) kümelenmemiş yaprak düğümlerimizin genişliğini genişleterek depolama gereksinimlerini ve bu kümelenmemiş dizinin tarama ve taramaları için okuma erişimini artırır; ve (2) kümelenmiş endeksimizden çıkmayı azaltır, dizin yüksekliğini ve dizin boyutunu artırarak, kümelenmiş dizinlerimiz için okuma ve depolama gereksinimlerini tekrar arttırır; ve (3) kümelenmiş dizinlerimiz için önbellek gereksinimlerini artırır. diğer dizinleri ve verileri önbellekten çıkarma.
RDBMS'ye "Birincil Anahtar" olarak atanan küçük bir Yedek Anahtar burada yararlı olmaktadır. Kümeleme anahtarı olarak ayarlandığında, kümelenmemiş dizinlerden kümelenmiş dizine anahtar aramaları ve ilgili tablolardan yabancı anahtar aramaları için kullanılacak şekilde, tüm bu dezavantajlar ortadan kalkar. Kümelenmiş dizin fan çıkışlarımız, kümelenmiş dizin yüksekliğini ve boyutunu azaltmak, kümelenmiş dizinlerimiz için önbellek yükünü azaltmak, herhangi bir mekanizma yoluyla verilere erişirken (dizin taraması, dizin araması, kümelenmemiş anahtar araması veya yabancı anahtar araması) okumaları yeniden artırır tablolarımızın hem kümelenmiş hem de kümelenmemiş dizinleri için depolama gereksinimlerini azaltır.
Bu avantajların yalnızca yedek anahtar hem küçük hem de kümeleme anahtarı olduğunda ortaya çıkar. Küme anahtarı olarak bir GUID kullanılırsa, durum genellikle kullanılabilir en küçük Doğal Anahtarın kullanılmasından daha kötü olur. Tablo bir yığın olarak düzenlenmişse, 8 baytlık (yığın) RowID, 16 baytlık bir GUID'den daha iyi ancak 4 baytlık bir tam sayıdan daha az performans gösteren anahtar aramaları için kullanılır.
İş kısıtlamaları nedeniyle bir GUID kullanılması gerekiyorsa, daha iyi bir kümeleme anahtarını aramak faydalı olacaktır. Örneğin, küçük bir site tanımlayıcısı ve 4 baytlık "site-sıra numarası" mümkünse, bu tasarım Yedek Anahtar olarak bir GUID'den daha iyi performans verebilir.
Bir yığının sonuçları (belki de karma birleştirme) tercih edilen depolamayı yaparsa, daha geniş bir kümeleme anahtarının maliyetlerinin değiş tokuş analiziyle dengelenmesi gerekir.
Bu örneği düşünün ::
ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
burada " (P_Id, LastName) " dizisi benzersiz bir kısıtlama gerektirir ve uzun bir Unicode LastName artı 4 baytlık bir tamsayı olabilir ; , LastName) "ve (2) ayrı olarak küçük bir Yedek Anahtarı" Birincil Anahtar "olarak bildirir kümelenmiş bir dizinin " . Anita'nın TÜM alanlar kapsadığı için kümelenmiş bir dizinde gereksiz olan kapalı bir alanın yapılması için bu kısıtlamaya yalnızca LastName eklemek istediğini belirtmek gerekir.
SQL Server'da Birincil Anahtarı kümelenmemiş olarak atama yeteneği, "tercih edilen doğal veya aday anahtar" (Mantıksal Modelden) anlamının "Depolamada arama anahtarı" anlamıyla Fiziksel Modeli. Benim anlayış başlangıçta SYBASE SQL Server her zaman bir yığın veya kümelenmiş bir dizin içine 4-baytlık bir RowID fiziksel modelden "depolamada arama anahtarı" olarak kullandığıdır.
Bazı kişiler "birincil anahtar" terimini, değerlerini bazı otomatik mekanizmalar tarafından oluşturulan tam sayı sütununu ifade etmek için kullanırlar. Örneğin AUTO_INCREMENT
MySQL veyaIDENTITY
Microsoft SQL Server'da. Bu anlamda birincil anahtar mı kullanıyorsunuz?
Öyleyse, cevap kullandığınız veritabanının markasına bağlıdır. MySQL'de bunu yapamazsınız, bir hata alırsınız:
mysql> create table foo (
id int primary key auto_increment,
id2 int auto_increment
);
ERROR 1075 (42000): Incorrect table definition;
there can be only one auto column and it must be defined as a key
Diğer bazı veritabanı markalarında, bir tabloda birden fazla otomatik oluşturma sütunu tanımlayabilirsiniz.
Aynı anda iki ana tuşa sahip olmak mümkün değildir. Ancak (davayı bileşik anahtarla karıştırmamanız durumunda), ihtiyacınız olabilecek şey bir özelliği benzersiz hale getirmektir.
CREATE t1(
c1 int NOT NULL,
c2 int NOT NULL UNIQUE,
...,
PRIMARY KEY (c1)
);
Ancak ilişkisel veritabanında bir "süper anahtar" ın, bir tablodaki bir tuple veya satırı benzersiz bir şekilde tanımlayan niteliklerin bir alt kümesi olduğunu unutmayın. 'Anahtar', anahtardan herhangi bir özniteliği kaldıran ek bir özelliğe sahip bir 'süper anahtardır', bu anahtarı artık bir 'süper anahtar' yapmaz (veya sadece bir 'anahtar' minimal bir süper anahtardır). Daha fazla anahtar varsa, hepsi aday anahtarlardır. Birincil anahtar olarak aday anahtarlarından birini seçiyoruz. Bu nedenle, tek bir ilişki veya tablo için birden çok birincil anahtardan bahsetmek bir çatışmadır.
Birincil anahtar, bir kaydı benzersiz şekilde tanımlayan ve tüm dizinlerde kullanılan anahtardır. Bu yüzden birden fazla olamaz. Ayrıca genellikle alt tablolara katılmak için kullanılan anahtardır, ancak bu bir zorunluluk değildir. PK'nin asıl amacı, veri değişikliklerinin doğru kaydı etkilemesi ve dizinlerin oluşturulması için bir şeyin bir kaydı benzersiz bir şekilde tanımlamanıza izin vermesini sağlamaktır.
Ancak, bir birincil anahtara (bileşik PK) birden çok alan koyabilirsiniz. Bu, birleşimlerinizi yavaşlatır (özellikle daha büyük dize türü alanlarsa) ve dizinleriniz daha büyük olur, ancak performans ve tasarım açısından bazı alt tablolarda birleşim yapma ihtiyacını ortadan kaldırabilir. davanın temeli. Bunu yaptığınızda, her alanın kendisi benzersiz değildir, ancak bunların birleşimi olur. Bileşik anahtardaki alanlardan biri veya daha fazlası da benzersizse, üzerinde benzersiz bir dizine ihtiyacınız vardır. Bir alan benzersizse, bunun PK için daha iyi bir aday olması muhtemeldir.
Şimdi zaman zaman PK için birden fazla adayınız var. Bu durumda PK olarak birini seçer veya yedek anahtar kullanırsınız (bu örnek için şahsen yedek anahtarları tercih ederim). Ve (bu kritik!) PK olarak seçilmemiş aday anahtarların her birine benzersiz dizinler eklersiniz. Verilerin benzersiz olması gerekiyorsa, PK olsun ya da olmasın benzersiz bir dizine ihtiyaç duyar. Bu bir veri bütünlüğü sorunudur. (Yedek anahtar kullandığınızda bunun da geçerli olduğunu unutmayın; insanlar yedek anahtarlarla sorun yaşarlar çünkü aday anahtarlarda benzersiz dizinler oluşturmayı unuturlar.)
Bazen birden fazla vekil anahtar istediğiniz zamanlar vardır (bunlara sahipseniz genellikle PK olur). Bu durumda istediğiniz şey daha fazla PK değil, otomatik olarak oluşturulmuş anahtarları olan alanlardır. Çoğu DB buna izin vermez, ancak bunun üstesinden gelmenin yolları vardır. İlk olarak, ikinci alanın ilk otomatik olarak oluşturulan anahtara (örneğin Alan1 * -1) göre hesaplanıp hesaplanamayacağını veya belki de ikinci bir otomatik olarak oluşturulan anahtara duyulan ihtiyacın gerçekten ilişkili bir tablo oluşturmanız gerektiği anlamına geldiğini düşünün. İlgili tablolar birebir ilişki içinde olabilir. Üst tablodan alt tabloya PK ekleyerek ve sonra tabloya yeni otomatik oluşturulan alanı ve sonra bu tablo için uygun olan alanları ekleyerek zorlarsınız. Ardından, PK olarak iki anahtardan birini seçin ve diğerine benzersiz bir dizin koyun (otomatik olarak oluşturulan alanın PK olması gerekmez). Ve FK'yi üst tablodaki alana eklediğinizden emin olun. Genel olarak, alt tablo için ek alanınız yoksa, neden iki otomatik oluşturulmuş alana ihtiyacınız olduğunu düşündüğünüzü incelemeniz gerekir.
İyi teknik cevaplar benden daha iyi bir şekilde verildi. Ben sadece bu konuya ekleyebilirsiniz:
İzin verilmeyen / kabul edilmeyen bir şey istiyorsanız, geri adım atmanız iyi bir nedendir.
Umarım birine yardımcı olur.
Evet, SQL'de mümkündür, ancak MsAccess'te birden fazla birincil anahtar ayarlayamayız. O zaman, diğer veritabanlarını bilmiyorum.
CREATE TABLE CHAPTER (
BOOK_ISBN VARCHAR(50) NOT NULL,
IDX INT NOT NULL,
TITLE VARCHAR(100) NOT NULL,
NUM_OF_PAGES INT,
PRIMARY KEY (BOOK_ISBN, IDX)
);