You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何MySQL使用唯一索引并隐式类型转换时返回多行数据?

隐式类型转换导致唯一索引查询返回错误多行结果

这不是Bug,是MySQL隐式类型转换的特性引发的问题。当用数值类型匹配字符串列时,MySQL不会把数值转成字符串,反而会将字符串列的所有值转换为数值类型进行比较。

问题根源

你写的查询SELECT * FROM index_test WHERE string = 42356411000001102中,右侧的数值42356411000001102会被MySQL当作DOUBLE类型处理。DOUBLE的有效精度仅为53位二进制,对应十进制约15-17位,而你的两个字符串值是17位数字,转成DOUBLE时末尾的差异会被精度丢失抹平,导致CAST("42356411000001102" AS DOUBLE)与CAST("42356411000001104" AS DOUBLE)结果相等,因此查询返回了两行。

解决方案

  • 严格保持类型匹配,直接用字符串作为查询条件:
    SELECT * FROM index_test WHERE string = "42356411000001102";
    
  • 显式将数值转换为字符串后再比较:
    SELECT * FROM index_test WHERE string = CAST(42356411000001102 AS CHAR);
    

测试验证代码

DROP TABLE IF EXISTS index_test;

CREATE TABLE index_test (
    string VARCHAR(40),
    number BIGINT,
    
    UNIQUE INDEX uq_string(string),
    UNIQUE INDEX uq_number(number)
) ENGINE = INNODB;

INSERT INTO index_test
(string, number)
VALUES
("42356411000001102", 42356411000001102),
("42356411000001104", 42356411000001104);

-- 正常返回1行:原生BIGINT匹配
SELECT * FROM index_test WHERE number = 42356411000001102;
-- 正常返回1行:原生VARCHAR匹配
SELECT * FROM index_test WHERE string = "42356411000001102";
-- 正常返回1行:字符串转BIGINT匹配(无精度丢失)
SELECT * FROM index_test WHERE number = "42356411000001102";
-- 返回2行:字符串转DOUBLE时精度丢失,导致匹配两行
SELECT * FROM index_test WHERE string = 42356411000001102;

-- 验证精度丢失:两个值转DOUBLE后相等
SELECT CAST("42356411000001102" AS DOUBLE), CAST("42356411000001104" AS DOUBLE);

内容的提问来源于stack exchange,提问作者Tirinoarim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:57:31