我有一些名称为联系人,关注,任务,门票,帐户和...的表格 上述每个表都应与Notifications表有关。
现在我在SQL中使用此结构用于Notifications表来创建它们之间的关系:
Id, ContactId, FollowId, TaskId, TicketId, AccountId, Text
Id
是主键,ContactId
,FollowId
,TaskId
,TicketId
,AccountId
应为外键。
每次将记录添加到此表时,只有此外键列表的一列有值,如下所示:
Id ContactId FollowId TaskId TicketId AccountId Text
1 null null null null 2 notification test 1
2 null null null 12 null notification test 2
3 null null null 11 null notification test 3
4 5 null null null null notification test 4
5 null 1 null null null notification test 5
6 null null null null 3 notification test 6
7 null null null null 43 notification test 7
这是一个很好的架构师,不会拒绝databBase中的规范化吗?
答案 0 :(得分:1)
您创建的结构是非规范化结构,不适合OLTP环境。
以下是理想的规范化结构
Notifications Contacts
Notifications Follows
Notifications Tasks
Notifications Tickets
Notifications Accounts
答案 1 :(得分:0)
这是一个很好的解决方案吗?好吧,不是真的。但是SQL并没有为与其他实体相关的实体(例如notations
)提供一个很好的解决方案。
此特定解决方案的优点是您可以声明外键关系。它的缺点是添加新的实体类型需要重组表,并且每个NULL
值占用空间。因此,它不具有特别的可扩展性。
没有完美的解决方案。如果您愿意放弃外键关系,您可以这样做:
create table notifications (
notificationId int identity(1, 1) primary key,
notificationType varchar(32),
relatedId int,
check notificationType in ('contact', . . .)
);
不幸的是,SQL Server没有过滤外键关系。你可以这样做:
create table contacts (
contactId int identity(1, 1) primary key,
. . .
);
create table n (
id int identity(1, 1),
relatedId int,
notificationType varchar(32),
contactId as (case when type = 'contact' then relatedId end) persisted,
foreign key (contactId) references contacts(contactId)
);
这几乎可以满足您的需求。问题是需要持久化contactId
才能在外键关系中使用 - 并且持久化的计算列仍占用空间。