为多个数据集构建“注释”表的正确方法是什么?

时间:2011-02-03 21:58:47

标签: sql mysql database-design data-structures database-schema

请原谅标题,我的问题没有过于描述而没有问题。

我的应用程序有这样的表格:
联系人
属性
事件

我正在添加一种将备注附加到上表中的项目的方法。我希望这样一条音符可以与联系人,财产或事件(或三者的组合)相关联。

目前我的备注表格如下:

  

noteID int
  noteCreated数据时间
  noteContent text
  userID int(创建注释的用户ID
   contactID int
  propertyID int
  eventID int

有问题的部分以粗体显示。现在,当我为事件创建注释时,我只需插入注释并设置 eventID 。如果事件与联系人相关,我也可以添加 contactID (将设置contactID和eventID)。虽然它有效,但我认为它效率低下且未正确规范化。

我要做的是创建一对多的关系,问题是“很多”部分可以有不同的目标表。与此同时,我希望减少选择或插入笔记所需的查询次数。

我的想法是创建一个将它们连接在一起的表,然后为属性,联系人和事件提供他们自己保持不变的唯一targetType。但我仍然觉得这不是最好的方法。或者,我可以为每个目标表创建一个单独的关系表(notes_properties,notes_contacts等...)。

  

noteID int
  targetID int
  targetType int

很多人会感激不尽。谢谢:))

3 个答案:

答案 0 :(得分:3)

如果说明和联系人之间的关系,属性和&事件是1比1,例如,联系人只能有一个注释,那么建模它的最佳方法是简单地将noteID列添加到联系人,属性和事件表中。

如果它是多对多关系,例如,联系人可以有很多笔记,那么您可能想要创建一个单独的表,比如说contact_notes有两列 - contactID和{{ 1}}。

请注意,注释可以与多个实体相关联。它根本不会影响你建模的方式。

答案 1 :(得分:0)

如果你真的想把所有笔记保存在一个表中,我会建议这样的结构:

noteID
noteCreated
noteContent 
userID
noteType (contact, property or event)
RelatedID

然后你可以使用:

加入
FROM Contacts C
INNER JOIN Notes N on C.ID = N.RelatedID and N.noteType = 'contact'

FROM Property P
INNER JOIN Notes N on P.ID = N.RelatedID and N.noteType = 'property'

答案 2 :(得分:0)

你在描述什么......

  

我希望这样一条便条可以与联系人,财产或事件(或三者的组合)相关联。

...是经典的多对多关系的变体(附加假设一个联系人,属性或事件可以有多个音符以及处理四个表而不是两个表的额外复杂性)。

正确规范化这种情况的方法是使用一个中间表,其中包含您在问题中描述的字段:

noteID int
targetID int
targetType int

正如您所指出的那样,这会使某些查询更难写,效率更低。具体来说,外连接(因为我确定笔记是可选的,你几乎肯定需要它)将必须使用子查询。

我建议稍微进行非规范化并使用如下所示的中间表:

ID int          'autonumber to provide a reliable and efficient unique key'
noteID int
contactID int   'allow nulls'
propertyID int  'allow nulls'
eventID int     'allow nulls'