Một khóa chính tổng hợp là một khóa chính gồm nhiều cột. Microsoft thường gọi chúng là khóa chính nhiều cột trong tài liệu của mình.
Bài viết này cung cấp một ví dụ về cách tạo khóa chính tổng hợp bằng Transact-SQL trong SQL Server.
Bạn có thể tạo khóa chính tổng hợp giống như cách bạn tạo một khóa chính, ngoại trừ việc thay vì chỉ định chỉ một cột, bạn cung cấp tên của hai hoặc nhiều cột, được phân tách bằng dấu phẩy.
Như thế này:
CONSTRAINT PK_Name PRIMARY KEY (Column1, Column2)
Ví dụ 1 - Tạo khóa chính tổng hợp
Dưới đây là ví dụ về cơ sở dữ liệu sử dụng khóa chính tổng hợp.
Với mục đích của ví dụ này, tôi sẽ tạo một cơ sở dữ liệu có tên là PK_Test :
TẠO CƠ SỞ DỮ LIỆU PK_Test;
Bây giờ cơ sở dữ liệu đã được tạo, hãy tiếp tục và tạo các bảng.
SỬ DỤNG PK_Test; TẠO BẢNG Nhạc sĩ (MusicianId int NOT NULL, FirstName varchar (60), LastName varchar (60), CONSTRAINT PK_Musician PRIMARY KEY (MusicianID)); TẠO BẢNG Band (BandId int NOT NULL, BandName varchar (255) , CONSTRAINT PK_Band KEY CHÍNH (BandId)); TẠO BẢNG BandMember (MusicianId int NOT NULL, BandId int NOT NULL, CONSTRAINT PK_BandMember PRIMARY KEY (MusicianID, BandId), CONSTRAINT FK_BandMember_BINT FOREIGN KEY (BandId KEY (MusicianId) TÀI LIỆU THAM KHẢO Nhạc sĩ (MusicianId));
Trong ví dụ này, BandMember
bảng có khóa chính nhiều cột. Trong trường hợp này, mỗi cột trong khóa chính cũng là một khóa ngoại đối với khóa chính của bảng khác, nhưng đây không phải là một yêu cầu bắt buộc.
Lý do đằng sau thiết kế cơ sở dữ liệu trên là một nhạc sĩ có thể là thành viên của nhiều ban nhạc. Ngoài ra, mỗi ban nhạc có thể có nhiều nhạc sĩ. Vì vậy, chúng tôi có một mối quan hệ nhiều-nhiều. Đây là lý do tại sao BandMember
bảng được tạo - nó được sử dụng làm bảng tham chiếu chéo giữa Musician
bảng và Band
bàn.
Trường hợp cụ thể này hỗ trợ khóa chính tổng hợp, bởi vì một nhạc sĩ là thành viên của ban nhạc nên là một lần xuất hiện duy nhất. Nói cách khác, chúng tôi không muốn có nhiều hàng với một nhạc sĩ là thành viên của cùng một ban nhạc. Điều đó sẽ vi phạm tính toàn vẹn của dữ liệu. Nó cũng có thể gây ra sự tàn phá khi cố gắng duy trì tính toàn vẹn của tham chiếu ngay cả khi chúng tôi tạo mối quan hệ giữa bảng này với bảng khác (mà chúng tôi làm ở đây).
Ví dụ 2 - Chèn dữ liệu
Chỉ cần chạy đoạn mã trên, bây giờ tôi có thể tải cơ sở dữ liệu với dữ liệu:
CHÈN VÀO Nhạc sĩVALUES (1, 'Ian', 'Paice'), (2, 'Roger', 'Glover'), (3, 'Richie', 'Blackmore'), (4, 'Rod', ' Evans '), (5,' Ozzy ',' Osbourne '); CHÈN VÀO BandVALUES (1,' Deep Purple '), (2,' Rainbow '), (3,' Whitesnake '), (4,' Iron Maiden '); CHÈN VÀO BandMemberVALUES (1, 1), (1, 3), (2, 1), (2, 2), (3, 1), (3, 2), (4, 1);Ví dụ 3 - Truy vấn cơ bản
Bây giờ dữ liệu đó đã có trong cơ sở dữ liệu của chúng tôi, hãy chạy truy vấn để trả về một số dữ liệu đó.
Đây là một truy vấn cơ bản:
SELECT CONCAT (m.FirstName, '', m.LastName) AS 'Nhạc sĩ', b.BandName AS 'Band'FROM Nhạc sĩ mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b ON b.BandId =bm .BandId VÀ m.MusicianId =bm.MusicianId;Kết quả:
+ ------------------ + ------------- + | Nhạc sĩ | Ban nhạc || ------------------ + ------------- || Ian Paice | Màu tím đậm || Ian Paice | Whitesnake || Roger Glover | Màu tím đậm || Roger Glover | Cầu vồng || Richie Blackmore | Màu tím đậm || Richie Blackmore | Cầu vồng || Rod Evans | Màu tím đậm | + ------------------ + ------------- +Vì vậy, như mong đợi, điều này chỉ trả về những nhạc sĩ và ban nhạc có mục nhập trong
BandMember
bảng tham chiếu.Ví dụ 4 - Truy vấn được sửa đổi một chút
Dưới đây là phiên bản sửa đổi của truy vấn ở trên trình bày kết quả theo một cách khác:
SELECT b.BandName AS 'Band', STRING_AGG (CONCAT (m.FirstName, '', m.LastName), ',') AS 'Musicians'FROM Nhạc sĩ mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b ON b.BandId =bm.BandId VÀ m.MusicianId =bm.MusicianIdGROUP BY b.BandName;Kết quả:
+ ------------- + -------------------------------- ---------------------- + | Ban nhạc | Nhạc sĩ || ------------- + --------------------------------- --------------------- || Màu tím đậm | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans || Cầu vồng | Roger Glover, Richie Blackmore || Whitesnake | Ian Paice | + ------------- + -------------------------------- ---------------------- +Tại đây, kết quả được nhóm theo ban nhạc và tất cả các nhạc sĩ của mỗi ban nhạc đều được hiển thị dưới dạng danh sách được phân tách bằng dấu phẩy trong một trường duy nhất.
Để thực hiện việc này, tôi sử dụng
STRING_AGG()
chức năng nối các nhạc công.Khoá ngoại tổng hợp
Vấn đề với ví dụ trên là hầu hết dữ liệu đã lỗi thời. Một số nhạc sĩ đã thực sự rời khỏi các ban nhạc đó. Và một số đã rời đi và sau đó quay trở lại vào một ngày sau đó.
Chúng ta có thể giải quyết vấn đề này như thế nào?
Chúng tôi có thể tạo một bảng tham chiếu khác để ghi lại khoảng thời gian mà mỗi nhạc sĩ là thành viên của mỗi ban nhạc. Một bảng như vậy sẽ cần tham chiếu đến
BandMember
bảng thông qua một khóa ngoại. Và vì bảng này có khóa chính tổng hợp, chúng tôi sẽ cần sử dụng khóa ngoại tổng hợp trên bảng mới tham chiếu đến nó.Xem Cách tạo khóa ngoại tổng hợp trong SQL Server để làm ví dụ. Bài viết đó sử dụng cùng một ví dụ như trên, ngoại trừ một bảng phụ có khóa ngoại tổng hợp tham chiếu đến khóa chính tổng hợp ở trên.