额外的表或非特定的外键?

时间:2008-09-02 16:15:15

标签: database-design foreign-keys normalization

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

  1. 一个注释表,每个对象类型都有一个FK列(ObjectAID,ObjectBID等)
  2. 几个注释表,每个对象类型一个(ObjectAComments,ObjectBComments等)
  3. 一个通用FK(ParentObjectID),另一列用于指示类型(“ObjectA”)
  4. 你会选择哪个?有没有更好的方法我没想到?

5 个答案:

答案 0 :(得分:1)

设计模式是否可行,以便可评论(缺少更好的单词)表遵循标准继承建模模式之一?如果是这样,您可以将注释表的FK指向公共父表。

答案 1 :(得分:1)

@palmsey

相当多,但我见过的那种模式的变化经常摆脱ObjectAID等。 ParentID成为Parents的PK和FK。这会让你感觉像是:

  • Parents

    • ParentID
  • ObjectA

    • ParentID(FK和PK)
    • ColumnFromA NOT NULL
  • ObjectB

    • ParentID(FK和PK)
    • ColumnFromB NOT NULL

Comments将保持不变。然后你只需要约束ID生成,这样你就不会意外地找到ObjectA行和ObjectB行,它们都指向同一行Parents;最简单的方法是使用与ParentsObjectA ObjectB相同的序列(或其他)。

您还会看到很多类似的模式:

  • Parents
    • ID
    • SubclassDiscriminator
    • ColumnFromA (nullable)
    • ColumnFromB (nullable)

Comments将保持不变。但是现在你无法强制执行所有业务约束(子类的属性都可以为空)而无需编写触发器或在不同的层执行它。

答案 2 :(得分:0)

@Hank Gay

类似于:

  1. 对象A
    • ObjectAID
    • PARENTID
  2. 对象B
    • ObjectBID
    • PARENTID
  3. 评论
    • CommentID
    • PARENTID
  4. 父母
    • PARENTID

答案 3 :(得分:0)

请注意不完全指向一个表的通用外键。如果必须在类型上拆分where条件并指向几个不同的表,则查询性能会受到严重影响。如果你只有几种类型,并且类型的数量不会增长,那么对不同的表有单独的可以为空的外键是好的,但如果你有更多的类型,最好提出一个不同的数据模型(比如@ palmsey的建议)。

答案 4 :(得分:0)

我喜欢做的事情之一就是有一个单独的表,它将通用/通用表链接到所有个性化表。

所以,对于对象Foo和Bar然后评论Foo&吧,你有这样的事情:

    • Foo ID(PK)
  • 酒吧
    • 酒吧ID(PK)
  • 注释
    • 评论ID(PK)
    • 评论文字
  • FooComment
    • Foo ID(PK FK)
    • 评论ID(PK FK)
  • BarComment
    • 酒吧ID(PK FK)
    • 评论ID(PK FK)

这个结构:

  1. 让您有一个共同的评论表
  2. 不需要具有表继承的数据库
  3. 不会使用与评论相关的信息污染Foo和Bar表
  4. 允许您将评论附加到多个对象(可能是理想的)
  5. 如果需要,可以将其他属性附加到Foo / Bar和Comment的交汇点。
  6. 仍然保留与标准(即:快速,简单,可靠)外键的关系