不确定这是否是一个错误,但是当使用唯一索引(和隐式类型转换)从表中进行选择时,会返回多行,其中一行显然是错误的。
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);
SELECT * FROM index_test WHERE number = 42356411000001102; -- 1 Row NATIVE BIGINT
SELECT * FROM index_test WHERE string = "42356411000001102"; -- 1 Row NATIVE VARCHAR
SELECT * FROM index_test WHERE number = "42356411000001102"; -- 1 Row CASTING
SELECT * FROM index_test WHERE string = 42356411000001102; -- 2 ROWS!!! CASTING
https://dev.mysql.com/doc/refman/8.0/en/type-conversion.html说:
以下规则描述了比较操作如何进行转换:
...
- 在所有其他情况下,参数将作为浮点(双精度)数字进行比较。例如,字符串和数字操作数的比较就像浮点数的比较一样。
将字符串与数字进行比较属于“所有其他情况”类别。您显示的数字被转换为
DOUBLE
,但这没有足够的精度来表示如此大的数字而不进行四舍五入。
mysql> select cast('42356411000001100' as double) as `string`,
cast(42356411000001100 as double) as `number`,
cast('42356411000001100' as double) = cast(42356411000001100 as double) as `matches`;
+---------------------+---------------------+---------+
| string | number | matches |
+---------------------+---------------------+---------+
| 4.23564110000011e16 | 4.23564110000011e16 | 1 |
+---------------------+---------------------+---------+