简体   繁体   English

MySQL中BIT(64)列的奇怪行为

[英]Strange behaviour of BIT(64) column in MySQL

Can anyone help me understand the following problem with a BIT(64) column in MySQL (5.7.19). 谁能帮助我了解MySQL(5.7.19)中BIT(64)列的以下问题。

This simple example works fine and returns the record from the temporary table: 这个简单的示例工作正常,并从临时表返回记录:

CREATE TEMPORARY TABLE test (v bit(64));
INSERT INTO test values (b'111');
SELECT * FROM test WHERE v = b'111';
-- Returns the record as expected

When using all the 64 bits of the column it no longer works: 当使用列的所有64位时,它将不再起作用:

CREATE TEMPORARY TABLE test (v bit(64));
INSERT INTO test values (b'1111111111111111111111111111111111111111111111111111111111111111');
SELECT * FROM test WHERE v = b'1111111111111111111111111111111111111111111111111111111111111111';
-- Does NOT return the record

This only happens when using a value with 64 bits. 这仅在使用64位值时发生。 But I would expect that to be possible. 但我希望这是可能的。

Can anyone explain this to me? 有人可以向我解释吗?

Please do not respond by advising me not to use BIT columns. 请不要建议我不要使用BIT列。 I am working on a database tool that should be able to handle all the data types of MySQL. 我正在使用一个数据库工具,该工具应该能够处理MySQL的所有数据类型。

Bits are returned as binary, so to display them, either add 0, or use a function such as HEX, OCT or BIN to convert them https://mariadb.com/kb/en/library/bit/ or Bit values in result sets are returned as binary values, which may not display well. 位以二进制形式返回,因此要显示它们,可以加0或使用HEX,OCT或BIN之类的函数将它们转换为https://mariadb.com/kb/en/library/bit/或结果中的位值集以二进制值形式返回,可能无法很好地显示。 To convert a bit value to printable form, use it in numeric context or use a conversion function such as BIN() or HEX(). 要将位值转换为可打印形式,请在数字上下文中使用它,或使用诸如BIN()或HEX()之类的转换函数。 High-order 0 digits are not displayed in the converted value. 转换后的值中不显示高位0位数。 https://dev.mysql.com/doc/refman/8.0/en/bit-value-literals.html https://dev.mysql.com/doc/refman/8.0/zh-CN/bit-value-literals.html

The problem seems to be, that the value b'11..11' in the WHERE clause is considered to be a SIGNED BIGINT which is -1 and is compared to the value in your table which is considered to be an UNSIGNED BIGINT which is 18446744073709551615 . 问题似乎是,WHERE子句中的值b'11..11'被认为是-1SIGNED BIGINT ,并与表中被认为是UNSIGNED BIGINT进行比较。 18446744073709551615 This is always an issue when the first of 64 bits is 1 . 当64位的第一个为1时,这始终是一个问题。 IMHO this is a bug or a design flaw, because I expect an expression in the WHERE clause to match a row if the same expression has been used in the INSERT satement (at least in this case). 恕我直言,这是一个错误或设计缺陷,因为如果在INSERT状态中使用了相同的表达式(至少在这种情况下),我希望WHERE子句中的表达式与一行匹配。

One workaround would be to cast the value to UNSIGNED : 一种解决方法是将值转换为UNSIGNED

SELECT * 
FROM test
WHERE v = CAST(b'1111111111111111111111111111111111111111111111111111111111111111' as UNSIGNED);

Or (if your application language supports it) convert it to something like long uint or decimal : 或者(如果您的应用程序语言支持)将其转换为long uintdecimal

SELECT * FROM test WHERE v = 18446744073709551615;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM