【问题标题】:Duplicating columns in an inheritance model在继承模型中复制列
【发布时间】:2012-02-17 06:34:04
【问题描述】:

我有两个模拟继承关系的表。这通过引用Base.IdDerived.Id 上的外键约束来表示。 Base 中的某些列在Derived 中基本上是重复的,因此可以在唯一约束和复合外键中引用它们。我想确保这两个表中这些列的值相同。理想情况下,这将通过Id + 列上的复合外键来完成。但这会阻止值被更改——这是一个 catch-22 场景。

我如何确保这些列在两个表中具有相同的值并且允许它们被更新?我有完全的灵活性,所以我可以更改表的架构或做任何其他必要的事情来实现这一点。

【问题讨论】:

    标签: sql-server sql-server-2005 database-design


    【解决方案1】:

    如果它适用于所有对象,我只会将列保留在其中一个表中,base。 你能举个例子说明复制列的必要性吗?比如 base = car, has VIN, derived = myCar, has VIN.

    另外,如果重复的列是键的一部分,请使用级联更新。

    【讨论】:

    • 例如,所有Base 都有一个Category。但是Category 必须在Derived 中才能对Category + Name 施加唯一约束(仅在Derived 中)。关于级联更新,不幸的是,由于我需要使用 ORM,这是不受限制的。
    • 当我过去做过那种事情时,我只是在基表中有类别并且对名称字段有唯一约束,因为派生表只包含一个类别每个类别都有不同的列。
    • 实际上,如果每个派生类别都有名称(或其他名称),您可以将其保存在基表中。
    • cdeszaq 也推荐了一张桌子,但由于我在他的回答中提到的原因,它不起作用。
    • 在我的情况下最好的答案(也是最简单的)是使用级联更新。
    【解决方案2】:

    而不是第二个表,我只需要在 Base 表中包含所有列 Derived 并将这些列设置为可为空。如果您还添加一个鉴别器列来确定特定记录是代表Base 对象还是Derived 对象,则一切就绪。

    您可以设置所需的任何约束,而不必处理不同步的重复数据,这就是 Hibernate(和 NHibernate)用于映射继承的默认方法的原因.

    【讨论】:

    • 如果您希望表在外键约束中引用Derived 怎么办?您不能使用单个表 + 鉴别器列来做到这一点。
    • 如果您的意思是您需要另一个对象来引用Derived 而不仅仅是Base,您可以通过多种不同的方式来实现。一种方法是让Derived 列之一成为ID 列,与Base ID 列分开,并对其进行唯一性约束,并使FK 脱离它。另一种选择是使 FK 脱离 Base PK 和一个额外的 Derived-only 字段。
    • 在我看来,您的后一个建议是“弱保证”,因为如果“Derived-only 字段”为空,则不会强制执行约束。
    • 是的,这并不理想,因为数据库无法强制数据完全正确(至少不容易......),但数据库保持绝对控制的能力(在 ORM 中)特别是环境)总是在某个时候崩溃。我提出的第一个解决方案是我认为更好的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多