将CSV文件中的数据加载到PostgreSQL数据库中

时间:2016-03-19 22:15:11

标签: database postgresql csv

我有一个应用程序,需要将用户指定的CSV文件中的数据加载到PostgreSQL数据库表中。

CSV文件的结构很简单:

name,email
John Doe,john@example.com
...

在数据库中,我有三个表:

---------------
-- CAMPAIGNS --
---------------

CREATE TABLE "campaigns" (
    "id"         serial  PRIMARY KEY,
    "name"       citext  UNIQUE CHECK ("name" ~ '^[-a-z0-9_]+$'),
    "title"      text
);

----------------
-- RECIPIENTS --
----------------

CREATE TABLE "recipients" (
    "id"           serial  PRIMARY KEY,
    "email"        citext  UNIQUE CHECK (length("email") <= 254),
    "name"         text
);


-----------------
-- SUBMISSIONS --
-----------------

CREATE TYPE "enum_submissions_status" AS ENUM (
    'WAITING',
    'SENT',
    'FAILED'
);

CREATE TABLE "submissions" (
    "id"           serial                     PRIMARY KEY,
    "campaignId"   integer                    REFERENCES "campaigns"   ON UPDATE CASCADE  ON DELETE CASCADE  NOT NULL,
    "recipientId"  integer                    REFERENCES "recipients"  ON UPDATE CASCADE  ON DELETE CASCADE  NOT NULL,
    "status"       "enum_submissions_status"  DEFAULT 'WAITING',
    "sentAt"       timestamp with time zone
);

CREATE UNIQUE INDEX "submissions_unique" ON "submissions" ("campaignId", "recipientId");
CREATE INDEX "submissions_recipient_id_index" ON "submissions" ("recipientId");

我想读取指定CSV文件中的所有行,并确保recipientssubmissions表中存在相应记录。

在这些表中加载数据的性能最有效的方法是什么?

这主要是一个概念性问题,我不是要求具体实施。

  • 首先,我天真地尝试逐行阅读和解析CSV文件,并为每封电子邮件发出SELECT/INSERT次查询。显然,这是一个非常缓慢的解决方案,允许我每分钟加载~4k记录,但代码非常简单明了。

  • 现在,我逐行读取CSV文件,但将所有电子邮件聚合成一批1000个元素。所有SELECT/INSERT个查询都是使用SELECT id, email WHERE email IN ('...', '...', '...', ...)构造批量生成的。这种方法提高了性能,现在我的性能达到每分钟约25k。但是,这种方法要求使用相当复杂的多步骤代码。

有没有更好的方法来解决这个问题并获得更好的性能?

这里的关键问题是我需要先将数据插入recipients表,然后我需要使用生成的idsubmissions表中创建相应的记录。

另外,我需要确保插入的电子邮件是唯一的。现在,我在我的应用程序中使用了一个简单的基于数组的索引,以防止将重复的电子邮件添加到批处理中。

我正在使用Node.jsSequelizeKnex编写我的应用,但是,具体技术在这里并不重要。

1 个答案:

答案 0 :(得分:0)

pgAdmin具有自1.16以来的数据导入GUI。您必须先创建表,然后才能轻松导入数据 - 只需右键单击表名并单击“导入”。

enter image description here

enter image description here