2016-03-19 215 views
0

我有一個應用程序,需要將用戶指定的CSV文件中的數據加載到PostgreSQL數據庫表中。將CSV文件中的數據加載到PostgreSQL數據庫中

CSV文件的結構很簡單:

name,email 
John Doe,[email protected] 
... 

在數據庫中,我有三個表:

--------------- 
-- 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文件,但將所有電子郵件彙總爲1'000個元素的批次。所有SELECT/INSERT查詢是使用SELECT id, email WHERE email IN ('...', '...', '...', ...)構造分批進行的。這種方法提高了性能,現在我的性能達到了每分鐘25k的記錄。但是,這種方法需要一個非常複雜的多步代碼才能工作。

有沒有更好的方法來解決這個問題,並獲得更高的性能?


這裏的關鍵問題是,我需要首先將數據插入到recipients表,然後我需要使用產生idsubmissions表中創建一個相應的記錄。

此外,我需要確保插入的電子郵件是唯一的。現在,我在我的應用程序中使用了一個簡單的基於數組的索引,以防止重複的電子郵件被添加到批處理中。

我正在使用Node.jsSequelizeKnex編寫我的應用程序,但是,具體的技術在這裏並不重要。

+0

將數據加載到臨時表中,然後使用你需要SQL/PostgreSQL的任何功能。 – Abelisto

+2

您是否熟悉COPY(http://www.postgresql.org/docs/9.5/static/sql-copy.html)命令?將其帶入臨時表,然後使用插入來填充目標表。(COPY不是標準的SQL btw) –

+0

使用COPY是最快的方法。請參閱:http://stackoverflow.com/questions/33271377/postgres-csv-copy-from-import-is-not-respecting-csv-headers –

回答

0

從1.16開始,pgAdmin擁有用於數據導入的GUI。您必須先創建表格,然後才能輕鬆導入數據 - 只需右鍵單擊表格名稱並單擊導入。

enter image description here

enter image description here

+0

我不能使用一些第三方圖形工具。我需要通過我自己的應用程序或至少通過某種API來完成此操作。 –

相關問題