【发布时间】:2010-08-09 11:28:04
【问题描述】:
Ruby on Rails ORM(对象关系映射)有一个叫做多态关联的东西,它允许使用外键来引用 2 个或更多其他表。这是通过创建一个名为“type”的附加列来实现的,该列指定与外键关联的表。
从数据库的角度来看,此实现是否有名称?这是好/坏的做法吗?
谢谢
【问题讨论】:
标签: ruby-on-rails database database-design orm
Ruby on Rails ORM(对象关系映射)有一个叫做多态关联的东西,它允许使用外键来引用 2 个或更多其他表。这是通过创建一个名为“type”的附加列来实现的,该列指定与外键关联的表。
从数据库的角度来看,此实现是否有名称?这是好/坏的做法吗?
谢谢
【问题讨论】:
标签: ruby-on-rails database database-design orm
是的,使用多个键来引用唯一记录称为复合键。它是好的还是坏的做法取决于您的数据库模式。
假设我们有 4 个表:A、B、C 和 Z。 Z 维护对 A、B 和 C 的引用。每条记录都包含对单个表的引用。下面是Z 的两个潜在架构。
我们需要一个列来存储每个表的引用。这意味着我们最终将得到未使用列的 NULL 值。将来,如果我们引入D 表,那么我们将需要向Z 添加一个新列。
id | a_id | b_id | c_id
-----------------------
1 | 1 | NULL | NULL
2 | NULL | 1 | NULL
3 | NULL | NULL | 1
我们从两列开始构建对其他表的引用。但是,当我们引入D 时,我们不需要修改架构。此外,我们永远不会有具有 NULL 值的列。
id | z_id | z_type
------------------
1 | 1 | 'A'
2 | 1 | 'B'
3 | 1 | 'C'
因此,我们可以通过使用复合外键来实现某种程度的规范化。如果两列都被索引,查询应该非常快。虽然它必须比使用单个外键慢,但差异是微不足道的。
当您拥有看似相同的数据(例如:地址)时,通常很想使用 Rails 的多态关联。将多个模型耦合在一起时应始终小心谨慎。当您注意到自己根据关联类型进行切换时,您做得太过分的一个很好的指标。一个潜在的解决方案是将通用代码重构到一个模块中,然后将其混合到您关心的模型中。
【讨论】:
并非所有数据库都允许复合外键,我个人会向任何试图对我的数据库执行此操作的人开枪。外键必须由数据库维护,而不是像 Rails 这样的东西。还有其他过程通常会触及数据库,必须检查这种关键关系,这可能不使用 ORM(我当然不会使用这样的东西来导入 10,000,000 记录文件或更新一百万条价格记录或修复数据完整性问题。
【讨论】: