複合主キー 複数の列で構成される主キーです。 Microsoftは通常、ドキュメントでこれらを複数列の主キーと呼んでいます。
この記事では、SQLServerでTransact-SQLを使用して複合主キーを作成する例を示します。
単一の主キーを作成するのと同じように複合主キーを作成できますが、1つの列だけを指定する代わりに、2つ以上の列の名前をコンマで区切って指定する点が異なります。
このように:
CONSTRAINT PK_Name PRIMARY KEY (Column1, Column2)
例1-複合主キーを作成する
複合主キーを使用したデータベースの例を次に示します。
この例では、 PK_Test というデータベースを作成します。 :
CREATE DATABASE PK_Test;
データベースが作成されたので、先に進んでテーブルを作成しましょう。
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) );
この例では、BandMember
テーブルには複数列の主キーがあります。この場合、主キーの各列は別のテーブルの主キーへの外部キーでもありますが、これは必須ではありません。
上記のデータベース設計の背後にある理由は、ミュージシャンが多くのバンドのメンバーになる可能性があるということです。また、各バンドには多くのミュージシャンがいる可能性があります。したがって、私たちは多対多の関係を持っています。これがBandMember
の理由です テーブルが作成されます–Musician
間の相互参照テーブルとして使用されます テーブルとBand
テーブル。
バンドのメンバーであるミュージシャンはユニークな出来事である必要があるため、この特定のケースは複合主キーをサポートします。つまり、ミュージシャンが同じバンドのメンバーである複数の行は必要ありません。これはデータの整合性に違反します。また、このテーブルと別のテーブルの間に関係を作成したとしても、参照整合性を維持しようとすると大混乱を引き起こす可能性があります(ここで行います)。
例2–データの挿入
上記のコードを実行しただけで、データベースにデータをロードできます。
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 );
例3–基本的なクエリ
データがデータベースにあるので、クエリを実行してそのデータの一部を返しましょう。
基本的なクエリは次のとおりです:
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;
結果:
+------------------+-------------+ | 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 | +------------------+-------------+
したがって、予想どおり、これはBandMember
にエントリがあるミュージシャンとバンドのみを返します。 参照表。
例4–わずかに変更されたクエリ
これは、結果を別の方法で表示する上記のクエリの修正バージョンです。
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;
結果:
+-------------+------------------------------------------------------+ | Band | Musicians | |-------------+------------------------------------------------------| | Deep Purple | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans | | Rainbow | Roger Glover, Richie Blackmore | | Whitesnake | Ian Paice | +-------------+------------------------------------------------------+
ここでは、結果がバンドごとにグループ化され、各バンドのすべてのミュージシャンがすべて、1つのフィールドにコンマ区切りのリストとして表示されます。
これを行うには、STRING_AGG()
を使用します ミュージシャンを連結する機能。
複合外部キー
上記の例の問題は、ほとんどのデータが古くなっていることです。これらのミュージシャンの何人かは実際にそれらのバンドを去りました。そして、何人かは去って、後日戻ってきました。
どうすればこれに対処できますか?
各ミュージシャンが各バンドのメンバーである期間を記録するために、別の参照テーブルを作成できます。このようなテーブルは、BandMember
を参照する必要があります 外部キーを介したテーブル。また、このテーブルには複合主キーがあるため、それを参照する新しいテーブルで複合外部キーを使用する必要があります。
例については、SQLServerで複合外部キーを作成する方法を参照してください。この記事では、上記の複合主キーを参照する複合外部キーを持つ追加のテーブルを除いて、上記と同じ例を使用しています。