将复合主键限制为仅一条记录为“未删除”(其中多个“已删除”记录不调用约束)
Posted
技术标签:
【中文标题】将复合主键限制为仅一条记录为“未删除”(其中多个“已删除”记录不调用约束)【英文标题】:Limit composite primary key to only one record as "not deleted" (where multiple "deleted" records do not invoke constraint) 【发布时间】:2021-12-30 16:09:01 【问题描述】:想要使用复合主键以限制只有一条记录可用于生产。
表:user_id text, well_id text, deleted int, [other attributes]
建议的主键:(user_id, well_id, deleted)
这里的唯一性只与一个唯一组合的记录真正相关:user_id + well_id + deleted = 0 ...
换句话说,可能有多个记录user_id + well_id + deleted = 1
(删除的值只是一个删除的标记)?现在,我正在考虑定义 deleted
标记在大于 0 时表示“已删除”,因此我可以为所有已删除的记录递增。但我认为有人可能有更好的主意。
【问题讨论】:
为什么需要重复使用 ID? 无法完成。为历史记录创建一个单独的表并将它们存储在那里。 @stickybit - 需要重新获取其特定用户和特定井的 ID。 【参考方案1】:在您的情况下,您可以使用不可变的标准 deleted = 0
来实现唯一性。
这是示例设置;
create table table1 (
id serial primary key,
user_id text,
well_id text,
deleted int
);
-- the index is unique only for the records which have deleted = 0
create unique index on table1 (user_id, well_id) where deleted = 0;
insert into table1 (user_id, well_id, deleted) values ('user1', 'well1', 0);
insert into table1 (user_id, well_id, deleted) values ('user1', 'well1', 1);
-- this statement doesn't throws error
insert into table1 (user_id, well_id, deleted) values ('user1', 'well1', 1);
insert into table1 (user_id, well_id, deleted) values ('user2', 'well2', 0);
select * from table1;
id | user_id | well_id | deleted |
---|---|---|---|
1 | user1 | well1 | 0 |
2 | user1 | well1 | 1 |
3 | user1 | well1 | 1 |
4 | user2 | well2 | 0 |
-- Finally, this statement throws an error
insert into table1 (user_id, well_id, deleted) values ('user1', 'well1', 0);
ERROR: duplicate key value violates unique constraint "table1_user_id_well_id_idx"
DETAIL: Key (user_id, well_id)=(user1, well1) already exists.
db 小提琴here
【讨论】:
最好让deleted
成为boolean
。但这是正确的解决方案!
谢谢@Sahap Asci!这非常有帮助!
@LaurenzAlbe - 同意布尔值...但会损害开发团队偏好的 b/c。
“开发者团队偏好”,hmpf。因此,如果他们不知道或不喜欢一种数据类型,即使它是正确的,也不会被使用?以上是关于将复合主键限制为仅一条记录为“未删除”(其中多个“已删除”记录不调用约束)的主要内容,如果未能解决你的问题,请参考以下文章