最初に、上記のそれぞれについて個別のメモテーブルを[作成]し、それらをビューで結合しました。
これは、タイプに関係なく各メモが一意の ID を取得する、NULL 可能な列のない複数テーブル構造の使用を検討したかどうか疑問に思います。を使用せずに、クエリで「単一テーブルの継承」(または同様のもの) でデータを提示できます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
があり、 がないUNION
):
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
null 許容列の多くの条件を持つ、さらに多くの制約が必要になります。
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
「単一テーブルの継承」を使用するほとんどのアプリケーション開発者は、これらのデータ整合性制約を作成することを思いついたとしても、わざわざ作成することはないと思います (失礼に聞こえるという意味ではありません。 「フロントエンド」よりも「バックエンド」に気を配ってください :)