我有一张名为Feed的表。该表将跟踪用户创建的不同类型(照片,事件,状态等)的社交对象。现在我有2个设计选择。
CREATE TABLE [dbo].[Feed](
[feedId] [int] IDENTITY(1,1) NOT NULL,
[objectTypeId] [int] NULL,
[objectId] [datetime] NOT NULL
)
CREATE TABLE [dbo].[ObjectType](
[typeId] [int] IDENTITY(1,1) NOT NULL,
[name] [NVARCHAR] NULL
)
然后,对象类型将包含所有可能类型的列表。 但我讨厌这种方法。原因是,我无法在数据库上强制执行参照完整性。
如果在其中一个表中删除了某个对象,则Feed中的objectId值指向一个不存在的对象。
另外,这里的Join语句很乱。您必须硬编码具有硬值的表,例如LEFT JOIN Events ON feed.objectTypeId = 2 AND feed.objectId = Events.eventId etc ...
PRO:可以强制执行参照完整性。空列不会造成太多问题,因为它们不存储任何内容。无需创建其他对象类型表。
CREATE TABLE [dbo].[Feed](
[feedId] [int] IDENTITY(1,1) NOT NULL,
[eventId] [int] NULL,
[photoId] [int] NULL,
[statusId] [int] NULL,
)
但是这个表并没有真正感觉到正常化。
那么,做我想做的事情的最佳方式是什么,并实现我的目标。参考完整性,而不必在每次添加新对象类型时更改模式。
忘了指出那些对象的表格......我有表格
CREATE TABLE [Events](
eventId INT, 其他cols只处理事件。 )
CREATE TABLE [Photos](
photoId INT, 其他只处理照片的cols )
CREATE TABLE [Status](
statusId INT, 其他只处理状态的cols )
答案 0 :(得分:0)
选择2很糟糕,会导致噩梦。您必须为每种新类型的内容添加新列。
我不知道为什么你认为选择1需要复杂的连接。要检索所有事件,例如:
SELECT * FROM Feed where objectTypeID =
(SELECT objectTypeID from ObjectType WHERE name = 'Event')
关于参照完整性:
如果在其中一个表中删除了某个对象,则Feed中的objectId值指向一个不存在的对象。
我不明白。如果Feed中的对象被删除,则没有悬空引用。如果删除了ObjectType,您打算如何处理该类型的对象?
我假设您意识到ObjectType表很小,每种类型的对象只有一行......对吗?
已编辑添加:
您提到的其他表格都需要FeedID
列。您应该不将对象ID放在Feed
表中。 (这假设每个对象只属于一个Feed。)
答案 1 :(得分:0)
如果Feed类型的数量较少,那么为每种Feed类型设置单独的表会不会更好?
以下内容可分为各自的表格。
答案 2 :(得分:0)
面对类似的问题,我选择为每种类型的对象创建一个单独的表。每个表都有一个唯一的标识,例如每行PhotoId
。它也有适当的外国参考,例如到FeedId
。 (如果可以共享对象,则可以添加链接表以允许对象位于多个位置。)这样可以最大程度地灵活地将正确的数据保存在正确的位置,例如: Height
和Width
可能适用于照片。
触发器用于根据需要验证和协调更新。
视图可用于汇总数据。它们集中了表之间的连接,并可以强制执行其他规则。