sql >> Databáze >  >> RDS >> Sqlserver

Jak vytvořit složený cizí klíč v SQL Server (příklad T-SQL)

složený cizí klíč je cizí klíč skládající se z více sloupců.

Tento článek poskytuje příklad vytvoření složeného cizího klíče pomocí Transact-SQL v SQL Server.

Složený cizí klíč můžete vytvořit stejně, jako byste vytvořili jeden cizí klíč, s tím rozdílem, že místo určení pouze jednoho sloupce zadáte název dvou nebo více sloupců oddělených čárkou.

Takhle:

CONSTRAINT FK_FKName CIZÍ KLÍČ (FKColumn1, FKColumn2)REFERENCE PrimaryKeyTable (PKColumn1, PKColumn2)

Příklad 1 – Vytvoření složeného cizího klíče

Zde je příklad databáze používající složený cizí klíč (a složený primární klíč).

Pro účely tohoto příkladu vytvořím databázi s názvem BandTest :

CREATE DATABASE BandTest;

Nyní, když je databáze vytvořena, pojďme do toho a vytvořte tabulky.

USE BandTest;CREATE TABLE Musician (MusicianId int NOT NULL,FirstName varchar(60),LastName varchar(60),CONSTRAINT PK_Musician PRIMARY KEY (MusicianID));CREATE TABLE Band (BandId int NOT NULL,BandName varchar) ,CONSTRAINT PK_Band PRIMARY KEY (BandId));CREATE TABLE Člen kapely (MusicianId int NOT NULL,BandId int NOT NULL,CONSTRAINT PK_BandMember PRIMÁRNÍ KLÍČ (MusicianID, BandId),CONSTRAINT FK_BandId KEY (dBandM BandId KEY) a CONSTRAINT FK_BandEIGN KEY_andM FORFERENCEGNULL_andM BandI. KEY (MusicianId) REFERENCE Musician(MusicianId));VYTVOŘIT TABULKU MembershipPeriod (MembershipPeriodId int NOT NULL,MusicianId int NOT NULL,BandId int NOT NULL,StartDatum NOT NULL,EndDate PRIINTRYPEKMKEYMeriod KEY (MusicianID, BandId) REFERENCE BandMember(MusicianID, BandId));

V tomto příkladu BandMember tabulka má vícesloupcový primární klíč. MembershipPeriod tabulka má cizí klíč, který odkazuje na tento vícesloupcový primární klíč. Proto definice primárního i cizího klíče zahrnují sloupce oddělené čárkou.

Důvodem výše uvedeného návrhu databáze je, že hudebník by mohl být potenciálně členem mnoha kapel. Každá kapela může mít také mnoho hudebníků. Takže máme vztah mnoho k mnoha. To je důvod, proč BandMember je vytvořena tabulka – používá se jako křížová referenční tabulka mezi Musician tabulka a Band stůl. V tomto případě jsem se rozhodl použít složený primární klíč.

Ale hudebník může být také členem skupiny při více než jedné příležitosti (např. hudebník může kapelu opustit, aby se později vrátil). Proto MembershipPeriod tabulku lze použít k zaznamenání všech období, kdy byl každý hudebník členem každé kapely. To musí odkazovat na složený primární klíč na BandMember tabulky, a proto musím vytvořit vícesloupcový cizí klíč.

Příklad 2 – Vložení dat

Po spuštění výše uvedeného kódu nyní mohu načíst databázi s daty:

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 );INSERT INTO MembershipPeriodVALUES ( 1, 1, 1, '1968-03-01', '1976-03-15' ),( 2, 1, 1, '1984-04-01', NULL ),( 3, 1, 3, '1979-08-01', '1982-01-01' ),( 4, 2, 1, '1969-01-01', '1973-06-29' ),( 5, 2, 1, '1984 -04-01', NULL ),( 6, 2, 2, '1979-01-01', '1984-01-01'),( 7, 3, 1, '1968-03-01', '1975 -06-21' ),( 8, 3, 1, '1984-04-01', '1993-11-17' ),( 9, 3, 2, '1975-02-01', '1984-04 -01' ),( 10, 3, 2, '1993-11-17', '1997-05-31' ),( 11, 3, 2, '2015-01-01', NULL ),( 12, 4, 1, '1968-03-01', '1969-12-01');

