模拟可空列的主键

Simulate a primary key for a nullable column

我在 table 中使用这种结构处理成员的角色:

添加角色时,date_start设置为current_timestampdate_end为空。 当我删除角色时,date_end 设置为 current_timestamp

不希望一个用户同时拥有多个角色,所以一开始我想设置一个三重主键:id_memberid_roledate_end,但我似乎无法将可为空的列作为主键。

如何更改 table 的结构以防止用户拥有 2 个活动角色?我考虑过添加一个 active 列,但它不仅会使结构过度收费,而且我将无法保存 2 个历史角色(例如,如果用户在 4 个不同时期是 ROLE3)。

提前致谢。

I don't want a user to have several roles at the same time

部分UNIQUE索引

因此,每个成员只能有一个活动角色 (date_end IS NULL)。
部分 UNIQUE 索引将强制执行:

CREATE UNIQUE INDEX tbl_member_active_role_uni ON tbl (id_member)
WHERE date_end IS NULL;  -- active role

参见:

EXCLUDE

以上仍然允许添加重叠的历史条目。同样,要禁止这样做,请对整数列使用 exclusion constraint. You'll need the additional module btree_gist。参见:

然后:

ALTER TABLE tbl ADD CONSTRAINT tbl_member_no_overlapping_role
EXCLUDE USING gist (id_member with =, tsrange(date_start, date_end) WITH &&);

NULL date_end 的值恰好完美地工作。在范围类型中,NULL 作为上限表示“无界”。 参见: