【问题标题】:How to remove duplicate rows in CockroachDB如何删除 CockroachDB 中的重复行
【发布时间】:2018-01-22 16:49:22
【问题描述】:

我在 CockroachDB 中有一个表,在应用约束设置主键之前,我已将数据填充到表中,并且由于某些 INSERT 语句在数据加载阶段失败,一些行被加载到错误的表不止一次。

我要应用的约束是:

CREATE UNIQUE INDEX ON "MyDB"."MyTable" ("Row_ID");

但由于重复数据已经加载到表中,我收到以下错误:

pq: multiple primary keys for table "MyTable" are not allowed

我检查了以下查询是否确实有一些重复的行:

SELECT  
    Row_ID,
    COUNT(Row_ID) as id
FROM    
    MyTable
GROUP BY 
    Row_ID
HAVING  
    COUNT(Row_ID) > 1;

查询显示有一些重复的行。

在 CockroachDB 中删除重复行的最佳方法是什么?

【问题讨论】:

    标签: duplicates sql-delete cockroachdb


    【解决方案1】:

    如果您不关心您保留的哪个重复行,请运行:

    DELETE FROM MyTable WHERE rowid IN (
        SELECT MIN(rowid) FROM MyTable GROUP BY Row_ID HAVING COUNT(*) > 1
    );
    

    对于任何重复,该查询将删除除首先粗略创建的行之外的所有行。†

    请注意,rowid 与您的Row_ID相同。 rowid 是一个内部 CockroachDB 列,它是为没有主键的表神奇地创建的,并且保证对于表中的每一行都是唯一的。

    rowid 存储 <timestamp><node-id>,因此它大致根据插入时间进行排序,但由具有倾斜时钟的节点几乎同时插入的行可能不会按插入顺序排序。

    【讨论】:

    • 所以我相信一般建议是在需要与 cockroachdb v1 连接的地方使用子查询?
    【解决方案2】:

    如果它们完全匹配,您可以使用不同的记录创建一个新表。

    然后删除所有旧表并从上一步创建的表中重新填充。

    创建表:

    create table MyWorkData as select distinct * from MyTable;
    

    删除 MyTable

    delete from MyTable;
    

    重新填充 MyTable。 (感谢@benesch 更正声明)

    INSERT INTO MyTable SELECT * FROM MyWorkData
    

    最后删除工作表。

    【讨论】:

    • 谢谢,我试过了,每次运行查询:create table MyWorkData as select distinct * from MyTable;,进程就会被杀死。不知道为什么,服务器没有给出任何其他原因,使用命令“free -m”,我认为不是因为内存。
    • 您还可以分两步创建表格并使用“选择进入”来填充它。
    • @Cyrus,您可以在日志文件中获得更详细的故障报告。请提交问题或在 Gitter 上与我们聊天! gitter.im/cockroachdb/cockroach
    • @Juan,CockroachDB 不支持SELECT... INTO。您需要改为运行 INSERT INTO MyTable SELECT * FROM MyWorkData
    • @benesch 感谢您的更正。我已经更新了答案。
    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 2018-05-26
    • 2019-05-27
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多