mysql - 限制数据库级别的关联记录数

标签 mysql sql postgresql database-design foreign-keys

假设我有两个表parentschildren。自然地, parent 可能有许多具有一对多关系的 child 。 MySQL 或 PostgreSQL 中是否有任何结构允许限制关联对象的数量,例如:

FOREIGN KEY (parent_id) 
  REFERENCES parent(id)
  LIMIT 3

是否存在类似的东西,或者我们是否需要自定义触发器?

最佳答案

不在外键的定义中。我会通过为每个父级的每个子级添加一个序列号来解决这个问题(PostgreSQL 的代码,主要是标准 SQL):

CREATE TABLE child (
   child_id  serial PRIMARY KEY
 , parent_id int NOT NULL REFERENCES parent
 , child_nr  int NOT NULL
 , CHECK (child_nr BETWEEN 1 AND 3)
 , UNIQUE (parent_id, child_nr)
);

通过这种方式,您可以为每位 parent 拥有 1 到 3 个 child ,或者其中一些 child 或没有 child 。但没有其他人。

因为你和(parent_id, child_nr)有天生的PK现在,您可以删除代理 PK 列 child_id .但我喜欢为几乎每张表设置一个单列代理 PK ...

可以使用触发器来限制数量,它会在插入新的之前检查已经有多少 child 。但是你会遇到并发问题,而且它更昂贵、更不可靠、更容易规避并且特定于供应商。

如何管理child_nr

RDBMS 只是(可靠地)强制在表中不存在任何非法状态。你怎么算出下child_nr你决定。许多不同的方法都是可能的。

对于只有三个子项,您可以在创建父项时自动插入所有子项(使用触发器、规则或在您的应用程序中)。给定 (parent_id, child_nr)和其他列为 NULL。

那么你只允许 UPDATE而不是 INSERTDELETE对于子表( GRANT/REVOKE ),甚至确保使用另一个触发器,以便 super 用户无法绕过它。 FK 到 parentON DELETE CASCADE , 所以 child 会自动和 parent 一起死去。

备选

不太可靠,但更便宜:在 parent 中保持 child 的流动计数表并将其限制为 <= 3 .使用 child 中的每个更改更新它带触发器的表。请务必涵盖更改子表中数据的所有可能方法。

关于mysql - 限制数据库级别的关联记录数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26016545/

相关文章:

python - psycopg2.ProgrammingError : column cons. consrc 不存在

python - Django 的 NotImplementedError : aggregate() + distinct(fields) not implemented

MYSQL 集群 (NDB) 与 MongoDB

mysql - 没有数据的sql计数查询

c# - MVC 5 ASP.NET Json 结果传递参数为 null

mysql - 在表中,如何通过保留其他列的引用来选择一列的不同值?

sql - Postgresql:如何使用随机字符串高效地填充 1000 万行表

php - 如何在 mySQL 数据库中将 "int"更改为 "varchar"而 php 代码没有问题?

php - 如何在 MYSQL 中获取汇总计数

mysql 不同的选择查询合二为一