将 CSV 文件批量加载到 PostgreSQL 的最佳方式 table
Best way to bulk load CSV file into PostgreSQL table
我在 D:\DataSet\business_names_202007/businessDataSet.csv
中有一个制表符分隔的 CSV 文件,其中包含 60 万条记录(可能会增加)。我想将整个数据加载到 postgresql table.
下面
PostgreSQL table:
CSV 文件结构:
正如您在上面的结构中看到的,CSV 文件和数据库之间的列数不同(“transform_business”列在数据库中是额外的)。在加载数据时我们也需要添加它,此列的值如下所示。
"transform_business" 数据库中的列值与 DataSet 中的 "BN_NAME" 相同,但有以下更改:转换为大写并且应删除单词之间的所有空格
例如:
BN_NAME:墨尔本碰撞修复
transform_business:墨尔本碰撞修复
工具:Dbeaver
数据库架构:testDev
table姓名:testdevtable
临时形成的copt语句:
COPY testdevtable(register_name,bn_name,bn_status,transform_business)
FROM 'D:\DataSet\business_names_202007/businessDataSet.csv' DELIMITER E’\t’ CSV HEADER;
如果是我的话,我会在业务 table 中添加一个 ON INSERT
触发器,在 INSERT
期间转换 bn_name
--> transform_business
。然后在 COPY
中保留 transform_business
。第二个选项是在加载之前进行转换,并将 transform_business
和新数据添加到 CSV 文件中。
将执行转换的示例 SQL 代码片段:
SELECT upper(replace('Melbourne Collision Repair Centre Mentone', ' ', ''));
upper
---------------------------------------
MELBOURNECOLLISIONREPAIRCENTREMENTONE
另一种选择是 COPY
(register_name,bn_name,bn_status) 进入数据库(table 上没有触发器)然后运行:
UPDATE business SET transform_business = upper(replace(bn_name, ' ', ''));
不确定之后会发生什么,transform_business 值是否将与新数据一起输入。如果 user/application 不打算输入它,那么我认为您又回到了 table 的业务触发器 运行s upper(replace(bn_name, ' ', ''))
.
也许您遗漏了一条有价值的信息:您的 Postgres 版本是什么 运行?如果您有或可以更新到版本 12,您可以重新定义 table,以便列 transform_business 是生成的列。那么例如:
create table table_name(
id bigint generated always as identity
, register_name text
, bn_name text
, status text
, transform_name text generated always as ( upper(replace(bn_name,' ',''))) stored
) ;
如果您需要维护当前数据,那么您可以:
alter table table_name drop column transform_name;
alter table table_name add transform_name text generated always as ( upper(replace(bn_name,' ',''))) stored;
这个选项会很慢,特别是如果 table 很大,但它是一次性过程。任何一个选项都会给你一个“约束”,即 transform_name 不能直接更新,但会在 bn_name 更新时自动更新。
那么您的复制命令只会加载 register_name、bn_name 和状态。
我在 D:\DataSet\business_names_202007/businessDataSet.csv
中有一个制表符分隔的 CSV 文件,其中包含 60 万条记录(可能会增加)。我想将整个数据加载到 postgresql table.
PostgreSQL table:
CSV 文件结构:
正如您在上面的结构中看到的,CSV 文件和数据库之间的列数不同(“transform_business”列在数据库中是额外的)。在加载数据时我们也需要添加它,此列的值如下所示。
"transform_business" 数据库中的列值与 DataSet 中的 "BN_NAME" 相同,但有以下更改:转换为大写并且应删除单词之间的所有空格
例如:
BN_NAME:墨尔本碰撞修复
transform_business:墨尔本碰撞修复
工具:Dbeaver
数据库架构:testDev
table姓名:testdevtable
临时形成的copt语句:
COPY testdevtable(register_name,bn_name,bn_status,transform_business)
FROM 'D:\DataSet\business_names_202007/businessDataSet.csv' DELIMITER E’\t’ CSV HEADER;
如果是我的话,我会在业务 table 中添加一个 ON INSERT
触发器,在 INSERT
期间转换 bn_name
--> transform_business
。然后在 COPY
中保留 transform_business
。第二个选项是在加载之前进行转换,并将 transform_business
和新数据添加到 CSV 文件中。
将执行转换的示例 SQL 代码片段:
SELECT upper(replace('Melbourne Collision Repair Centre Mentone', ' ', ''));
upper
---------------------------------------
MELBOURNECOLLISIONREPAIRCENTREMENTONE
另一种选择是 COPY
(register_name,bn_name,bn_status) 进入数据库(table 上没有触发器)然后运行:
UPDATE business SET transform_business = upper(replace(bn_name, ' ', ''));
不确定之后会发生什么,transform_business 值是否将与新数据一起输入。如果 user/application 不打算输入它,那么我认为您又回到了 table 的业务触发器 运行s upper(replace(bn_name, ' ', ''))
.
也许您遗漏了一条有价值的信息:您的 Postgres 版本是什么 运行?如果您有或可以更新到版本 12,您可以重新定义 table,以便列 transform_business 是生成的列。那么例如:
create table table_name(
id bigint generated always as identity
, register_name text
, bn_name text
, status text
, transform_name text generated always as ( upper(replace(bn_name,' ',''))) stored
) ;
如果您需要维护当前数据,那么您可以:
alter table table_name drop column transform_name;
alter table table_name add transform_name text generated always as ( upper(replace(bn_name,' ',''))) stored;
这个选项会很慢,特别是如果 table 很大,但它是一次性过程。任何一个选项都会给你一个“约束”,即 transform_name 不能直接更新,但会在 bn_name 更新时自动更新。
那么您的复制命令只会加载 register_name、bn_name 和状态。