多态关联外键约束。这是一个好的解决方案吗?
多态关联外键约束。这是一个好的解决方案吗?
我们在我们的应用程序中使用多态关联。我们遇到了经典问题:我们遇到了一个无效的外键引用,并且我们无法创建外键约束,因为它是一个多态关联。
话虽如此,我已经对此进行了大量的研究。我知道使用多态关联的弊端和优势。但是我找到了一个看起来不错的解决方案:
这很好,因为你可以兼顾两者。我担心的是数据重复。我对PostgreSQL的知识不够深入,无法完全理解这种解决方案的成本。
你有什么想法?这个解决方案应该完全避免吗?还是它是一个好的解决方案?
在我看来,唯一的选择是为每种关联类型创建一个外键。但是然后你会遇到只允许存在一个关联的验证问题。这是一个“选择你的毒药”的情况。多态关联清晰地描述了意图,并且使这种情况成为不可能。在我看来,这是最重要的。数据库外键约束是一个幕后功能,为了使“意图”与数据库的限制配合工作而改变感觉不对。这就是为什么我想使用上述解决方案的原因,假设它没有明显的“避免”的问题。
多态关联外键约束。这是一个好的解决方案吗?
在数据库中,你无法以一种简单的方式强制实施多态关联的外键约束 - 所以这是一个非常糟糕的想法。通常最好的解决方案是简单的解决方案 - 忘记多态关联吧 - 这是一种反模式的味道。
实际上,作为我的应用程序迁移的一部分,我可以非常轻松地实现这个解决方案:只需一个方法调用即可。我关心的不是如何实现这个解决方案,而是一旦实施后它对我的应用程序产生的影响。
这是一个关于这种反模式的好的帖子:stackoverflow.com/questions/922184/…
多态关联外键约束。这是一个好的解决方案吗?
PostgreSQL的INHERITS
实现的最大问题是无法将外键引用设置为父表。有很多情况下需要这样做。请参见我答案末尾的示例。
决定在Rails之外创建表、视图或触发器是至关重要的。一旦决定这样做,我认为你最好使用最好的结构。
我长期以来一直使用基本的父表,使用外键来强制实施不相交的子类型。这种结构保证只能存在一个关联,并且关联将解析为父表中的正确子类型。该方法在Bill Karwin的SQL反模式幻灯片中从46页开始。在简单的情况下,这不需要触发器,但我通常为每个子类型提供一个可更新的视图,并要求客户端代码使用这些视图。在PostgreSQL中,可更新的视图需要编写触发器或规则。 (9.1版本之前需要规则。)
在最一般的情况下,不相交的子类型没有相同数量或种类的属性。这就是为什么我喜欢可更新的视图。
表继承不是可移植的,但这种结构是可移植的。你甚至可以在MySQL中实现它。在MySQL中,你必须用对一行表的外键引用来替换CHECK约束。(MySQL解析和忽略CHECK约束。)
我认为你不必担心数据重复。首先,我非常确定数据在父表和继承表之间不会重复。它只是看起来是这样。其次,重复的数据或其完全由数据库管理系统控制完整性的派生数据并不是一个特别难以接受的问题。(但是,未受控制的重复数据是。)
考虑一下是否应该级联删除。
- 一个具有SQL代码的出版物示例。
- 一个具有SQL代码的“参与者”示例。
谢谢你。听起来这个解决方案并不差。显然,我希望尽量避免在Rails之外进行操作,但我发现随着应用程序的增长,这是不可避免的。尽管我希望依赖于validates_uniqueness_of和:dependent => :destroy,但毫无疑问,我最终会发现数据完整性问题。你对数据重复的评论很有帮助,我不知道PG实际上没有复制数据。这是我最关注的问题。