最佳多关系表对象类型设计

时间:2012-08-22 20:14:54

标签: sql sql-server tsql foreign-keys

我有一张名为Feed的表。该表将跟踪用户创建的不同类型(照片,事件,状态等)的社交对象。现在我有2个设计选择。

CHOICE 1:objectTypeId,objectId:

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 ...

CHOICE 2:ADD eventId NULL,photoId NULL,statusId NULL或任何其他objectTypeId到Feed表

PRO:可以强制执行参照完整性。空列不会造成太多问题,因为它们不存储任何内容。无需创建其他对象类型表。

CREATE TABLE [dbo].[Feed](
[feedId] [int] IDENTITY(1,1) NOT NULL,
[eventId] [int] NULL,
[photoId] [int] NULL,
[statusId] [int] NULL,
)

但是这个表并没有真正感觉到正常化。

那么,做我想做的事情的最佳方式是什么,并实现我的目标。参考完整性,而不必在每次添加新对象类型时更改模式。

UPDATE:

忘了指出那些对象的表格......我有表格

CREATE TABLE [Events](

eventId INT, 其他cols只处理事件。 )

CREATE TABLE [Photos](

photoId INT, 其他只处理照片的cols )

CREATE TABLE [Status](

statusId INT, 其他只处理状态的cols )

3 个答案:

答案 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类型设置单独的表会不会更好?

以下内容可分为各自的表格。

  1. 照片
  2. 活动
  3. 以下状态

答案 2 :(得分:0)

面对类似的问题,我选择为每种类型的对象创建一个单独的表。每个表都有一个唯一的标识,例如每行PhotoId。它也有适当的外国参考,例如到FeedId。 (如果可以共享对象,则可以添加链接表以允许对象位于多个位置。)这样可以最大程度地灵活地将正确的数据保存在正确的位置,例如: HeightWidth可能适用于照片。

触发器用于根据需要验证和协调更新。

视图可用于汇总数据。它们集中了表之间的连接,并可以强制执行其他规则。