2017-10-16 75 views
1

我会提供一个我的问题的简单例子。这是在Postgres中批量插入冲突的正确方法吗?

我有两个表:reviewsusers

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 DISTINCTORDER BY步骤3)是因为我:

  1. 只想要返回重复行的一个实例。
  2. 从这些 重复确保我得到 排序account_age_in_mins最新的记录。

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

+0

看起来很不错。 –

+0

@LaurenzAlbe很好听。任何你会做不同的事情? – Petar

+0

乍一看,没有。 –

回答

相关问题