Изначально я [создал] отдельные заметки
таблица для каждого из вышеперечисленных и
объединяю их в представлении.
Это заставляет меня задуматься, рассматривали ли вы возможность использования многостоловой структуры без столбцов NULLable, где каждая заметка получает уникальный идентификатор независимо от типа. Вы можете представить данные в «наследовании одной таблицы» (или аналогично) в запросе, не используя UNION
.
Ниже предлагается структура. Я изменил NoteTypeId
на VARCHAR, чтобы сделать разные типы более понятными и удобными для чтения (вы все равно не перечислили значения 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
со многими, многими условиями для столбцов, допускающих обнуляемость, например
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
Держу пари, что большинство разработчиков приложений, использующих «наследование одной таблицы», не будут беспокоиться о создании этих ограничений целостности данных, если им вообще придется это делать (это не должно звучать грубо, просто разница в приоритетах) для нас, которые больше заботятся о «бэкэнде», чем о «бэкэнде»:)