在多个表中排除约束?

时间:2019-03-15 07:12:53

标签: postgresql exclusion-constraint

请考虑下表:

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个加入。

1 个答案:

答案 0 :(得分:2)

您可以编写一个AFTER INSERT OR UPDATE触发器来检查条件,如果不满足则抛出错误。

但是请注意,此类触发器具有争用条件-两次并发数据修改不能看到彼此的影响。因此,您要么必须使用SERIALIZABLE隔离级别,要么使用SELECT ... FOR UPDATE锁定触发器中受影响的行。