问题背景:
MySQL版本8.0,id为表的主键,字段定义:id
varchar(22) COLLATE utf8mb4_general_ci NOT NULL COMMENT ‘主键ID’,线上数据更新,提交sql工单,sql工单工具提示影响条数很多,不是只有一条,变更sql如下:
update table set a = 1 where id = 1915266715287552123
原因:
发生了隐式转换,当字段为varchar类型,而条件数值为数字类型时,mysql会尝试将数据库中id都转换成double类型与对应的条件数值进行比对;但当数据库中的id值超过16位时,使用的是科学计数法比较,以1915266715287552124为例,会转换成 1.915266715287552E+18,其他1915266715287552111、1915266715287552112等前16为位1915266715287552的19位数字都会转换成1.915266715287552E+18,sql的条件数值1915266715287552123也会转换成1.915266715287552E+18,因此sql条件会判断为相等,导致影响的数据条数就不止一条了
影响:
1、影响数据范围错误,数据范围相当于 update table set a = 1 where id like ‘1915266715287552%’;
2、隐式转换,导致sql不走索引,会全表扫描;
结论:
1、如果主键id是varchar类型,按id修改时,数值一定要用单引号引起来,使用
update table set a = 1 where id = ‘1915266715287552123’ 变更数据。
2、即使id的数据范围是小于等于16位的数字,也要加单引号,防止索引失效,发生全表扫描;