这是在 Postgres 中批量插入冲突的正确方法吗?
Is this the correct way to bulk INSERT ON CONFLICT in Postgres?
我将提供一个简化的问题示例。
我有两个 table:reviews
和 users
。
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。锁定users
table并执行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 DISTINCT
和 ORDER BY
的原因是因为我:
- 只想 return 重复行的一个实例。
- 从那些
重复确保我得到最新的记录
在
account_age_in_mins
. 上排序
这是实现我目标的正确方法吗?
这是一个很好的方法。
当你只锁定临时 table 中的元组时,也许你可以避免 table-lock。
https://dba.stackexchange.com/questions/106121/locking-in-postgres-for-update-insert-combination
我将提供一个简化的问题示例。
我有两个 table:reviews
和 users
。
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。锁定users
table并执行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 DISTINCT
和 ORDER BY
的原因是因为我:
- 只想 return 重复行的一个实例。
- 从那些
重复确保我得到最新的记录
在
account_age_in_mins
. 上排序
这是实现我目标的正确方法吗?
这是一个很好的方法。 当你只锁定临时 table 中的元组时,也许你可以避免 table-lock。 https://dba.stackexchange.com/questions/106121/locking-in-postgres-for-update-insert-combination