0

考虑下表:

todos:

 id | floor_start | floor_end
----+-------------+-------------
 1  | 10          | 20
 2  | 20          | 30
 3  | 30          | 40
 4  | 35          | 45

为了防止同一楼层有两部电梯,我可以选择:

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_idtodos不是一个选项,因为这只是一个最小的示例,在现实生活中的应用程序中,我有更多的 0..N 连接。

4

1 回答 1

2

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

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

于 2019-03-15T07:23:45.020 回答