我们假设我有两个父母和孩子的桌子.父母自然会有很多孩子与一对多的关联. 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成为父级,因此子级会自动与父级一起死亡.
替代
可靠性稍差但更便宜:在父表中保留子进程的运行计数并将其限制为< = 3.使用触发器对子表中的每次更改进行更新.请务必涵盖更改子表中数据的所有可能方法.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。