2015-06-01 157 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`)