多余的表或者非特定的外键?

时间:2020-03-05 18:46:34  来源:igfitidea点击:

系统中有几种类型的对象,每种对象在数据库中都有自己的表。用户应该能够对其中任何一个发表评论。我们将如何设计评论表?我可以想到一些选择:

  • 一个注释表,每个对象类型(ObjectAID,ObjectBID等)带有FK列
  • 几个注释表,每个对象类型一个(ObjectAComments,ObjectBComments等)
  • 一个通用FK(ParentObjectID),另一列指示类型(" ObjectA")

我们会选择哪一个?有我没有想到的更好的方法吗?

解决方案

回答

设计架构以使可注释的表(缺少更好的词)遵循一种标准的继承建模模式是否可行?如果是这样,则可以使注释表的FK指向公共父表。

回答

@汉克·盖伊

所以像这样:

  • 父母ID
  • 父母ID
  • 父母ID

回答

@palmsey

差不多,但是我最常看到的那种模式的变化却摆脱了" ObjectAID"等。 " ParentID"成为" Parents"的PK和FK。那会给你类似的东西:

  • ColumnFromA NOT NULL
  • ColumnFromB NOT NULL

"评论"将保持不变。然后,我们只需要限制ID的生成,这样就不会意外出现两个都指向同一"父代"行的" ObjectA"行和" ObjectB"行。最简单的方法是对ObjectA和ObjectB使用与"父母"相同的顺序(或者其他顺序)。

我们还会看到很多类似以下内容的架构:

  • SubclassDiscriminator
  • ColumnFromA(可为空)
  • ColumnFromB(可为空)

和"评论"将保持不变。但是现在,如果不编写触发器或者在不同的层上执行触发器,就无法实施所有业务约束(子类的属性都可以为空)。

回答

小心不要指向一个表的通用外键。如果必须拆分类型的where条件并指向几个不同的表,则查询性能会受到很大影响。如果我们只有几个类型,并且类型的数量不会增加,则可以为不同的表使用单独的可为空的外键,但是如果我们有更多的类型,则最好使用不同的数据模型(例如@palmsey的建议)。

回答

我想做的一件事情是有一个单独的表,将通用/公用表链接到所有个性化表。

因此,对于对象Foo和Bar然后在Foo&Bar上进行注释,我们将具有以下内容:

  • 评论文字
  • 评论编号(PK FK)
  • 评论编号(PK FK)

这个结构:

  • 让我们有一个通用的注释表
  • 不需要具有表继承功能的数据库
  • 不使用注释相关信息污染Foo和Bar表
  • 使我们可以将注释添加到多个对象(可能需要)
  • 如果需要,可将其他属性添加到Foo / Bar和Comment的交界处。
  • 仍保留与标准(即,快速,简单,可靠)外键的关系