如何在连接表上的两个外键之间强制实施数据库约束?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在连接表上的两个外键之间强制实施数据库约束?相关的知识,希望对你有一定的参考价值。

我试图在连接表上强制执行两个外键之间的约束,我不知道我是否可以使用数据库来执行此操作,或者我是否应该通过我的应用程序或我的ORM来执行此操作。

这是我的表格:

Dataset

Tag
 - Dataset: FK
 - name: string (eg: "park", "church", etc)

Place
 - Dataset: FK
 - latitude
 - longitude

PlaceTag (my join table)
 - Tag: FK
 - Place: FK
 - note: string (eg: "this place is my favorite park")

我想强制执行约束,即每个PlaceTag都有一个Tag和一个属于同一个数据集的Place。我应该使用数据库还是我的应用程序执行此操作?或者我应该重新构建我的模型以更容易地强制执行此约束?

FWIW,这是一个开源项目,我创建这些表的PR在这里:https://github.com/mapseed/api/pull/161/files该项目正在使用Django,如果这有帮助的话。

答案

在Django中“强制执行”(注意引号)的一种方法是覆盖PlaceTagsave()方法。在那里你可以在self.place.dataset != self.tag.dataset时提出异常。但是你应该注意到有些情况下Django不会调用模型的自定义save()方法:

  1. 在查询集上调用update()方法时。此方法适用于批量更新,因此,出于性能原因,直接在数据库级别(reference)进行更新。
  2. 内部(数据)迁移自定义save()方法不可用。

在这两种情况下,我提出的方法对强制执行约束(因此在开头的引号)没有用。这当然不一样,也不像在数据库级别强制执行那样强大。无论如何,我不认为有一种可移植的方式(即在任何或大多数SQL数据库引擎中可用)执行这样的条件,因为检查它将需要在其他表上加入,但我可能在这个上错了。

以上是关于如何在连接表上的两个外键之间强制实施数据库约束?的主要内容,如果未能解决你的问题,请参考以下文章

使用复合主键在联结表上设置外键约束

如何通过 Java 在 SQLite 中强制执行外键约束?

不在数据库中的表上的外键,使用 ORM

SQL中如何为表添加外键约束

表连接

oracle怎么查看外键在哪个表