mysql数据库插入,检测重复。

一组很长的数据在向一个很大的表中做插入操作时,如何有效率地判断要插入的数值是否与数据库中已有的值重复了?
假设这个表的字段比较多,只有一个id是unqiue的。

阅读 21.9k
9 个回答

可以使用hash.

方案:

假设该表有10个字段,1个是unique的主键,你可以在插入字段时将要比较重复的其他字段(这里我们假设是其他9个字段)连成字符串,取 hash 值,放进缓存(数据量比较小的话可以考虑 memcached, 比较大的话可以考虑 Redis),用 hash->id 存储。

这样,在插入新数据的时候,只要把要比较的字段按照相同的方式连起来取 hash值,到缓存里找一下,就可以很快找到是否有相同的了,有的话,再取出 id,到数据库中取出整条数据。

本方案的缺陷就是额外使用了缓存。如果没有条件的话,可以稍加改进。再建一个表,里面只有两个字段, hash 和 id,这个表专门用来做这个功能。想必比比较9个字段要快得多吧。

$str = $f1 . $f2 . $f3 ... . $f9; // 如果有非字符串类型,安全起见可以考虑转一下类型
$hash = md5($str);

// 从 redis 或其他数据库中取出,如果为空,就保存,如果有,做其他操作
$rs = $redis->get($hash);
if(!$rs){
    // code for saving
    // 保存完别忘了把这条记录插入缓存
    $redis->set($hash, $id);
}else{
    // return to frontend
}

不邀自答。这个问题,刚好昨天也遇到过,google了一下stackoverflow.com,建议的答案是使用:

insert ... on duplicate key update

例如:

insert into table (id, name, age) values(1, "A", 19) on duplicate key update name=values(name), age=values(age)

只要 key 是相同的,就会进行更新。

1、对于主键和唯一索引,可以用IGNORE关键字,遇到重复记录会直接忽略插入记录,返回0。
insert ignore into table_name ('id','name') values (1,'eddy')
2、replace关键字:REPLACE的运行与INSERT很相像,但是如果旧记录与新记录有相同的值,则在新记录被插入之前,旧记录被删除。REPLACE返回受影响的行数。
replace into table_name ('id','name') values (1,'eddy')
3、ON DUPLICATE KEY UPDATE:遇到重复的记录则更新指定的字段。如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2。
insert ignore into table_name ('id','name') values (1,'eddy') on duplicate key update id = 100

如果是mysql数据库,建议你使用replace语句:
我们在使用数据库时可能会经常遇到这种情况。如果一个表在一个字段上建立了唯一索引,当我们再向这个表中使用已经存在的键值插入一条记录,那将会抛出 一个主键冲突的错误。当然,我们可能想用新记录的值来覆盖原来的记录值。如果使用传统的做法,必须先使用DELETE语句删除原先的记录,然后再使用 INSERT插入新的记录。而在MySQL中为我们提供了一种新的解决方案,这就是REPLACE语句。使用REPLACE插入一条记录时,如果不重 复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。

小数据量无所谓,插入前取出验证即可几百万条索引查询无所谓的。大数据验证缓存。

楼上说的对,那就借助nosql,把你这组长数据当作key,存入nosql,当用户插入数据的时候直接get下是否为真,真就是已经存在

我不用mysql的sql去处理,我用对象的方式去做处理,以对象的方式取出记录,做对象的字段的反射获取,形成数组,然后对比

还是用数据库自己有的能力来做吧,nosql那个方案没考虑并发,nosql本身无法和数据库操作形成一个事务,真这么干运行时还是会有重复数据的。

新手上路,请多包涵

insert ... on duplicate key update
同@ljy520zhiyong143

推荐问题
宣传栏