如何在避免 Postgresql 中的重复项的同时进行批量插入
How to do a bulk insert while avoiding duplicates in Postgresql
我在 nodejs 中工作,托管在 Heroku(目前免费计划)。
我自动从其他地方获取数据(这部分工作正常,我得到 JSON 或 CVS),我的目标是将它们添加到 Prostresql 数据库中。
虽然我是 DB 管理和 Postgresql 的新手,但我在发布这篇文章之前进行了研究。我知道 COPY command exist, and how to INSERT 多个数据没有重复。但我的问题是两者兼而有之(加上另一个困难)。
希望我的问题没有违反规则。
简版,我需要:
- 一次添加大量数据
- 永不重复
- 重命名源数据和我的 table
之间的列名称
长版 详细信息:
我收集的数据来自多个来源(目前为 2 个,但会越来越大)并且相当大 (>1000)。
我还需要将列名重新映射到一个统一的系统。在一个来源中可以称为 "firstDay" 的在另一个来源中称为 "dateBegin",我希望它们在我的 table.
中称为 "startDate"
如果我使用 INSERT,我会在构建查询时自己(在 JS 中)处理这个问题。但也许 COPY 可以以更好的方式做到这一点。此外,INSERT 似乎有一次可以推送的数据限制,因此我需要将查询分成多次,并且可能使用回调或 promise 来避免淹没数据库。
最后,我会定期自动更新这个数据库,它们会有很多重复。希望每条数据都有一个唯一的 ID,我在 table 中创建了一个列 PRIMARY KEY 来存储这个 ID。我认为它可以消除重复的任何问题,但我可能错了。
我的第一个版本非常丑陋(for 循环在每个循环中创建一个新查询)并且没有用。我正在考虑以递归方式一次处理 1000 个数据,等待回调,然后再发送另一批数据。那样做似乎很笨重而且很费时间。如果我可以 select/rename/remap 列并避免重复,COPY 似乎是完美的。我已经阅读了文档,但没有找到这样做的方法。
非常感谢,欢迎任何帮助。我还在学习,所以请多关照。
我在使用临时 table 到 "stage" 您的数据之前完成了此操作,然后执行 INSERT SELECT 将数据从暂存转移到您的生产 table .
要填充暂存区 table,您可以使用批量插入或复制。
例如,
BEGIN;
CREATE TEMPORARY TABLE staging_my_table ( // your columns etc );
// Now that you have your staging table you can bulk INSERT or COPY
// into it from your code, e.g.,
INSERT INTO staging_my_table (blah, bloo, firstDay) VALUES (1,2,3), (4,5,6), etc.
// Now you can do an INSERT into your live table from your staging, e.g.,
INSERT INTO my_table (blah, bloo, startDate)
SELECT cool, bloo, firstDay
FROM staging_my_table staging
WHERE NOT EXISTS (
SELECT 1
FROM mytable
WHERE staging.bloo = mytable.bloo
);
COMMIT;
总是有例外,但这可能适合您。
玩得开心
我在 nodejs 中工作,托管在 Heroku(目前免费计划)。
我自动从其他地方获取数据(这部分工作正常,我得到 JSON 或 CVS),我的目标是将它们添加到 Prostresql 数据库中。
虽然我是 DB 管理和 Postgresql 的新手,但我在发布这篇文章之前进行了研究。我知道 COPY command exist, and how to INSERT 多个数据没有重复。但我的问题是两者兼而有之(加上另一个困难)。
希望我的问题没有违反规则。
简版,我需要:
- 一次添加大量数据
- 永不重复
- 重命名源数据和我的 table 之间的列名称
长版 详细信息:
我收集的数据来自多个来源(目前为 2 个,但会越来越大)并且相当大 (>1000)。
我还需要将列名重新映射到一个统一的系统。在一个来源中可以称为 "firstDay" 的在另一个来源中称为 "dateBegin",我希望它们在我的 table.
中称为 "startDate"如果我使用 INSERT,我会在构建查询时自己(在 JS 中)处理这个问题。但也许 COPY 可以以更好的方式做到这一点。此外,INSERT 似乎有一次可以推送的数据限制,因此我需要将查询分成多次,并且可能使用回调或 promise 来避免淹没数据库。
最后,我会定期自动更新这个数据库,它们会有很多重复。希望每条数据都有一个唯一的 ID,我在 table 中创建了一个列 PRIMARY KEY 来存储这个 ID。我认为它可以消除重复的任何问题,但我可能错了。
我的第一个版本非常丑陋(for 循环在每个循环中创建一个新查询)并且没有用。我正在考虑以递归方式一次处理 1000 个数据,等待回调,然后再发送另一批数据。那样做似乎很笨重而且很费时间。如果我可以 select/rename/remap 列并避免重复,COPY 似乎是完美的。我已经阅读了文档,但没有找到这样做的方法。
非常感谢,欢迎任何帮助。我还在学习,所以请多关照。
我在使用临时 table 到 "stage" 您的数据之前完成了此操作,然后执行 INSERT SELECT 将数据从暂存转移到您的生产 table .
要填充暂存区 table,您可以使用批量插入或复制。
例如,
BEGIN;
CREATE TEMPORARY TABLE staging_my_table ( // your columns etc );
// Now that you have your staging table you can bulk INSERT or COPY
// into it from your code, e.g.,
INSERT INTO staging_my_table (blah, bloo, firstDay) VALUES (1,2,3), (4,5,6), etc.
// Now you can do an INSERT into your live table from your staging, e.g.,
INSERT INTO my_table (blah, bloo, startDate)
SELECT cool, bloo, firstDay
FROM staging_my_table staging
WHERE NOT EXISTS (
SELECT 1
FROM mytable
WHERE staging.bloo = mytable.bloo
);
COMMIT;
总是有例外,但这可能适合您。
玩得开心