[英]Limit number of associated records on DB level
我们假设我有两个parents
和children
桌子。 父母自然会有很多孩子与一对多的关联。 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)
);
通过这种方式,您可以为每个父母提供1到3个孩子,或者为这些孩子设置一些或不提供任 但没有其他人。
由于你现在有一个带有(parent_id, child_nr)
的自然PK,你可以删除代理PK列child_id
。 但我喜欢几乎每张桌子都有一个单列代理PK ...
您可以使用触发器来限制数量,该数字会在插入新子节点之前检查已有多少子节点。 但是你会遇到并发问题,而且它更昂贵,更不可靠,更容易规避和特定于供应商。
child_nr
? RDBMS只强制(可靠地)表中不存在非法状态。 你如何找出下一个child_nr
取决于你。 许多不同的方法是可能的。
对于三个孩子,您可以在创建父项时自动插入所有子项(使用触发器,规则或在应用程序中)。 给定(parent_id, child_nr)
和其他列NULL。
那么你只允许UPDATE
而不是INSERT
或DELETE
用于子表( GRANT
/ REVOKE
),甚至可以确保使用另一个触发器,这样超级用户就无法绕过它。 使用ON DELETE CASCADE
使FK成为parent
,因此子级会自动与父级一起死亡。
可靠性稍差但更便宜:在parent
表中保留一个子运行计数并将其限制为<= 3
。 使用触发器更新child
表中的每个更改。 请务必涵盖更改子表中数据的所有可能方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.