sql >> Database >  >> RDS >> Sqlserver

Een samengestelde primaire sleutel maken in SQL Server (T-SQL-voorbeeld)

Een samengestelde primaire sleutel is een primaire sleutel die uit meerdere kolommen bestaat. Microsoft verwijst hier in de documentatie meestal naar als primaire sleutels met meerdere kolommen.

Dit artikel bevat een voorbeeld van het maken van een samengestelde primaire sleutel met Transact-SQL in SQL Server.

U kunt een samengestelde primaire sleutel maken net zoals u een enkele primaire sleutel zou maken, behalve dat u in plaats van slechts één kolom op te geven, de naam van twee of meer kolommen opgeeft, gescheiden door een komma.

Zoals dit:

CONSTRAINT PK_Name PRIMARY KEY (Column1, Column2)

Voorbeeld 1 – Maak een samengestelde primaire sleutel

Hier is een voorbeeld van een database die een samengestelde primaire sleutel gebruikt.

Voor dit voorbeeld maak ik een database met de naam PK_Test :

CREATE DATABASE PK_Test;

Nu de database is gemaakt, gaan we verder met het maken van de tabellen.

USE 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 NOT NULL,
BandName varchar(255),
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 FOREIGN KEY (BandId) REFERENCES Band(BandId),
CONSTRAINT FK_BandMember_Musician FOREIGN KEY (MusicianId) REFERENCES Musician(MusicianId)
);

In dit voorbeeld is de BandMember tabel heeft een primaire sleutel met meerdere kolommen. In dit geval is elke kolom in de primaire sleutel ook een externe sleutel naar de primaire sleutel van een andere tabel, maar dit is geen vereiste.

De redenering achter het bovenstaande databaseontwerp is dat een muzikant mogelijk lid kan zijn van veel bands. Elke band kan ook veel muzikanten hebben. We hebben dus een veel-op-veel relatie. Dit is de reden waarom het BandMember tabel wordt gemaakt – deze wordt gebruikt als een kruisverwijzingstabel tussen de Musician tabel en de Band tafel.

Dit specifieke geval ondersteunt een samengestelde primaire sleutel, omdat een muzikant die lid is van een band een unieke gebeurtenis zou moeten zijn. Met andere woorden, we zouden niet meerdere rijen willen met een muzikant die lid is van dezelfde band. Dat zou de gegevensintegriteit schenden. Het kan ook chaos veroorzaken wanneer we proberen de referentiële integriteit te behouden, zelfs als we ooit een relatie tussen deze tabel en een andere creëren (wat we hier doen).

Voorbeeld 2 – Gegevens invoegen

Nadat ik zojuist de bovenstaande code heb uitgevoerd, kan ik nu de database met gegevens laden:

INSERT INTO Musician
VALUES 
( 1, 'Ian', 'Paice' ),
( 2, 'Roger', 'Glover' ),
( 3, 'Richie', 'Blackmore' ),
( 4, 'Rod', 'Evans' ),
( 5, 'Ozzy', 'Osbourne' );

INSERT INTO Band
VALUES 
( 1, 'Deep Purple' ),
( 2, 'Rainbow' ),
( 3, 'Whitesnake' ),
( 4, 'Iron Maiden' );

INSERT INTO BandMember
VALUES 
( 1, 1 ),
( 1, 3 ),
( 2, 1 ),
( 2, 2 ),
( 3, 1 ),
( 3, 2 ),
( 4, 1 );

Voorbeeld 3 – Basisquery

Nu de gegevens in onze database staan, gaan we een query uitvoeren om een ​​deel van die gegevens te retourneren.

Hier is een basisvraag:

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

Resultaat:

+------------------+-------------+
| Musician         | Band        |
|------------------+-------------|
| Ian Paice        | Deep Purple |
| Ian Paice        | Whitesnake  |
| Roger Glover     | Deep Purple |
| Roger Glover     | Rainbow     |
| Richie Blackmore | Deep Purple |
| Richie Blackmore | Rainbow     |
| Rod Evans        | Deep Purple |
+------------------+-------------+

Dus zoals verwacht, retourneert dit alleen die muzikanten en bands die een vermelding hebben in het BandMember referentietabel.

Voorbeeld 4 – Iets gewijzigde zoekopdracht

Hier is een aangepaste versie van de bovenstaande zoekopdracht die de resultaten op een andere manier presenteert:

SELECT 
  b.BandName AS 'Band',
  STRING_AGG(CONCAT(m.FirstName, ' ', m.LastName), ', ') AS 'Musicians'
FROM Musician m
JOIN BandMember bm
  ON m.MusicianId = bm.MusicianId
JOIN Band b 
  ON b.BandId = bm.BandId AND m.MusicianId = bm.MusicianId
GROUP BY b.BandName;

Resultaat:

+-------------+------------------------------------------------------+
| Band        | Musicians                                            |
|-------------+------------------------------------------------------|
| Deep Purple | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans |
| Rainbow     | Roger Glover, Richie Blackmore                       |
| Whitesnake  | Ian Paice                                            |
+-------------+------------------------------------------------------+

Hier zijn de resultaten gegroepeerd per band, en alle muzikanten voor elke band worden allemaal weergegeven als een door komma's gescheiden lijst in een enkel veld.

Hiervoor gebruik ik de STRING_AGG() functie om de muzikanten samen te voegen.

Samengestelde externe sleutel

Het probleem met het bovenstaande voorbeeld is dat de meeste gegevens verouderd zijn. Sommige van deze muzikanten hebben die bands zelfs verlaten. En sommigen zijn vertrokken en zijn op een later tijdstip teruggekomen.

Hoe kunnen we hiermee omgaan?

We zouden een andere referentietabel kunnen maken om de tijdsperiode vast te leggen waarin elke muzikant lid is van elke band. Zo'n tabel zou moeten verwijzen naar het BandMember tabel via een externe sleutel. En aangezien deze tabel een samengestelde primaire sleutel heeft, zouden we een samengestelde externe sleutel moeten gebruiken in de nieuwe tabel die ernaar verwijst.

Zie voor een voorbeeld een samengestelde externe sleutel maken in SQL Server. Dat artikel gebruikt hetzelfde voorbeeld als hierboven, behalve met een extra tabel met een samengestelde externe sleutel die verwijst naar de bovenstaande samengestelde primaire sleutel.


  1. De string splitsen in de sql-server

  2. Passeer en retourneer een aangepast array-object in ibatis en oracle in java

  3. Functies maken in phpMyAdmin - Fout:toegang geweigerd, u hebt het superrecht voor deze bewerking nodig

  4. Manieren om eenvoudig de hoofddatabase in SQL Server opnieuw op te bouwen