Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 添加唯一约束,但忽略现有表数据_Sql_Postgresql_Unique Constraint - Fatal编程技术网

Sql 添加唯一约束,但忽略现有表数据

Sql 添加唯一约束,但忽略现有表数据,sql,postgresql,unique-constraint,Sql,Postgresql,Unique Constraint,我希望使用以下查询向表添加唯一约束- ALTER TABLE events ADD CONSTRAINT events_timestamp_request_session_key UNIQUE (event_timestamp, request_id, session_id); 查询是有效的,但是在一个数据库上,现有数据不满足约束,因此查询失败- 错误:无法创建唯一索引“事件\时间戳\请求\会话\密钥” 详细信息:密钥(事件时间戳、请求id、会话id)=(2017-07-05 14:53:25

我希望使用以下查询向表添加唯一约束-

ALTER TABLE events ADD CONSTRAINT events_timestamp_request_session_key UNIQUE (event_timestamp, request_id, session_id);
查询是有效的,但是在一个数据库上,现有数据不满足约束,因此查询失败-

错误:无法创建唯一索引“事件\时间戳\请求\会话\密钥”
详细信息:密钥(事件时间戳、请求id、会话id)=(2017-07-05 14:53:25.475246+00,a55df6-8533e322cd-aa9d57-87e2,132443)重复

预计会有一些副本,但不幸的是,我不能简单地删除或更改它们


是否有任何方法可以根据需要添加约束,同时忽略表中的现有数据?

我认为没有内置的方法可以做到这一点。但是,可以使用表达式创建唯一索引。假设每个表中都有一个序列唯一id:

create unique index unq_events_timestamp_request_session_key 
    on (event_timestamp, request_id, session_id,
        (case when event_id < 99999 then event_id else -1 end)
       ); 
这将需要对当前的副本进行研究。实际上,您也可以使用筛选子句:

create unique index unq_events_timestamp_request_session_key 
    on (event_timestamp, request_id, session_id)
    where event_id > 999999 ;

create unique index unq_events_timestamp_request_session_key 
    on (event_timestamp, request_id, session_id)
    where event_id not in (1, 2, 3, 5, 8) ;

您可以为此使用部分索引,这不是一个特别好的解决方案,但在您能够更正旧数据之前,它将一直有效

比如:

CREATE UNIQUE INDEX events_timestamp_request_session_key
ON events (event_timestamp, request_id, session_id)
WHERE event_timestamp >= '2017-07-01'::timestamp;
其中时间是清理数据的开始

where子句将索引限制为仅查看具有较新事件时间戳的记录。旧记录完全从索引中排除,因此不考虑进行唯一性检查


Doc:

它起作用,并强制这些列的组合是唯一的,因此感谢您。但是,展望未来,您知道对查询的影响是什么吗?也就是说,每周添加大约300万行,查询速度会比使用唯一约束时慢吗?“谢谢,”大卫·加德说。插入速度会变慢,因为它们必须维护一个额外的索引。您需要进行基准测试,以确定这是否会导致问题。有一点需要考虑的是,因为这是一个部分索引,它不会帮助您运行的任何查询,这些查询可能会查看旧数据,因此您可能发现自己需要2个索引,对于部分表来说,需要一个唯一的索引,而对于整个表则需要一个非唯一索引。
CREATE UNIQUE INDEX events_timestamp_request_session_key
ON events (event_timestamp, request_id, session_id)
WHERE event_timestamp >= '2017-07-01'::timestamp;