扫码关注官方订阅号
一组很长的数据在向一个很大的表中做插入操作时,如何有效率地判断要插入的数值是否与数据库中已有的值重复了? 假设这个表的字段比较多,只有一个id是unqiue的。
闭关修行中......
可以使用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
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
可以使用hash.
方案:
假设该表有10个字段,1个是unique的主键,你可以在插入字段时将要比较重复的其他字段(这里我们假设是其他9个字段)连成字符串,取 hash 值,放进缓存(数据量比较小的话可以考虑 memcached, 比较大的话可以考虑 Redis),用 hash->id 存储。
这样,在插入新数据的时候,只要把要比较的字段按照相同的方式连起来取 hash值,到缓存里找一下,就可以很快找到是否有相同的了,有的话,再取出 id,到数据库中取出整条数据。
本方案的缺陷就是额外使用了缓存。如果没有条件的话,可以稍加改进。再建一个表,里面只有两个字段, hash 和 id,这个表专门用来做这个功能。想必比比较9个字段要快得多吧。
不邀自答。这个问题,刚好昨天也遇到过,google了一下stackoverflow.com,建议的答案是使用:
例如:
只要 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