最初,我为上述每个 [创建] 单独的注释表,并将它们合并到一个视图中。
这让我想知道您是否考虑过使用没有 NULLable 列的多表结构,其中每个注释都获得一个唯一 ID,而不管类型如何。您可以在不使用UNION
.
下面是一个建议的结构。我已更改为 VARCHAR 以使不同的类型更清晰、更易于阅读(无论如何NoteTypeId
您都没有枚举值):INTEGER
CREATE TABLE Notes
(
Id INTEGER IDENTITY(1,1) NOT NULL UNIQUE,
NoteType VARCHAR(11) NOT NULL
CHECK (NoteType IN ('Account', 'Order', 'Order line')),
Note VARCHAR(300) NOT NULL,
UNIQUE (Id, NoteType)
);
CREATE TABLE AccountNotes
(
Id INTEGER NOT NULL UNIQUE,
NoteType VARCHAR(11)
DEFAULT 'Account'
NOT NULL
CHECK (NoteType = 'account'),
FOREIGN KEY (Id, NoteType)
REFERENCES Notes (Id, NoteType)
ON DELETE CASCADE,
AccountId INTEGER NOT NULL
REFERENCES Accounts (AccountId)
);
CREATE TABLE OrderNotes
(
Id INTEGER NOT NULL UNIQUE,
NoteType VARCHAR(11)
DEFAULT 'Order'
NOT NULL
CHECK (NoteType = 'Order'),
FOREIGN KEY (Id, NoteType)
REFERENCES Notes (Id, NoteType)
ON DELETE CASCADE,
OrderId INTEGER NOT NULL
REFERENCES Orders (OrderId)
);
CREATE TABLE OrderLineNotes
(
Id INTEGER NOT NULL UNIQUE,
NoteType VARCHAR(11)
DEFAULT 'Order line'
NOT NULL
CHECK (NoteType = 'Order line'),
FOREIGN KEY (Id, NoteType)
REFERENCES Notes (Id, NoteType)
ON DELETE CASCADE,
OrderLineId INTEGER NOT NULL
REFERENCES OrderLines (OrderLineId)
);
以“单表继承”结构(即所有JOIN
s 和没有UNION
s)呈现数据:
SELECT N1.Id, N1.NoteType, N1.Note,
AN1.AccountId,
ON1.OrderId,
OLN1.OrderLineId
FROM Notes AS N1
LEFT OUTER JOIN AccountNotes AS AN1
ON N1.Id = AN1.Id
LEFT OUTER JOIN OrderNotes AS ON1
ON N1.Id = ON1.Id
LEFT OUTER JOIN OrderLineNotes AS OLN1
ON N1.Id = OLN1.Id;
考虑到上述结构具有完整的数据完整性约束。要使用“单表继承”结构来做同样的事情,需要更多的CHECK
约束,其中有许多可空列的条件,例如
CHECK (
(
AccountId IS NOT NULL
AND OrderId IS NULL
AND OrderLineId IS NULL
)
OR
(
AccountId IS NULL
AND OrderId IS NOT NULL
AND OrderLineId IS NULL
)
OR
(
AccountId IS NULL
AND OrderId IS NULL
AND OrderLineId IS NOT NULL
)
);
CHECK (
(
NoteType = 'Account'
AND AccountId IS NOT NULL
)
OR
(
NoteType = 'Order'
AND OrderId IS NOT NULL
)
OR
(
NoteType = 'Order line'
AND OrdereLineId IS NOT NULL
)
);
etc etc
我敢打赌,大多数使用“单表继承”的应用程序开发人员根本不会费心去创建这些数据完整性约束,如果他们想到这样做的话(这听起来并不粗鲁,只是对我们来说,优先级有所不同)比“前端”更关心“后端”:)