Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara Membuat Kunci Asing Komposit di SQL Server (Contoh T-SQL)

kunci asing gabungan adalah kunci asing yang terdiri dari beberapa kolom.

Artikel ini memberikan contoh membuat kunci asing komposit menggunakan Transact-SQL di SQL Server.

Anda dapat membuat kunci asing gabungan seperti Anda membuat kunci asing tunggal, kecuali bahwa alih-alih menentukan hanya satu kolom, Anda memberikan nama dua kolom atau lebih, dipisahkan dengan koma.

Seperti ini:

CONSTRAINT FK_FKName FOREIGN KEY
 (FKColumn1, FKColumn2)
REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)

Contoh 1 – Membuat Kunci Asing Gabungan

Berikut adalah contoh database yang menggunakan kunci asing komposit (dan kunci utama komposit).

Untuk keperluan contoh ini, saya akan membuat database bernama BandTest :

CREATE DATABASE BandTest;

Sekarang setelah database dibuat, mari kita buat tabelnya.

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

CREATE TABLE MembershipPeriod (
MembershipPeriodId int NOT NULL,
MusicianId int NOT NULL,
BandId int NOT NULL,
StartDate date NOT NULL,
EndDate date NULL,
CONSTRAINT PK_MembershipPeriod PRIMARY KEY (MembershipPeriodID),
CONSTRAINT FK_MembershipPeriod_BandMember FOREIGN KEY (MusicianID, BandId) REFERENCES BandMember(MusicianID, BandId)
);

Dalam contoh ini, BandMember tabel memiliki kunci primer multikolom. MembershipPeriod tabel memiliki kunci asing yang mereferensikan kunci primer multikolom itu. Oleh karena itu, definisi kunci utama dan kunci asing menyertakan kolom yang dipisahkan oleh koma.

Alasan di balik desain database di atas adalah, seorang musisi berpotensi menjadi anggota dari banyak band. Juga, setiap band dapat memiliki banyak musisi. Jadi kita memiliki hubungan banyak-ke-banyak. Inilah sebabnya mengapa BandMember tabel dibuat – digunakan sebagai tabel referensi silang antara Musician tabel dan Band meja. Dalam hal ini, saya telah memilih untuk menggunakan kunci primer komposit.

Tetapi seorang musisi juga bisa menjadi anggota sebuah band pada lebih dari satu kesempatan (misalnya seorang musisi mungkin meninggalkan sebuah band, hanya untuk kembali lagi nanti). Oleh karena itu, MembershipPeriod tabel dapat digunakan untuk merekam semua periode setiap musisi telah menjadi anggota dari setiap band. Ini perlu mereferensikan kunci utama komposit pada BandMember tabel, jadi saya perlu membuat kunci asing multikolom.

Contoh 2 – Sisipkan Data

Setelah menjalankan kode di atas, sekarang saya dapat memuat database dengan data:

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

INSERT INTO MembershipPeriod
VALUES 
( 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' );

Contoh 3 – Kueri Dasar

Berikut ini contoh kueri yang dapat dijalankan terhadap database:

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

Hasil:

+------------------+-------------+------------+------------+
| Musician         | Band        | Start      | End        |
|------------------+-------------+------------+------------|
| 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     | Rainbow     | 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 | Rainbow     | 1975-02-01 | 1984-04-01 |
| Richie Blackmore | Rainbow     | 1993-11-17 | 1997-05-31 |
| Richie Blackmore | Rainbow     | 2015-01-01 | NULL       |
| Rod Evans        | Deep Purple | 1968-03-01 | 1969-12-01 |
+------------------+-------------+------------+------------+

Jadi sekarang kita bisa melihat tanggal berapa setiap musisi menjadi anggota dari setiap band, meskipun mereka menjadi anggota beberapa kali.

Contoh 4 – Kueri yang Sedikit Dimodifikasi

Kami dapat memodifikasi kueri di atas untuk memberikan hasil dalam format yang sedikit lebih mudah dibaca:

SELECT 
  CONCAT(m.FirstName, ' ', m.LastName) AS 'Musician',
  b.BandName AS 'Band',
  STRING_AGG(
    CONCAT(FORMAT(mp.StartDate, 'yyyy'), '-', ISNULL(FORMAT(mp.EndDate, 'yyyy'), 'present')), ', ') AS 'Time with the 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
JOIN MembershipPeriod mp
ON mp.BandId = b.BandId AND mp.MusicianId = m.MusicianId
GROUP BY m.FirstName, m.LastName, b.BandName;

Hasil:

+------------------+-------------+------------------------------------+
| Musician         | Band        | Time with the band                 |
|------------------+-------------+------------------------------------|
| Ian Paice        | Deep Purple | 1968-1976, 1984-present            |
| Ian Paice        | Whitesnake  | 1979-1982                          |
| Richie Blackmore | Deep Purple | 1968-1975, 1984-1993               |
| Richie Blackmore | Rainbow     | 1975-1984, 1993-1997, 2015-present |
| Rod Evans        | Deep Purple | 1968-1969                          |
| Roger Glover     | Deep Purple | 1969-1973, 1984-present            |
| Roger Glover     | Rainbow     | 1979-1984                          |
+------------------+-------------+------------------------------------+

Contoh ini memanfaatkan STRING_AGG() berfungsi untuk menggabungkan berbagai periode waktu untuk setiap musisi. Hal ini pada akhirnya mengurangi jumlah baris yang diperlukan, dan memungkinkan kita untuk mengelompokkan periode waktu bersama-sama dalam bidang yang sama.

Saya juga memanfaatkan ISNULL() fungsi, yang memungkinkan saya untuk mengubah nilai NULL menjadi sesuatu yang lebih bermakna.

Perhatikan bahwa ISNULL() mensyaratkan bahwa argumen kedua adalah tipe yang dapat secara implisit dikonversi ke tipe argumen pertama. Dalam hal ini, argumen pertama awalnya adalah tanggal type, yang berarti saya tidak akan dapat menggunakan string. Namun, dalam hal ini saya memutuskan untuk menggunakan FORMAT() berfungsi untuk memformat tanggal nilai. Fungsi ini secara implisit mengonversi tanggal nilai ke string, dan karena itu saya dapat menggunakan string untuk argumen kedua.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa itu DATALENGTH() di SQL Server?

  2. Cara membuat banyak satu ke satu

  3. Berapa ukuran batch yang direkomendasikan untuk SqlBulkCopy?

  4. Di SQL Server, bagaimana cara menghasilkan pernyataan CREATE TABLE untuk tabel yang diberikan?

  5. Cara Mengonversi String ke Tanggal/Waktu di SQL Server menggunakan CAST()