Tôi bắt gặp một tình huống trong cơ sở dữ liệu khá thường xuyên khi một bảng đã cho có thể FK đến một trong số các bảng cha khác nhau. Tôi đã thấy hai giải pháp cho vấn đề này, nhưng cả hai đều không thỏa mãn cá nhân. Tôi tò mò không biết những mẫu khác mà bạn đã thấy ngoài kia? Có cách nào tốt hơn để làm điều đó?
Một ví dụ giả định
Hãy nói rằng hệ thống của tôi có Alerts
. Cảnh báo có thể được nhận cho nhiều đối tượng - Khách hàng, Tin tức và Sản phẩm. Một cảnh báo nhất định có thể dành cho một và chỉ một mục. Vì bất kỳ lý do gì, Khách hàng, Bài viết và Sản phẩm đều di chuyển nhanh (hoặc được bản địa hóa) để văn bản / dữ liệu cần thiết có thể được kéo vào Cảnh báo khi tạo Thông báo. Đưa ra thiết lập này, tôi đã thấy hai giải pháp.
Lưu ý: Dưới đây DDL dành cho SQL Server nhưng câu hỏi của tôi nên được áp dụng cho bất kỳ DBMS nào.
Giải pháp 1 - Nhiều khóa Fullable
Trong giải pháp này, bảng liên kết đến một trong nhiều bảng có nhiều Cột FK (vì đơn giản là DDL dưới đây không hiển thị việc tạo FK). TỐT - Trong giải pháp này, thật tuyệt khi tôi có khóa ngoại. Tính không tối ưu của FK giúp cho việc thêm dữ liệu chính xác trở nên thuận tiện và tương đối dễ dàng. Truy vấn BAD không tuyệt vời vì nó yêu cầu các câu lệnh N LEFT THAM GIA hoặc N UNION để có được dữ liệu liên quan. Trong SQL Server, cụ thể là LEFT THAM GIA ngăn chặn việc tạo chế độ xem được lập chỉ mục.
CREATE TABLE Product (
ProductID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
CONSTRAINT PK_Product Primary Key CLUSTERED (ProductID)
)
CREATE TABLE Customer (
CustomerID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
CONSTRAINT PK_Customer Primary Key CLUSTERED (CustomerID)
)
CREATE TABLE News (
NewsID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
CONSTRAINT PK_News Primary Key CLUSTERED (NewsID)
)
CREATE TABLE Alert (
AlertID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
ProductID int null,
NewsID int null,
CustomerID int null,
CONSTRAINT PK_Alert Primary Key CLUSTERED (AlertID)
)
ALTER TABLE Alert WITH CHECK ADD CONSTRAINT CK_OnlyOneFKAllowed
CHECK (
(ProductID is not null AND NewsID is null and CustomerID is null) OR
(ProductID is null AND NewsID is not null and CustomerID is null) OR
(ProductID is null AND NewsID is null and CustomerID is not null)
)
Giải pháp 2 - Một FK trong mỗi Bảng cha
Trong giải pháp này, mỗi bảng 'cha mẹ' có một FK cho bảng Thông báo. Nó giúp dễ dàng truy xuất các cảnh báo liên quan đến cha mẹ. Về phía bên dưới, không có chuỗi thực sự từ Thông báo đến người tham chiếu. Hơn nữa, mô hình dữ liệu cho phép Cảnh báo mồ côi - nơi cảnh báo không được liên kết với Sản phẩm, Tin tức hoặc Khách hàng. Một lần nữa, nhiều LEFT THAM GIA để tìm ra sự liên kết.
CREATE TABLE Product (
ProductID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
AlertID int null,
CONSTRAINT PK_Product Primary Key CLUSTERED (ProductID)
)
CREATE TABLE Customer (
CustomerID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
AlertID int null,
CONSTRAINT PK_Customer Primary Key CLUSTERED (CustomerID)
)
CREATE TABLE News (
NewsID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
AlertID int null,
CONSTRAINT PK_News Primary Key CLUSTERED (NewsID)
)
CREATE TABLE Alert (
AlertID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
CONSTRAINT PK_Alert Primary Key CLUSTERED (AlertID)
)
Đây chỉ là cuộc sống trong một cơ sở dữ liệu quan hệ? Có giải pháp thay thế nào bạn thấy thỏa mãn hơn không?
Alertable
. Điều đó có ý nghĩa gì?