Postgresql 是否跨多个表排除约束?
考虑下表:Postgresql 是否跨多个表排除约束?,postgresql,exclusion-constraint,Postgresql,Exclusion Constraint,考虑下表: todos: id | floor_start | floor_end ----+-------------+------------- 1 | 10 | 20 2 | 20 | 30 3 | 30 | 40 4 | 35 | 45 occupations: todo_id | room_id ---------+---------- 3 | 1 4 | 2
todos:
id | floor_start | floor_end
----+-------------+-------------
1 | 10 | 20
2 | 20 | 30
3 | 30 | 40
4 | 35 | 45
occupations:
todo_id | room_id
---------+----------
3 | 1
4 | 2
为了防止同一楼层有两部电梯,我可以选择:
EXCLUDE USING gist(int4range(start,end) with &&)
在这种情况下,3将与4冲突
但是,我有一个连接表:
todos:
id | floor_start | floor_end
----+-------------+-------------
1 | 10 | 20
2 | 20 | 30
3 | 30 | 40
4 | 35 | 45
occupations:
todo_id | room_id
---------+----------
3 | 1
4 | 2
因此,(3)在房间id=1
中完成,(4)在房间id=2
中完成,它们不会冲突
1和2在联接表中没有条目,因此所有房间都已占用
我知道exclude
仅在当前表的范围内有效-我如何处理它?我应该做多余的列吗
将
room\u id
添加到todos
不是一个选项,因为这只是一个最小的示例,在现实生活中,我有更多的0..N连接。您可以在插入或更新后编写触发器,检查条件,如果不满足,则抛出错误
但是要注意,这样的触发器有一个竞争条件——两个并发的数据修改不能看到彼此的效果。因此,您要么使用SERIALIZABLE
隔离级别,要么使用SELECT锁定触发器中受影响的行。。。对于更新
,您可以在插入或更新后编写一个触发器,检查条件,如果不满足,则抛出一个错误
但是要注意,这样的触发器有一个竞争条件——两个并发的数据修改不能看到彼此的效果。因此,您要么使用SERIALIZABLE
隔离级别,要么使用SELECT锁定触发器中受影响的行。。。用于更新