Příklad 3 – Základní dotaz

Zde je příklad dotazu, který lze spustit proti databázi:

SELECT CONCAT(m.FirstName, ' ', m.LastName) AS 'Musician', b.BandName AS 'Band', mp.StartDate AS 'Start', mp.EndDate AS 'End'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Kapela b ON b.BandId =bm.BandId AND m.MusicianId =bm.MusicianIdJOIN Členství Období mpON mp.BandId =b.BandId AND mp.MusicianId = 

Výsledek:

+------------------+-------------+------------+ ------------+| Hudebník | Kapela | Start | Konec ||------------------+-------------+------------+- -----------|| Ian Paice | Deep Purple | 1968-03-01 | 1976-03-15 || Ian Paice | Deep Purple | 1984-04-01 | NULL || Ian Paice | Whitesnake | 1979-08-01 | 1982-01-01 || Roger Glover | Deep Purple | 1969-01-01 | 1973-06-29 || Roger Glover | Deep Purple | 1984-04-01 | NULL || Roger Glover | Duha | 1979-01-01 | 1984-01-01 || Richie Blackmore | Deep Purple | 1968-03-01 | 1975-06-21 || Richie Blackmore | Deep Purple | 1984-04-01 | 1993-11-17 || Richie Blackmore | Duha | 1975-02-01 | 1984-04-01 || Richie Blackmore | Duha | 1993-11-17 | 1997-05-31 || Richie Blackmore | Duha | 2015-01-01 | NULL || Rod Evans | Deep Purple | 1968-03-01 | 1969-12-01 |+------------------+--------------+----------- --+------------+

Nyní tedy můžeme vidět, kdy byl každý hudebník členem každé kapely, i když byl členem vícekrát.

Příklad 4 – Mírně upravený dotaz

Výše uvedený dotaz bychom mohli upravit tak, aby poskytoval výsledky v trochu čitelnějším formátu:

SELECT CONCAT(m.FirstName, ' ', m.LastName) AS 'Muzikant', b.BandName AS 'Kapela', STRING_AGG( CONCAT(FORMAT(mp.StartDate, 'yyyy'), '-', ISNULL (FORMAT(mp.EndDate, 'yyyy'), 'současnost')), ', ') AS 'Čas s kapelou'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b ON b.BandId =bm .BandId AND m.MusicianId =bm.MusicianIdJOIN MembershipPeriod mpON mp.BandId =b.BandId AND mp.MusicianId =m.MusicianIdGROUP BY m.FirstName, m.LastName, b.BandName; 

Výsledek:

+------------------+-------------+------------- ------------------------+| Hudebník | Kapela | Čas s kapelou ||------------------+-------------+------------ -------------------------|| Ian Paice | Deep Purple | 1968-1976, 1984-dosud || Ian Paice | Whitesnake | 1979-1982 || Richie Blackmore | Deep Purple | 1968-1975, 1984-1993 || Richie Blackmore | Duha | 1975-1984, 1993-1997, 2015-dosud || Rod Evans | Deep Purple | 1968-1969 || Roger Glover | Deep Purple | 1969-1973, 1984-dosud || Roger Glover | Duha | 1979-1984 |+------------------+-------------+------------- ------------------------+

Tento příklad využívá STRING_AGG() funkce pro zřetězení různých časových období pro každého hudebníka. Tím se sníží počet požadovaných řádků a umožní nám seskupit časová období ve stejném poli.

Také využívám výhody ISNULL() funkce, která mi umožňuje změnit jakékoli hodnoty NULL na něco smysluplnějšího.

Všimněte si, že ISNULL() vyžaduje, aby druhý argument byl typu, který lze implicitně převést na typ prvního argumentu. V tomto případě bylo prvním argumentem původně datum typ, což znamená, že bych nemohl použít řetězec. V tomto případě jsem se však rozhodl použít FORMAT() funkce pro formátování data hodnota. Tato funkce implicitně převádí datum hodnotu na řetězec, a proto jsem mohl použít řetězec pro druhý argument.


  1. Jak začít s Amazon ECS a Amazon Fargate

  2. SQL:BETWEEN vs <=a>=

  3. Jak Random() funguje v PostgreSQL

  4. Datové typy VARCHAR a NVARCHAR v SQL Server