【问题标题】:How to ignore rows that violate foreign key constraint in Postgres INSERT INTO?如何忽略 Postgres INSERT INTO 中违反外键约束的行?
【发布时间】:2023-03-27 16:37:01
【问题描述】:

在这条sql语句中

INSERT INTO child (parentId, value) SELECT parentId, value FROM temptable

child.parentId 是指向parent.id 的外键。 parent 表中的行可能会在此长时间运行的 INSERT INTO 语句(最多可插入几百万行)运行时被删除。

如果child 表在parent 中没有对应的外键之前 INSERT INTO 语句开始运行,或者如果parent 表中从child 引用的行是删除同时INSERT INTO 正在运行,我希望INSERT INTO 静默忽略该特定行(并简单地跳过插入child 违反外键约束的行),而不是整个语句失败。

我怎样才能做到这一点?我不熟悉在这种情况下任何竞争条件如何工作。

【问题讨论】:

    标签: sql postgresql foreign-keys sql-insert


    【解决方案1】:

    您可以尝试在SELECT 中锁定表parent 的引用行:

    INSERT INTO child (parent_id, value) 
        SELECT t.parent_id, t.value
        FROM temptable t
        JOIN parent p ON t.parent_id = p.id
        FOR UPDATE OF p;
    

    但是请注意,如果表 parent 同时被其他事务密集修改,这种预防性锁定可能会显着增加执行时间。

    作为一种补救措施,您可以考虑通过将数据划分为逻辑分区来在多个事务中执行插入,例如

    INSERT 
        ...
        WHERE parent_id < 1000
    
    INSERT 
        ...
        WHERE parent_id BETWEEN 1001 AND 2000 -- and so on.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 2022-11-11
      • 1970-01-01
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多