这是在Postgres中批量插入冲突的正确方法吗?
问题描述:
我会提供一个我的问题的简单例子。这是在Postgres中批量插入冲突的正确方法吗?
我有两个表:reviews
和users
。
reviews
更新了用户发布的一堆评论。获取评论的过程也会为提交它的用户返回信息(并且频繁地更改某些用户数据)。
我想更新users
每当我更新reviews
,批量使用COPY
。当提取的数据包含来自同一用户的两个或更多评论时,问题出现在users
。如果我做了一个简单的INSERT ON CONFLICT
,我可能会因为错误而失败,并且INSERT
语句不能两次更新同一行。
A 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';
的原因,我做了SELECT DISTINCT
和ORDER BY
步骤3)是因为我:
- 只想要返回重复行的一个实例。
- 从这些 重复确保我得到 排序
account_age_in_mins
最新的记录。
这是实现我的目标的正确方法吗?
答
这是一个非常好的方法。 也许你可以避免表锁,当你只锁定临时表中的元组时。 https://dba.stackexchange.com/questions/106121/locking-in-postgres-for-update-insert-combination
看起来很不错。 –
@LaurenzAlbe很好听。任何你会做不同的事情? – Petar
乍一看,没有。 –