返回

MySQL BINARY(16) 与 LIKE 查询的陷阱,你必须知道!

mysql

MySQL BINARY(16) 类型与 LIKE 查询的问题

简介

在 MySQL 中使用 BINARY(16) 类型进行 LIKE 查询时,可能会遇到意外的问题。在本文中,我们将深入探讨这个问题的原因及其解决方法。

问题

BINARY(16) 类型通常用于存储 16 字节的二进制数据,例如 ULID(Universally Unique Lexicographically Sortable Identifier)。当使用 LIKE 操作符查询 BINARY(16) 数据时,问题可能会出现在特定值上。

例如,对于 ULID 值 018e321f579997e1f2a907a72b98f965LIKE 查询可以正常工作。但是,对于 ULID 值 018e32448ce4605ca86ad3d4812de836LIKE 查询会失败。

原因分析

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 操作符正确解释为正则表达式。
  • 问:使用 BINARY 操作符有什么注意事项吗?

    • 答: BINARY 操作符只能比较二进制数据类型,并且它对大小写敏感。
  • 问:这个解决方案适用于其他二进制数据类型吗?

    • 答: 是的,该解决方案适用于任何二进制数据类型,包括 BLOBVARBINARY