为什么 MySQL 在唯一索引上返回多行(转换时)?

问题描述 投票:0回答:1

不确定这是否是一个错误,但是当使用唯一索引(和隐式类型转换)从表中进行选择时,会返回多行,其中一行显然是错误的。

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
mysql
1个回答
0
投票

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 |
+---------------------+---------------------+---------+
© www.soinside.com 2019 - 2024. All rights reserved.