2015-06-01 201 views
1

我正在使用mysql作爲我的數據庫的PHP應用程序。如何更新舊記錄時插入新記錄?

我必須解析csv表,並且只有在更新舊記錄時纔將數據插入到數據庫中。

一種方法是使用Ids從數據庫獲取記錄我已經在我的csv中檢查值,如果有差異,然後添加一條新記錄,但因爲我有數百MB的數據,我無法做到這一點來自數據庫,是否有一種完全在SQL中完成的方式?

Id不是唯一的,必須插入的新記錄將使用相同的ID。

例如,以下是目前的記錄
| 1001 | M丹麥語|新加坡|

和國家更改爲美國,表將有兩行如下
| 1001 | M丹麥語|新加坡|
| 1001 | M丹麥語| USA |

+0

'LOAD DATA INFILE' – Daan

+0

https://dev.mysql.com/doc/refman/5.0/en/insert-on-使用duplicate.html – rjdown

+0

向我們展示您已完成的工作。表結構,數據結構... ID是唯一的嗎?如果csv ID表示具有相同ID的配音中的記錄已更新,那麼將插入新行的ID是什麼? –

回答

0

正如我從你的問題的理解,你可以在你的數據庫表名稱「更新」值0或1(錯誤或真實)再次原始數據庫插入csv數據庫檢查該記錄然後做你的行爲作爲它的值(假或真)

0

往返數據庫往往相對昂貴。當面對這種情況時,我通常會嘗試存儲一個本地映射(即帶有字符串鍵的PHP數組)與要比較的值,這樣我只能循環訪問數據庫所需的更新/插入。

這裏是一個過於簡單化的例子進行說明的緣故:

// variable created in php file from previous run 
$records = [ 
    "1001 | M Danish | Singapore" => true 
    // ... other records 
]; 
// check if value present, a constant time operation on a map 
if (!isset($records["1001 | M Danish | USA"])) { 
    // insert into db 
} 

值得注意的是,上面的例子不會通過所有記錄遍歷,處理重複鍵,舊密鑰的缺失,等等。然而,希望通過在進行查詢之前在PHP中做一些快速的工作,它可以爲您大大減少數據庫往返次數(或一次往返的總體大小)提供一般想法。

+0

這是一個很好的解決方案,但是我有超過50K的記錄,有21列,並且隨着時間增長,所以將所有數據保存在內存中是不可行的。 – mdanishs

+0

@mdanishs它並不都必須存儲在內存中。地圖可以通過id或其他字段組合(類似於大型數據庫)在多個文件中分解(分片) – AdamJonR

+0

@mdanishs另外,您可以存儲校驗和/散列而不是列值以便觀察更改,而此會節省內存。 – AdamJonR

0

添加到您的表一個自動增量Id。然後在php中運行查詢來選擇與您在csv中的行匹配的最後一個ID。如果有差異,比較兩者並插入。這是我可以用你的表格結構考慮的最有效的方法。

我會創建一個表格,其中的數據不會更改,並且表格中包含重複ID(csv Id),您將只在更改時插入該表格。這會讓你的事情變得更容易和更快捷。第二個表格將自動增加Id以檢查csv中具有相同Id的最後一行。

希望它很清楚。

0

你可以運行插入忽略重複鍵更新sql。 如果你有一個獨特的鍵定義在列這隻會工作/你要的是獨一無二的

insert ignore into table1(col1, col2) 
values ('val1', 'val2') 
on duplicate key update 
col1 = VALUES(`col1`), 
col2 = VALUES(`col2`) 

這將更新一行值VAL1,VAL2,或插入如果該行娃沒有找到

,如果你有很多的插入/更新你可以用散貨

insert ignore into table1(col1, col2) 
values 
('val1', 'val2'), 
('val3', 'val4'), 
('val5', 'val6'), 
('val7', 'val8'), 
('val9', 'val10'), 
('val11', 'val12'), 
('val13', 'val14') 
on duplicate key update 
col1 = VALUES(`col1`), 
col2 = VALUES(`col2`)