【问题标题】:Best way to prevent duplicate data on copy csv postgresql防止复制 csv postgresql 上重复数据的最佳方法
【发布时间】:2015-10-16 19:30:59
【问题描述】:

这更像是一个概念性问题,因为我正在计划如何最好地实现我们的目标。

我有一个包含 5 列的 postgresql/postgis 表。我将每隔 10 分钟左右通过复制命令将数据从 csv 文件插入/追加到数据库中。可能会有一些重复的数据行,所以我想将数据从 csv 文件复制到 postgresql 表,但防止任何重复条目从 csv 文件进入表。共有三列,如果它们都相等,则表示该条目是重复的。它们是“纬度”、“经度”和“时间”。我应该从所有三列中创建一个复合键吗?如果我这样做,它会在尝试将 csv 文件复制到数据库时抛出错误吗?我将自动复制 csv 文件,因此我希望它继续复制不重复的文件的其余部分,而不是复制重复的文件。有没有办法做到这一点?

另外,我当然希望它以最有效的方式查找重复项。我不需要通过行上的时间戳查看整个表(这将是相当大的)重复...只是过去 20 分钟左右。我已经用时间列索引了数据库。

感谢您的帮助!

【问题讨论】:

    标签: postgresql csv postgis


    【解决方案1】:

    我想我会采取以下方法。

    首先,在您关心的三列上创建索引:

    create unique index idx_bigtable_col1_col2_col3 on bigtable(col1, col2, col3);
    

    然后,使用copy 将数据加载到临时表中。最后,你可以这样做:

    insert into bigtable(col1, . . . )
        select col1, . . .
        from stagingtable st
        where (col1, col2, col3) not in (select col1, col2, col3 from bigtable);
    

    假设没有其他数据修改正在进行,这应该可以完成您想要的。从性能的角度来看,使用索引检查重复项应该没问题。

    另一种方法是模拟 MySQL 的“重复键更新”以忽略此类记录。 Bill Karwin 建议在question 的回答中实施规则。规则的文档是here。触发器也可以做类似的事情。

    【讨论】:

    • 通过规则实现它确实有效,但向初学者建议它是一个坏主意,恕我直言。并且 wrt 性能,它不会给你带来任何好处,因为在引擎盖下它将有效地执行与硬编码版本相同的 SQL 步骤。
    • @wildplasser 。 . .很难拒绝比尔·卡尔文的推荐。不过,我同意你的看法。
    • 我非常感谢您的回复。我期待在短期内对其进行测试。我会尽快回复。
    • @user1610717 。 . .您可能还想问另一个问题。
    • 抱歉,没有意识到评论已发送。完美运行...谢谢!
    【解决方案2】:

    更新插入

    Answer by Linoff 是正确的,但可以通过Postgres 9.5 new ”UPSERT“ feature(又名MERGE)稍微简化一下。该新功能在 Postgres 中以 INSERT ON CONFLICT 语法实现。

    我们可以让ON CONFLICT 子句检测违规,而不是显式检查唯一索引的违规。然后我们DO NOTHING,这意味着我们放弃对INSERT 的努力,而不再尝试UPDATE。所以如果我们不能插入,我们就继续下一行。

    我们得到与 Linoff 的代码相同的结果,但丢失了 WHERE 子句。

    INSERT INTO bigtable(col1, … )
        SELECT col1, …
        FROM stagingtable st
    ON CONFLICT idx_bigtable_col1_col2_col
    DO NOTHING
    ;
    

    【讨论】:

    • 非常感谢您提供这个更新的答案!我会尝试把它放到数据库中。
    【解决方案3】:

    Basil Bourque 发的方法不错,只是语法有一点小错误。

    基于the documentation,我将其修改为以下,有效:

    INSERT INTO bigtable(col1, … )
        SELECT col1, …
        FROM stagingtable st
    ON CONFLICT (col1)
    DO NOTHING
    ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      相关资源
      最近更新 更多