2013-10-25 59 views
0

我有一個數據庫(Postgres的)兩個表:加載規格化數據插入到數據庫

CREATE TABLE invoices (
    id bigint, 
    some_data varchar 
) 

CREATE TABLE charges (
    id bigint, 
    invoice_id bigint, 
    some_data varchar 
) 

我試圖加載csv文件格式如下這個數據庫:

invoice_id, invoice_data, charge_id, charge_data 

例如,我可以在我的csv文件下面幾行:

1, $10.00, 1, $2.00 
1, $10.00, 2, $5.00 
1, $10.00, 3, $3.00 
2, $2.00, 4, $1.00 
2, $2.00, 5, $1.00 
3, $11.00, 6, $11.00 

該數據應符合下列RECO rds在數據庫中:

SELECT * FROM invoices; 
    id | some_data 
-----+------------- 
    1 | $10.00 
    2 | $2.00 
    3 | $11.00 

SELECT * FROM charges; 
    id | invoice_id | some_data 
-----+------------+------------- 
    1 | 1   | $2.00 
    2 | 1   | $5.00 
    3 | 1   | $3.00 
    4 | 2   | $1.00 
    5 | 2   | $1.00 
    6 | 3   | $11.00 

是否有加載此類數據的「最佳實踐」?目前,我正在將此文件加載到中間表中並使用php腳本(壞)進行處理。這是非常低效的。有沒有更好的辦法?我是否應該將此加載到中間表中,然後使用存儲過程來拆分信息?或者我應該直接處理我的.csv文件,並將這些信息分解成某種腳本?

+3

首先(使用COPY)加載到臨時表中,然後使用普通SQL將數據分發到兩個目標表是加載和按摩數據的常用方法。 – bma

+0

我應該爲此創建一個存儲過程嗎?或者只是使用文件加載腳本將sql保存在某個地方? – grobolom

+1

一個db函數(在Postgres中它們是函數,而不是存儲過程)是一種簡單的方法來封裝將數據從一個表移動到其他表的邏輯,所以工作得很好。如果列和表經常變化,在你的加載腳本中保留普通的SQL可能會更有意義,但如果它是合理的靜態,我會傾向於去函數路由。 – bma

回答

1

可以使用COPY命令首先將數據加載到結構與CSV匹配的中間表(例如:COPY intermediary_table FROM'/path/to/csv/charges.csv'DELIMITER','CSV;) ,然後選擇數據到每個表中。第一個查詢將是一個SELECT DISTINCT invoice_id,invoice_data INTO invoices FROM intermediary_table,第二個查詢SELECT DISTINCT charge_id,invoice_id,charge_data INTO收取intermediary_table。

順便說一句,你很可能不需要使用bigint(除非你期望數十億行)。