请考虑下表:
todos:
id | floor_start | floor_end
----+-------------+-------------
1 | 10 | 20
2 | 20 | 30
3 | 30 | 40
4 | 35 | 45
为了防止我在同一楼层使用2部电梯,
EXCLUDE USING gist(int4range(start,end) with &&)
在这种情况下,3将与4冲突。
但是我确实有一个联接表:
occupations:
todo_id | room_id
---------+----------
3 | 1
4 | 2
因此(3)在room_id = 1
中完成,而(4)在room_id = 2
中完成,它们不会冲突。
1&2在联接表中没有条目,因此所有房间都被占用。
我知道exclude
仅在当前表的范围内有效-我该如何处理?我应该制作多余的列吗?
不能将room_id
添加到todos
,因为这只是一个最小的示例,在现实应用中,我有0..N个加入。
答案 0 :(得分:2)
您可以编写一个AFTER INSERT OR UPDATE
触发器来检查条件,如果不满足则抛出错误。
但是请注意,此类触发器具有争用条件-两次并发数据修改不能看到彼此的影响。因此,您要么必须使用SERIALIZABLE
隔离级别,要么使用SELECT ... FOR UPDATE
锁定触发器中受影响的行。