Postgresql 如何对具有联接表的范围使用约束?

Postgresql 如何对具有联接表的范围使用约束?,postgresql,Postgresql,基于此,如何同时防止表中的任何重叠保留非常简单 创建扩展树; 创建桌子房间\u预订( 会议室文本, 在这个范围内,, 使用GIST排除(房间为=,期间为&&) ); 但是,当用户可以保留多个资源时,检查重叠的最佳方法是什么?您可以在下面看到,我想让用户保留多个资源。这就是为什么我要使用连接表资源。是否有任何方法可以使用EXCLUDE来检查是否同时没有保留任何资源 创建表用户( id串行主键, 名称文本 ); 创建表资源( id串行主键, 名称文本 ); 创建表格预订( id串行主键, 持续时间

基于此,如何同时防止表中的任何重叠保留非常简单

创建扩展树;
创建桌子房间\u预订(
会议室文本,
在这个范围内,,
使用GIST排除(房间为=,期间为&&)
);
但是,当用户可以保留多个资源时,检查重叠的最佳方法是什么?您可以在下面看到,我想让用户保留多个资源。这就是为什么我要使用连接表资源。是否有任何方法可以使用EXCLUDE来检查是否同时没有保留任何资源

创建表用户(
id串行主键,
名称文本
);
创建表资源(
id串行主键,
名称文本
);
创建表格预订(
id串行主键,
持续时间tstzrange,
用户id序列号,
外键(用户id)引用用户(id)
);
创建表资源\u预订(
资源id序列号,
预定号序列号,
外键(资源id)引用资源(id),
外键(保留_id)引用保留(id),
主键(资源id、保留id)
);

我认为只要稍微改变一下型号,你想要的是可行的
但首先让我们纠正一个误解。您将外键列(用户id、资源id等)定义为串行。这是不正确的,它们应该是整数。这是因为SERIAL实际上不是一种数据类型。它是一种psuedo数据类型,实际上是:创建一个序列,创建一个整型列,并将创建的序列定义为默认值。别挡道了
我认为你的资源是多余的。保留是由用户进行的,但是没有保留内容的保留只是用户信息。将资源\u id带到保留中。现在,用户可以对具有持续时间的资源进行预订。当前模型包含的所有内容,但复杂性较低。
假设您没有需要保存的数据,则:

create table users(
    id serial primary key,
    name text
);
     
create table resources(
    id serial primary key,
    name text
);
 
create table reservations(
    user_id     integer
    resource_id integer
    duration    tstzrange,
    foreign key (user_id) references users(id)
    foreign key (resource_id) references resources(id), 
    primary key (resource_id, user_id)    
);

您现在应该可以创建GIST排除功能了。

如果不将
持续时间
复制到Resources\u Reservation中,我想不出任何方法来实现这一点,因为GIST排除功能需要访问该列以检查
(resource\u id=,duration WITH&&)
。谢谢您的回答。这是我自己想的,但我没有去做,因为我失去了多对多的关系,也就是说,一个用户可以用许多资源进行单一预订。使用更新后的模型,用户必须创建与其想要保留的资源数量相同的保留。要么我使用它并确保我的应用程序从一个预订请求中进行多个预订,要么我编写一些函数/触发器来处理连接表(复制其中的duration列),要么我在应用程序中实现逻辑。我不确定我会走哪条路。