排除多个表的约束?

Exclude constraint across many tables?

考虑以下 table:

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 冲突。

不过我确实有加入 table:

occupations:

 todo_id | room_id
---------+----------
 3       | 1
 4       | 2

所以 (3) 在 room_id = 1 中完成,(4) 在 room_id = 2 中完成,它们不会冲突。

1 & 2 没有加入的条目 table,所以所有房间都被占用了。

我知道 exclude 只会在当前 table 的范围内工作 - 我该如何处理它?我应该制作多余的列吗?

room_id 添加到 todos 不是一个选项,因为这只是一个最小的例子,在现实生活中我有更多的 0..N 连接。

您可以编写一个 AFTER INSERT OR UPDATE 触发器来检查条件并在不满足条件时抛出错误。

但请注意,此类触发器存在竞争条件——两个并发数据修改无法看到彼此的效果。因此,您要么必须使用 SERIALIZABLE 隔离级别,要么使用 SELECT ... FOR UPDATE.

锁定触发器中受影响的行