将表格链接到2个不同的键的最佳方法是什么?

时间:2009-07-09 12:33:12

标签: mysql database-design foreign-keys

我正在设计一个mySQL数据库,我遇到了以下问题:

说我有一个wall_posts表。墙可以属于事件或用户。 因此wall_posts表必须引用event_iduser_id(外键约束)。

建立这种关系的最佳方式是什么,考虑到我必须始终能够知道墙壁属于谁......?

我一直在考虑使用2个表格,例如event_wall_postsuser_wall_posts,因此有一个event_id字段,另一个有user_id字段,但我相信那里必须比这种多余的解决方案好得多......

有没有办法使用中间表将wall_postsevent_iduser_id相关联?

提前致谢,

编辑:似乎没有明确的设计可以做到这一点,这两种方法似乎都没问题,所以, 如果有大量数据,哪一个会最快?

是否最好有2个分隔表(因此查询可能会更快,因为表格中的数据会少两倍......),或者仍然优先选择具有单个{{1}的更好的OO方法}表引用一个墙表(然后是两个用户和wall_posts wall_id`)

5 个答案:

答案 0 :(得分:4)

为什么多余?您不会编写两次代码来处理它们,您将使用相同的代码,只需更改SQL中表的名称即可 采用这种方法的另一个原因是,在未来的某个时间,您会发现每个实体都需要新的不同的字段。

答案 1 :(得分:2)

您所谈论的内容被称为独占弧,这不是一个好习惯。执行参照完整性很难。在对象意义上,你可能最好使用一种常见的超类型。

可以通过以下两种方式建模:

  1. 一个名为wall的超类表。两个子类型表(user_wall和event_wall)分别链接到用户和事件作为所有者。 wall_posts表链接到超类型表;或
  2. 将两种实体类型放在一个表中并具有一个类型列。这样你就不会链接到两个单独的表。

答案 2 :(得分:2)

选择最简单的解决方案:将event_id和user_id列添加到wall_posts表中。使用约束强制执行其中一个为空,另一个不为。

对我来说,任何更复杂的气味都像过度标准化一样:)

答案 3 :(得分:1)

解决这个问题的经典方法是:

  • 创建一个名为wall_container的表格,并保留其中usersevents共有的属性
  • usersevents都引用到wall_container
  • 参考wall_postswall_container

但是,效率并不高,并且无法保证此wall_container不会包含非userevent的记录。

SQL在处理多重继承方面不是特别好。

答案 4 :(得分:0)

你的墙和活动有自己独特的ID ..对吧?然后他们不需要另一张桌子。让wall_post表有一个属性作为origin,它将指向记录是事件或用户的记录。 “

如果墙和事件可能具有相同的ID,则创建一个包含三个属性origin(primary),ID number和type的表。 ID号将是您设置的类型,类型定义ID表示的实体类型,而原点将是您将生成的新ID,可能会添加不同的前缀。在相同ID的情况下,原始表将极大地帮助您除了墙贴之外的其他内容。