【问题标题】:Is this the correct way to bulk INSERT ON CONFLICT in Postgres?这是在 Postgres 中批量插入冲突的正确方法吗?
【发布时间】:2018-03-28 02:08:49
【问题描述】:

我将提供一个关于我的问题的简化示例。

我有两个表:reviewsusers

reviews 更新了用户发布的大量评论。获取评论的过程还会为提交评论的用户返回信息(并且某些用户数据经常更改)。

我想在每次更新 reviews 时使用 COPY 批量更新 users。当获取的数据包含来自同一用户的两个或多个评论时,users 会出现问题。如果我做一个简单的INSERT ON CONFLICT,我可能会遇到错误,因为INSERT 语句不能两次更新同一行。

SELECT DISTINCT 可以解决这个问题,但我也想保证将最新数据插入到users 表中。我就是这样做的。请记住,我是批量执行此操作:

1.创建一个临时表,以便我们可以COPY 访问/接收它。

CREATE TEMPORARY TABLE users_temp (
    id uuid, 
    stat_1 integer, 
    stat_2 integer, 
    account_age_in_mins integer);

2。 COPY 数据存入临时表

COPY users_temp (
    id,
    stat_1,
    stat_2,
    account_age_in_mins) FROM STDIN CSV ENCODING 'utf-8';

3.锁定users表并执行INSERT ON CONFLICT

LOCK TABLE users in EXCLUSIVE MODE;

INSERT INTO users SELECT DISTINCT ON (1) 
    users_temp.id,
    users_temp.stat_1,
    users_temp.stat_2,
    users_temp.account_age_in_mins
FROM users_temp
ORDER BY 1, 4 DESC, 2, 3
ON CONFLICT (id) DO UPDATE
SET
    stat_1 = EXCLUDED.stat_1,
    stat_2 = EXCLUDED.stat_2,
    account_age_in_mins = EXCLUDED.account_age_in_mins';

我在步骤 3) 中使用 SELECT DISTINCTORDER BY 的原因是因为我:

  1. 只想返回重复行的一个实例。
  2. 从那些 重复确保我通过以下方式获得最新记录 在account_age_in_mins 上排序。

这是实现我的目标的正确方法吗?

【问题讨论】:

  • 看起来不错。
  • @LaurenzAlbe 很高兴听到。你有什么不同的做法吗?
  • 乍一看,没有。

标签: postgresql bulkinsert upsert


【解决方案1】:

这是一个非常好的方法。 当您只锁定临时表中的元组时,也许您可​​以避免表锁。 https://dba.stackexchange.com/questions/106121/locking-in-postgres-for-update-insert-combination

【讨论】:

    猜你喜欢
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2012-03-01
    • 2011-02-26
    • 2016-05-17
    • 2014-05-05
    • 2013-06-28
    相关资源
    最近更新 更多