MySQL BINARY(16) 与 LIKE 查询的陷阱,你必须知道!
2024-03-21 13:40:47
MySQL BINARY(16) 类型与 LIKE 查询的问题
简介
在 MySQL 中使用 BINARY(16)
类型进行 LIKE
查询时,可能会遇到意外的问题。在本文中,我们将深入探讨这个问题的原因及其解决方法。
问题
BINARY(16)
类型通常用于存储 16 字节的二进制数据,例如 ULID(Universally Unique Lexicographically Sortable Identifier)。当使用 LIKE
操作符查询 BINARY(16)
数据时,问题可能会出现在特定值上。
例如,对于 ULID 值 018e321f579997e1f2a907a72b98f965
,LIKE
查询可以正常工作。但是,对于 ULID 值 018e32448ce4605ca86ad3d4812de836
,LIKE
查询会失败。
原因分析
LIKE
操作符的工作原理是将查询模式中的通配符(%
和 _
)转换为正则表达式。但是,对于二进制数据类型,LIKE
操作符无法正确解释这些通配符。
具体来说,在给定的示例中,查询模式 018e321f579997e1f2a907a72b98f965
可以被解释为正则表达式,但 018e32448ce4605ca86ad3d4812de836
却不行。这导致查询无法识别查询模式和实际值的匹配。
解决方法
为了解决这个问题,可以使用 BINARY
操作符代替 LIKE
操作符。BINARY
操作符在比较二进制数据时不会将通配符转换为正则表达式,从而可以准确比较二进制值。
修改后的查询:
SELECT HEX(id), name FROM new_table WHERE id BINARY UNHEX("018e321f579997e1f2a907a72b98f965");
SELECT HEX(id), name FROM new_table WHERE id BINARY UNHEX("018e32448ce4605ca86ad3d4812de836");
通过使用 BINARY
操作符,查询将成功返回匹配的 id
值,即使对于特定 ULID 值 018e32448ce4605ca86ad3d4812de836
也是如此。
结论
当使用 BINARY(16)
类型进行 LIKE
查询时,必须意识到通配符转换的问题。通过使用 BINARY
操作符作为替代方案,可以避免此问题并准确比较二进制数据。
常见问题解答
-
问:为什么
LIKE
操作符不能正确解释BINARY(16)
数据中的通配符?- 答:
LIKE
操作符将通配符转换为正则表达式,这对于二进制数据类型是不合适的。
- 答:
-
问:除了
BINARY
操作符之外,还有什么其他方法可以比较BINARY(16)
数据?- 答: 可以使用比较操作符(例如
=
、!=
)或其他二进制比较函数。
- 答: 可以使用比较操作符(例如
-
问:为什么特定的 ULID 值
018e32448ce4605ca86ad3d4812de836
导致查询失败?- 答: 这个特定的 ULID 值无法被
LIKE
操作符正确解释为正则表达式。
- 答: 这个特定的 ULID 值无法被
-
问:使用
BINARY
操作符有什么注意事项吗?- 答:
BINARY
操作符只能比较二进制数据类型,并且它对大小写敏感。
- 答:
-
问:这个解决方案适用于其他二进制数据类型吗?
- 答: 是的,该解决方案适用于任何二进制数据类型,包括
BLOB
和VARBINARY
。
- 答: 是的,该解决方案适用于任何二进制数据类型,包括