最近在项目中,需要对数据进行插表操作,由于数据量较大,按照一般的insert into将会有for循环操作,但所在公司部门产品流量大,对性能要求高;所以选择批量插入;下面将简单介绍一下最终选择批量SQL过程,这节可能会是你成为大牛的基石:
之前使用:
insert into user_info (user_id,user_name,status,years)values (123,'你好',1,15);
或者:
insert into user_info set user_id=123,user_name=“你好”,status=1,years=15;
这样的单句SQL插入,即使批量,也是循环进行:
for(int i=0;iquery(strSql);
Bingo_Timer::end('dbquery');
}
其中的strSql也就是insert into user_info (user_id,user_name,status,years)values (123,'你好',1,15);
慢慢地,会使用:
insert into user_info (user_id,user_name,status,years)values (123,'你好',1,15),(456,"你好",2,16);
上面描述的可能就是日常小项目中的表场景;但下面就是干货啦:
当在项目中插表操作时,可能并不知道所插的数据是否已经在表中,是不是会出现唯一索引冲突的情况,这些都是在批量插入时需要考虑的;
在上面所说的场景正是ON DUPLICATE KEY UPDATE和REPLACE的用武之地,也是下文的重点:
ON DUPLICATE KEY UPDATE:如果插入行出现唯一索引或者主键重复时,则执行旧的update;如果不会导致唯一索引或者主键重复时,就直接添加新行。
REPLACE:如果插入行出现唯一索引或者主键重复时,则delete老记录,而录入新的记录;如果不会导致唯一索引或者主键重复时,就直接添加新行。
比较:
1、在没有主键或者唯一索引重复时,replace与insert on deplicate udpate相同。
2、在主键或者唯一索引重复时,replace是delete老记录,而录入新的记录,所以原有的所有记录会被清除,这个时候,如果replace语句的字段不全的话,有些原有的比如c字段的值会被自动填充为默认值。
如果以user_id 为主键,则:
insert into user_info (user_id,user_name,status,years)values (123,'你好',1,15)on duplicate update user_name =values(user_name);
此时,当user_id冲突时 ,将会保持主键不变,更改user_name,其他数据项操持原数据;
replace into user_info (user_id,user_name,status,years)values (123,'你好',1,15);
此时,(into 可省略)当user_id冲突时 ,将会删除原数据,新加数据项;
注意:
duplicate update则只执行update标记之后的sql,它保留了所有字段的旧值,只更新update后面的语句;
而replace没有保留旧值,直接删除再insert新值,原有的所有记录会被清除,如果replace语句的字段不全的话,有些原有的比如c字段的值会被自动填充为默认值。
使用的时候结合场景选择。