Съставен първичен ключ е първичен ключ, състоящ се от множество колони. Microsoft обикновено ги нарича първични ключове с много колони в своята документация.
Тази статия предоставя пример за създаване на съставен първичен ключ с помощта на Transact-SQL в SQL Server.
Можете да създадете съставен първичен ключ точно както бихте създали единичен първичен ключ, с изключение на това, че вместо да посочвате само една колона, предоставяте името на две или повече колони, разделени със запетая.
Като това:
CONSTRAINT PK_Name PRIMARY KEY (колона 1, колона 2)
Пример 1 – Създаване на композитен първичен ключ
Ето пример за база данни, използваща съставен първичен ключ.
За целите на този пример ще създам база данни, наречена PK_Test :
СЪЗДАВАНЕ НА БАЗА ДАННИ PK_Test;
След като базата данни е създадена, нека да продължим и да създадем таблиците.
ИЗПОЛЗВАЙТЕ PK_Test;CREATE TABLE Musician (MusicianId int NOT NULL,FirstName varchar(60),LastName varchar(60),CONSTRAINT PK_Musician PRIMARY KEY (MusicianID));CREATE TABLE Band (BandId int, NOTBandName) varchar ,CONSTRAINT PK_Band PRIMARY KEY (BandId));CREATE TABLE BandMember (MusicianId int NOT NULL,BandId int NOT NULL,CONSTRAINT PK_BandMember ПРАВИЛЕН КЛЮЧ (MusicianID, BandId),CONSTRAINT FK_BandMember,CONSTRAINT FK_BandMember, CONSTRAINT FK_BandMember, CONSTRAINT FK_BandMember, REGNUM FK_BandBEIGNES и BANDBFEIGNES и BANDBEIGNES и BANDBMEmber_и КЛЮЧОВИ (MusicianId) РЕФЕРЕНЦИИ Музикант (MusicianId));
В този пример BandMember
таблицата има първичен ключ от няколко колони. В този случай всяка колона в първичния ключ също е външен ключ към първичния ключ на друга таблица, но това не е изискване.
Причината зад горния дизайн на база данни е, че един музикант потенциално може да бъде член на много групи. Освен това всяка група може да има много музиканти. Така че имаме връзка много към много. Ето защо BandMember
таблицата е създадена – тя се използва като таблица за кръстосани препратки между Musician
таблица и Band
маса.
Този конкретен случай поддържа съставен първичен ключ, тъй като музикантът, който е член на група, трябва да бъде уникално явление. С други думи, не бихме искали множество редове с музикант да е член на една и съща група. Това би нарушило целостта на данните. Това също може да причини хаос, когато се опитваме да запазим референтната цялост, дори когато някога създадем връзка между тази таблица и друга (което правим тук).
Пример 2 – Вмъкване на данни
След като изпълних горния код, вече мога да заредя базата данни с данни:
INSERT INTO MusicianVALUES ( 1, 'Ian', 'Paice' ),( 2, 'Roger', 'Glover' ),( 3, 'Richie', 'Blackmore' ),( 4, 'Rod', ' Evans' ),( 5, 'Ozzy', 'Osbourne' );INSERT INTO BandVALUES ( 1, 'Deep Purple' ),( 2, 'Rainbow' ),( 3, 'Whitesnake' ),( 4, 'Iron Maiden ' );INSERT INTO BandMemberVALUES ( 1, 1 ), ( 1, 3 ), ( 2, 1 ), ( 2, 2 ), ( 3, 1 ), ( 3, 2 ), ( 4, 1 );предварително>Пример 3 – Основна заявка
Сега, когато данните са в нашата база данни, нека изпълним заявка, за да върнем част от тези данни.
Ето една основна заявка:
ИЗБЕРЕТЕ CONCAT(m.FirstName, ' ', m.Lastname) КАТО 'Musician', b.BandName КАТО 'Band'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b ON b.BandId =bmBandId. .BandId И m.MusicianId =bm.MusicianId;Резултат:
+------------------+------------+| Музикант | Група ||-------------------+------------|| Иън Пейс | Deep Purple || Иън Пейс | Бяла змия || Роджър Глоувър | Deep Purple || Роджър Глоувър | Дъга || Ричи Блекмор | Deep Purple || Ричи Блекмор | Дъга || Род Евънс | Deep Purple |+------------------+------------+Така че, както се очаква, това връща само онези музиканти и групи, които имат запис в
BandMember
справочна таблица.Пример 4 – Леко модифицирана заявка
Ето модифицирана версия на горната заявка, която представя резултатите по различен начин:
ИЗБЕРЕТЕ b.BandName КАТО 'Band', STRING_AGG(CONCAT(m.FirstName, ' m.LastName), ', ') КАТО 'Musicians'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianId b ON b.BandId =bm.BandId И m.MusicianId =bm.MusicianIdGROUP BY b.BandName;Резултат:
+------------+-------------------------------- ---------------------+| Банда | Музиканти ||-------------+-------------------------------- ---------------------|| Deep Purple | Иън Пейс, Роджър Глоувър, Ричи Блекмор, Род Евънс || Дъга | Роджър Глоувър, Ричи Блекмор || Бяла змия | Иън Пейс |+------------+-------------------------------- ---------------------+Тук резултатите са групирани по групи и всички музиканти за всяка група се показват като разделен със запетая списък в едно поле.
За да направя това, използвам
STRING_AGG()
функция за обединяване на музикантите.Съставен външен ключ
Проблемът с горния пример е, че повечето данни са остарели. Някои от тези музиканти всъщност са напуснали тези групи. И някои са напуснали и след това се върнали на по-късна дата.
Как можем да се справим с това?
Бихме могли да създадем друга референтна таблица, за да запишем периода от време, в който всеки музикант е член на всяка група. Такава таблица ще трябва да препраща към
BandMember
таблица чрез външен ключ. И тъй като тази таблица има съставен първичен ключ, ще трябва да използваме съставен външен ключ в новата таблица, която я препраща.Вижте как да създадете композитен външен ключ в SQL Server за пример. Тази статия използва същия пример като по-горе, освен с допълнителна таблица със съставен външен ключ, който препраща към горния съставен първичен ключ.