【问题标题】:Doctrine ORM linking foreign key to multiple tablesDoctrine ORM 将外键链接到多个表
【发布时间】:2014-12-05 17:34:32
【问题描述】:

我想实现一个通用表,例如 info,其中包含 type 列和 foreign_id 列。 foreign_id 是不同表的外键,具体取决于 type

使用Doctrine ORM,我的理解是需要提前指定映射关系。但是,由于 foreign_id 可以根据 type 链接到不同的表。你如何使用 ORM 实现这种关系?

目前,我通过创建多个表来解决这个问题,比如 info_ainfo_ba_idb_id时间>。如果类型的数量增加,它将导致许多表具有基本相似的结构。

您如何使用 ORM 解决此问题?提前致谢。

【问题讨论】:

  • 将外键映射到多个表是数据库设计中的反模式。见here

标签: database-design orm doctrine-orm


【解决方案1】:

您通过接受拥有多个“具有相似结构”的表这一事实来“解决”这个问题。

您拥有表格的原因不是它们的结构,您拥有表格的原因是因为它们(及其内容)对最终用户意味着什么 .

因此,决定拥有多少个表格,首先应该由它们对用户代表的含义来决定,不同类型的含义会导致不同的表格。观察到两个表“具有相同结构”因此应该合并为一个的习惯很普遍,但这仍然是一个严重的错误。

帮自己一个忙,学习/接受“通用表”不好的反应。

【讨论】:

  • 感谢您的回复。我认为保持代码干燥是件好事。这不应该也适用于数据库结构吗?
  • 没有。数据库结构不是代码。见quora.com/How-would-you-explain-the-relational-database-model/…。表格的“结构”是其中提到的“一组孔”。但是你可以有多个不同的谓词(= 多个不同的外部含义),它们具有完全相同的“孔集”。
【解决方案2】:

您没有多个外键。你有一些让人想起 FK 的东西。 FK 是一个列集,其子类型值始终也在另一个表中,其中列形成候选键。正如所评论的那样,您的设计是一种反模式,因为它不必要地复杂。而且 SQL 不容易支持其完整性或优化。

在 table info 中没有列 type 和 foreign_id [sic],其中 type 值指示它必须作为 id 值出现在哪个其他表中,而是为每个允许在类型中使用 FK foreign_id 的值创建一个表 VALUE_info到相应的 VALUE_other 表 ID。

但是,您真正需要的可能是每个 VALUE_other 表都将其 foreign_id 列作为 FK 引用信息。即,您可能希望 FK 走另一条路。当 info(id,type,...) 表示“事物 [id] 是子类型 [type] 并且 ...) 并且 VALUE_other(foreign_id,...) 表示“事物 [foreign_id] 是子类型 VALUE 并且...”。请注意,正确的名称是 thing_info(id,type,...) 和 VALUE_thing_info(id,...)。您可能不再需要 type。类似的事情可能都会自动设置通过明确支持“子类型化”或“多态性”的 ORM。

如果这符合您的需求,那么在这种子类型化的特殊情况下,因为您能够让每一行信息都有一个指向一个 VALUE_other 表的 foreign_id FK,这意味着每件事都属于一个子类型。对于最多一个子类型,您可以为每个 VALUE_thing_info 表编写一个 SQL 约束,只要 thing_info 中的 id 匹配行的类型值为 VALUE。 (从技术上讲,类型在数据库中仍然是多余的,但它有助于提高清晰度和效率。)您可以编写 SQL 约束,使 thing_info id 值位于 VALUE_thing_info id 值的联合中。 (一些这样的约束可以是声明性的。在 thing_info 中输入类型有助于实现这一点。将类型也放在 VALUE_thing_info 表中是另一个更多余的习惯用法,但也有助于更具声明性。尽管更新的约束可以更快。)

【讨论】:

    猜你喜欢
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 2016-10-15
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多