多余的表或者非特定的外键?
时间: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的交界处。
- 仍保留与标准(即,快速,简单,可靠)外键的关系