SQL 中的引用完整性完整性检查
Referential completeness integrity check in SQL
我有 3 个表 - users
、teams
和 team_members
。后者是从 team(id)
到 user(id)
的多对多映射(分别是 teams
和 users
的外键)。是否有任何完整性检查可以添加到我的数据库中,可以断言虽然没有成员的团队是可能的,但没有团队的用户是不可能的?澄清一下,我想在数据库层强制所有用户必须属于至少 1 个团队(但没有要求所有团队必须有 1 个用户)。在 MYSQL 或 Postgres 中有效的答案是可以接受的。
(答案假定使用 PostgreSQL;如果您使用其他 RDBMS,有关触发器和锁定的详细信息会有所不同,但大多数 RDBMS 应该能够支持相同的底层操作。)
虽然可以将外键从 users
添加到 teams
,但这样做需要复制知识 - 除了存在 m:n 关系。这是不可取的。
如果您不需要太多并发,这里最好的选择可能是使用延迟约束触发器和 table 锁定。添加:
延迟约束触发器 ON INSERT OR UPDATE ... FOR EACH ROW
在 users
上触发执行 LOCK TABLE users, team_members IN EXCLUSIVE MODE
然后检查创建的用户,如果它没有被删除,至少有一个团队通过 team_members
使用加入。您的应用程序在写入之前也需要 LOCK TABLE users IN EXCLUSIVE MODE
以防止死锁。请注意 EXCLUSIVE MODE
不会阻止 SELECT
.
team_members
上的延迟约束触发器 ON UPDATE OR DELETE ... FOR EACH ROW
以相反的方式执行相同的操作,确保如果您删除团队成员资格,那么曾经是成员的用户仍然有其他团队成员。它还必须同时锁定 users
和 team_members
.
当然,team_members
也需要对 users
和 teams
的 FK 约束,但对于 m:n 加入 table 来说应该只是假设。
如果您不介意必须按照特定顺序小心地做事,例如始终在删除旧成员之前添加新成员,您可以使用普通触发器而不是延迟约束触发器。这会在你做错事后立即给你错误,而不是在 COMMIT 时间,但会做出某些语句的顺序,否则这些语句在错误条件下是有效的。
如果您确实需要良好的并发性,那么您可能已经吃饱了。
我有 3 个表 - users
、teams
和 team_members
。后者是从 team(id)
到 user(id)
的多对多映射(分别是 teams
和 users
的外键)。是否有任何完整性检查可以添加到我的数据库中,可以断言虽然没有成员的团队是可能的,但没有团队的用户是不可能的?澄清一下,我想在数据库层强制所有用户必须属于至少 1 个团队(但没有要求所有团队必须有 1 个用户)。在 MYSQL 或 Postgres 中有效的答案是可以接受的。
(答案假定使用 PostgreSQL;如果您使用其他 RDBMS,有关触发器和锁定的详细信息会有所不同,但大多数 RDBMS 应该能够支持相同的底层操作。)
虽然可以将外键从 users
添加到 teams
,但这样做需要复制知识 - 除了存在 m:n 关系。这是不可取的。
如果您不需要太多并发,这里最好的选择可能是使用延迟约束触发器和 table 锁定。添加:
延迟约束触发器
ON INSERT OR UPDATE ... FOR EACH ROW
在users
上触发执行LOCK TABLE users, team_members IN EXCLUSIVE MODE
然后检查创建的用户,如果它没有被删除,至少有一个团队通过team_members
使用加入。您的应用程序在写入之前也需要LOCK TABLE users IN EXCLUSIVE MODE
以防止死锁。请注意EXCLUSIVE MODE
不会阻止SELECT
.team_members
上的延迟约束触发器ON UPDATE OR DELETE ... FOR EACH ROW
以相反的方式执行相同的操作,确保如果您删除团队成员资格,那么曾经是成员的用户仍然有其他团队成员。它还必须同时锁定users
和team_members
.
当然,team_members
也需要对 users
和 teams
的 FK 约束,但对于 m:n 加入 table 来说应该只是假设。
如果您不介意必须按照特定顺序小心地做事,例如始终在删除旧成员之前添加新成员,您可以使用普通触发器而不是延迟约束触发器。这会在你做错事后立即给你错误,而不是在 COMMIT 时间,但会做出某些语句的顺序,否则这些语句在错误条件下是有效的。
如果您确实需要良好的并发性,那么您可能已经吃饱了。