加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 多字段UNIQUE约束可以包含多个表中的字段吗?

发布时间:2020-12-13 16:03:20 所属栏目:百科 来源:网络整理
导读:我有以下2个表格: Bookings - User IDShifts - Booking ID - Date 我想确保用户在同一天没有预订多个班次.换句话说,字段的UNIQUE约束[Bookings.UserID,Shifts.date] 我可以在PostgreSQL中执行此操作吗? 解决方法 PostgreSQL中的索引位于一个表中,不能跨越
我有以下2个表格:

Bookings
  - User ID

Shifts
  - Booking ID
  - Date

我想确保用户在同一天没有预订多个班次.换句话说,字段的UNIQUE约束[Bookings.UserID,Shifts.date]

我可以在PostgreSQL中执行此操作吗?

解决方法

PostgreSQL中的索引位于一个表中,不能跨越多个表.

但您可以使用正确的表格布局解决您的问题.您可能需要的是一个n:m关系,用3个表实现.然后有各种方法来强制你的病情.

>您可以在冗余预订中存储日期,在(usr_id,shift_date)上创建主键而不是(usr_id,shift_id),并使用(shift_id,shift_date)上的多列外键保证参照完整性:

CREATE TABLE usr(
  usr_id serial PRIMARY KEY
 --,more?
);

CREATE TABLE shift(
  shift_id serial PRIMARY KEY,shift_date date
 --,more?
);

这也需要先换班的独特指数:

CREATE UNIQUE INDEX shift_date_idx ON shift (shift_id,shift_date);

CREATE TABLE booking(
  usr_id int REFERENCES usr(usr_id),shift_id int,more?,CONSTRAINT booking_pkey PRIMARY KEY (usr_id,shift_date),CONSTRAINT booking_fkey FOREIGN KEY (shift_id,shift_date)
 REFERENCES shift(shift_id,shift_date)
);

>另一种限制较少但也不太可靠的方法是在表预订上触发ON INSERT或UPDATE,检查用户是否已经转换了新日期.没有冗余日期列可以工作.

我会选择第一个解决方案.

PostgreSQL中的视图也没有索引(据我所知,从v9.1开始).

您可以创建一个函数,为给定的shift_id返回shift_date并将其声明为IMMUTABLE(实际上,它不是).有了它,您可以在表达式上创建一个多列索引:

CREATE function f_shift_date (shift_id int)
 RETURNS date LANGUAGE SQL IMMUTABLE AS
$BODY$
   SELECT shift_date FROM shift WHERE shift_id = $1;
$BODY$;

CREATE UNIQUE INDEX shift_date_idx ON booking (shift_id,f_shift_date(shift_id));

这会强制你的条件.但说实话,这是非常自杀的.索引依赖于无限期获得shift_id相同日期的条件.如果shift_date相对于其shift_id发生了变化,则必须重新创建索引,否则将产生不正确的结果.所以,不要这样做.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读