SQL中的参照完整性完整性检查

时间:2015-03-31 02:41:51

标签: mysql sql postgresql constraints referential-integrity

我有3个表格 - usersteamsteam_members。后者是从team(id)user(id)的多对多地图(外键分别为teamsusers)。是否有任何完整性检查我可以添加到我的数据库,可以断言虽然没有成员的团队是可能的,但没有团队的用户是不可能的?为了澄清,我想在数据库层强制执行所有用户必须属于至少1个团队(而没有要求所有团队必须拥有1个用户)。可以接受在MYSQL或Postgres中有效的答案。

1 个答案:

答案 0 :(得分:3)

(答案假定PostgreSQL;如果您使用其他RDBMS,触发器和锁定的详细信息会有所不同,但大多数RDBMS应该能够支持相同的底层操作。)

虽然可以将users中的外键添加到teams,但这样做需要重复知识 - 除了现有的m:n之外,你基本上还要创建一个额外的m:1关系。关系。这是不可取的。

如果您不需要太多并发,那么这里最好的选择可能是使用延迟约束触发器和表锁定。添加:

  • 执行ON INSERT OR UPDATE ... FOR EACH ROW的{​​{1}}上的延迟约束触发users触发器,然后检查创建的用户(如果尚未删除)至少具有一个团队通过LOCK TABLE users, team_members IN EXCLUSIVE MODE使用加入。在写入之前,您的应用程序将需要team_members以防止死锁。请注意,LOCK TABLE users IN EXCLUSIVE MODE不会阻止EXCLUSIVE MODE

  • SELECT上的延迟约束触发器ON UPDATE OR DELETE ... FOR EACH ROW反向执行相同操作,确保如果删除团队成员身份,那么作为成员的用户仍具有其他团队成员身份。它还必须锁定team_membersusers

当然,team_members还需要team_membersusers的FK约束,但这应该只适用于m:n连接表。

如果您不介意在特定订单中谨慎处理,例如在删除旧成员资格之前总是添加新成员资格,您可以使用普通触发器而不是延迟约束触发器。这会在你做错事后立即给你错误,而不是在COMMIT时间,但会做出某些在错误条件下有效的语句排序。

如果你确实需要良好的并发性,那么你可能已经填满了。