Đầu tiên, có một quy tắc thiết kế là một mô hình bảng hoặc là một loại thực thể duy nhất hoặc mối quan hệ giữa các loại thực thể nhưng không phải cả hai. Do đó, tôi hình dung ba bảng, Media
(thực thể), Idea
(thực thể) và IdeasMedia
(mối quan hệ). p.s. bạn biết số ít của 'phương tiện' là 'trung bình', đúng không? :)
Dưới đây là một số tiêu chuẩn DDL SQL-92 tập trung vào duy nhất phím:
CREATE TABLE Media (MediaID INTEGER NOT NULL UNIQUE);
CREATE TABLE Idea (IdeaID INTEGER NOT NULL UNIQUE);
CREATE TABLE IdeasMedia
(
MediaID INTEGER NOT NULL REFERENCES Media (MediaID),
IdeaID INTEGER NOT NULL REFERENCES Idea (IdeaID)
);
CREATE ASSERTION Idea_must_have_media DEFERRABLE
CHECK (
NOT EXISTS (
SELECT *
FROM Idea AS i
WHERE NOT EXISTS (
SELECT *
FROM IdeasMedia AS im
WHERE im.MediaID = i.IdeaID
)
)
);
Có một 'gà và quả trứng' kịch bản ở đây: không thể tạo ra một ý tưởng với không có tham khảo IdeasMedia
nhưng có thể Không tạo ra một IdeasMedia
mà không cần tạo một Idea
!
Giải pháp lý tưởng (dựa trên cơ sở) sẽ là cho SQL Standard để hỗ trợ nhiều nhiệm vụ, ví dụ:
INSERT INTO Media (MediaID) VALUES (22),
INSERT INTO Idea (IdeaID) VALUES (55),
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55);
trong đó dấu chấm phẩy biểu thị ranh giới câu lệnh SQL tại điểm nào được kiểm tra và dấu phẩy biểu thị các câu lệnh phụ.
Đáng buồn thay, không có kế hoạch thêm mô hình dựa trên tập này vào Chuẩn SQL.
SQL-92 (thủ tục) giải pháp này như sau:
BEGIN TRANSACTION;
INSERT INTO Media (MediaID) VALUES (22);
SET CONSTRAINTS Idea_must_have_media DEFERRED;
-- omit the above if the constraint was declared as INITIALLY DEFERRED.
INSERT INTO Idea (IdeaID) VALUES (55);
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (55, 22);
SET CONSTRAINTS Idea_must_have_media IMMEDIATE;
-- above may be omitted: constraints are checked at commit anyhow.
COMMIT TRANSACTION;
Đáng buồn thay, SQL Server không hỗ trợ CREATE ASSERTION
cũng không CHECK
ngại rằng có thể tham khảo các bảng khác cũng không khó khăn deferrable!
Cá nhân, tôi sẽ xử lý này trong SQL Server như sau:
- Tạo 'helper' lưu trữ procs để thêm, sửa đổi và loại bỏ
Ideas
và tương ứng của họ IdeasMedia
mối quan hệ.
- Xóa đặc quyền cập nhật khỏi các bảng để buộc người dùng sử dụng các procs .
- Có thể sử dụng trình kích hoạt để xử lý các trường hợp khi xóa các đối tượng
Media
và Idea
.
Chắc chắn, điều này (một lần nữa thủ tục) thực hiện được xa rời phương pháp lý tưởng thiết lập dựa trên, mà có lẽ giải thích lý do tại sao hầu hết các lập trình SQL nhắm mắt làm ngơ để một yêu cầu cho một 1: mối quan hệ 1..N và thay vào đó giả sử nhà thiết kế có nghĩa là 1: 0..N !!
Tôi không chắc chắn làm thế nào bạn có thể làm điều này với việc giữ 'Media' trong một bảng riêng biệt: làm thế nào bạn sẽ chèn dữ liệu? Trước tiên, bạn phải chèn vào một bảng, sau đó nhập vào bảng thứ hai. Những gì bạn có thể thử làm là đặt 'Media' đầu tiên vào' Idea' (không chuẩn hóa) và khai báo các trường là 'không null' - nhưng tôi sẽ không khuyến khích nó. Bạn có thể tốt hơn với một số logic trong mã chứ không phải là cơ sở dữ liệu. –
Tôi đồng ý với Aleks. Tôi nghĩ rằng đây là một quy tắc kinh doanh thuộc về tầng giữa ở đâu đó, không phải trong cơ sở dữ liệu. – David
@Aleks gắn một FK NOT NULL từ Idea to Media không phải là không phổ biến. Nó đơn giản, và vâng, anh ta sẽ cần phải điền vào Media trước. – vol7ron