sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man skapar en sammansatt primär nyckel i SQL Server (T-SQL-exempel)

En sammansatt primärnyckel är en primärnyckel som består av flera kolumner. Microsoft hänvisar vanligtvis till dessa som primärnycklar med flera kolumner i sin dokumentation.

Den här artikeln ger ett exempel på hur du skapar en sammansatt primärnyckel med Transact-SQL i SQL Server.

Du kan skapa en sammansatt primärnyckel precis som du skulle skapa en enskild primärnyckel, förutom att istället för att ange bara en kolumn, anger du namnet på två eller flera kolumner, åtskilda av ett kommatecken.

Så här:

CONSTRAINT PK_Name PRIMÄRNYCKEL (kolumn1, kolumn2)

Exempel 1 – Skapa en sammansatt primärnyckel

Här är ett exempel på en databas som använder en sammansatt primärnyckel.

För detta exempel skapar jag en databas som heter PK_Test :

SKAPA DATABAS PK_Test;

Nu när databasen har skapats, låt oss gå vidare och skapa tabellerna.

ANVÄND PK_Test;CREATE TABLE Musiker (MusicianId int NOT NULL,FirstName varchar(60),Efternamn varchar(60),CONSTRAINT PK_Musician PRIMARY KEY (MusicianID));CREATE TABLE Band (BandId int NOT NULL,Band5) varchar(25) ,CONSTRAINT PK_Band PRIMARY KEY (BandId));CREATE TABLE BandMember (MusicianId int NOT NULL,BandId int NOT NULL,CONSTRAINT PK_BandMember PRIMARY KEY (MusicianID, BandId),CONSTRAINT FK_BandMember_Band_Band_Band FORFIGNd(MusicianBand_Band_Band_BandFEIGNCd)(MusicianBand_Band_Band_Band FORFIGNd) KEY (MusicianId) REFERENSER Musician(MusicianId));

I det här exemplet är BandMember tabellen har en primärnyckel med flera kolumner. I det här fallet är varje kolumn i primärnyckeln också en främmande nyckel till primärnyckeln i en annan tabell, men detta är inte ett krav.

Resonemanget bakom ovanstående databasdesign är att en musiker potentiellt kan vara medlem i många band. Dessutom kan varje band ha många musiker. Så vi har ett många-till-många-förhållande. Det är därför BandMember tabellen skapas – den används som en korsreferenstabell mellan Musician tabellen och Band tabell.

Det här specifika fallet stöder en sammansatt primärnyckel, eftersom en musiker som är medlem i ett band borde vara en unik händelse. Med andra ord, vi skulle inte vilja ha flera rader med en musiker som är medlem i samma band. Det skulle kränka dataintegriteten. Det kan också orsaka förödelse när vi försöker bibehålla referensintegritet även om vi någonsin skapar en relation mellan denna tabell och en annan (vilket vi gör här).

Exempel 2 – Infoga data

Efter att ha kört ovanstående kod kan jag nu ladda databasen med data:

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 ); 

Exempel 3 – Grundläggande fråga

Nu när data finns i vår databas, låt oss köra en fråga för att returnera en del av dessa data.

Här är en grundläggande fråga:

SELECT CONCAT(m.FirstName, ' ', m.LastName) AS 'Musician', b.BandName AS 'Band'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b ON b.BandId =bm .BandId OCH m.MusicianId =bm.MusicianId;

Resultat:

+-------------------+-------------+| Musiker | Band ||-----------------+------------|| Ian Paice | Deep Purple || Ian Paice | Whitesnake || Roger Glover | Deep Purple || Roger Glover | Regnbåge || Richie Blackmore | Deep Purple || Richie Blackmore | Regnbåge || Rod Evans | Deep Purple |+-------------------+---------------+

Så som förväntat returnerar detta bara de musiker och band som har en post i BandMember referenstabell.

Exempel 4 – Något modifierad fråga

Här är en modifierad version av ovanstående fråga som presenterar resultaten på ett annat sätt:

SELECT b.BandName AS 'Band', STRING_AGG(CONCAT(m.FirstName, ' ', m.LastName), ', ') AS 'Musicians'FROM Musician MJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b PÅ b.BandId =bm.BandId OCH m.MusicianId =bm.MusicianIdGROUP EFTER b.BandName;

Resultat:

+-------------+-------------------------------- ----------------------------+| Band | Musiker ||-------------+---------------------------------------- --------------------|| Deep Purple | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans || Regnbåge | Roger Glover, Richie Blackmore || Whitesnake | Ian Paice |+-------------+-------------------------------- ----------------------------+

Här grupperas resultaten efter band, och alla musiker för varje band visas som en kommaseparerad lista i ett enda fält.

För att göra detta använder jag STRING_AGG() funktion för att sammanfoga musikerna.

Komposit utländsk nyckel

Problemet med exemplet ovan är att de flesta data är inaktuella. Några av dessa musiker har faktiskt lämnat de banden. Och några har lämnat och sedan återvänt vid ett senare tillfälle.

Hur kan vi hantera detta?

Vi skulle kunna skapa en annan referenstabell för att registrera den tidsperiod varje musiker är medlem i varje band. En sådan tabell skulle behöva referera till BandMember tabell via en främmande nyckel. Och eftersom den här tabellen har en sammansatt primärnyckel, skulle vi behöva använda en sammansatt främmande nyckel på den nya tabellen som refererar till den.

Se hur man skapar en sammansatt främmande nyckel i SQL Server för ett exempel. Den artikeln använder samma exempel som ovan, förutom med en extra tabell med en sammansatt främmande nyckel som refererar till ovanstående sammansatta primärnyckel.


  1. Kapslad select-sats i SQL Server

  2. Öppna SQLite-frågeresultat automatiskt i en textredigerare

  3. Dela upp avgränsade värden i en SQL-kolumn i flera rader

  4. Lägg till en kolumn som representerar en sammanlänkning av två andra Varchar-kolumner