这是在 Postgres 中批量插入冲突的正确方法吗?

Is this the correct way to bulk INSERT ON CONFLICT in Postgres?

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

我有两个 table:reviewsusers

reviews 更新了用户 post 的一堆评论。获取评论的过程还 return 提交评论的用户的信息(并且某些用户数据经常更改)。

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

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

1.创建一个临时的 table 以便我们可以 COPY to/from 它。

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

2。 COPY数据进入临时table

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

3。锁定userstable并执行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. 只想 return 重复行的一个实例。
  2. 从那些 重复确保我得到最新的记录 在 account_age_in_mins.
  3. 上排序

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

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