使用二进制排序规则有啥影响?
Posted
技术标签:
【中文标题】使用二进制排序规则有啥影响?【英文标题】:What effects does using a binary collation have?使用二进制排序规则有什么影响? 【发布时间】:2011-07-28 10:25:11 【问题描述】:在回答 this question 时,我对一些我无法找到足够答案的事情感到不确定。
使用二进制 utf8_bin
和不区分大小写的 utf8_general_ci
排序规则之间有什么实际区别?
我可以看到三个:
两者的排序顺序不同; _bin
的排序顺序很可能会将任何变音符号放在字母表的末尾,因为比较的是字节值(对吗?)
_bin
中仅区分大小写搜索
A = Ä
不等于 _bin
还有其他需要注意的差异或副作用吗?
参考:
9.1.2. Character Sets and Collations in mysql 9.1.7.6. The _bin and binary Collations 在 mySQL 手册中 9.1.7.7. The BINARY Operator没有解决问题的类似问题:
UTF-8: General? Bin? Unicode?【问题讨论】:
【参考方案1】:如果字符不同(只是大小写或变音符号不同),二进制排序规则会完全按照 C 语言中的 strcmp()
来比较您的字符串。它的缺点是排序顺序不自然。
非自然排序顺序的示例(如“二进制”中的):A,B,a,b
在这种情况下,自然排序顺序是例如:A,a,B,b
(同一字母的小写和大写变体彼此相邻排序)
二进制排序的实际优势在于它的速度,因为字符串比较非常简单/快速。在一般情况下,二进制索引可能不会产生预期的排序结果,但对于精确匹配,它们可能很有用。
【讨论】:
感谢您提供的示例,它们很好地说明了问题。 以防万一,我需要涉及相当大的表的区分大小写的比较(就数据量而言 ~ 超过 400 万条记录)。我最近遇到了这个问题,使用 utf_8_unicode_ci 排序规则,我的查询在性能方面做得很好,但不会产生完全匹配。如果我将排序规则更改为 utf8_bin,它在性能方面就会死掉......在性能方面有很大的差异 对上述内容的小幅修正。它几乎与 strcmp() 一样工作,但不是 100% 完全正确。根据 SQL 标准,需要比较不同长度的字符串,就好像较短的字符串用空格字符(0x20)填充一样,直到较大的字符串的长度。在大多数情况下,它的行为类似于 strcmp(),但在涉及字节 jira.mariadb.org/browse/MDEV-9711)【参考方案2】:使用 utf8_general_ci,匹配发生时不考虑大小写和重读。当您需要对单词执行查询时,这可能是一件好事。
在utf8_bin中,匹配只发生在字符串严格相同的情况下。这样查询速度更快。
【讨论】:
utf8_bin 比 latin1_bin 或 ascii_bin 快吗? 否,但 _bin 应该比 _ci 快,因为不区分大小写的查询(或索引)涉及字符串转换。了解多快的最佳方法是针对包含许多条目的数据库进行测试。【参考方案3】:utf8_bin
:按字符串中每个字符的二进制值比较字符串。
utf8_general_ci
:使用通用语言规则和不区分大小写的比较来比较字符串。
utf8_general_cs
:使用通用语言规则和区分大小写的比较来比较字符串。
例如,以下将使用 UTF8_general
排序规则中的任何一个计算为 true,但不适用于 utf8_bin
排序规则:
Ä = A
Ö = O
Ü = U
使用utf8_general_ci
排序规则,即使情况不同,它们也会返回true
。
http://www.phpbuilder.com/board/showpost.php?s=2e642ac7dc5fceca2dbca1e2b9c424fd&p=10820221&postcount=2
【讨论】:
*_cs 是否比 *_ci 快?用于英语/ASCII 字符串【参考方案4】:其他答案很好地解释了差异。
二进制排序规则在某些情况下很有用:
列包含密码哈希等十六进制数据 您只对完全匹配感兴趣,而不是排序 对于只有 [a-z0-9_] 字符的标识符,您甚至可以使用它进行排序 出于某种原因,您将数字存储在 CHAR() 或 VARCHAR 列中(如电话) 邮政编码 UUID 等在所有这些情况下,您都可以使用二进制排序规则节省(少量)cpu 周期。
【讨论】:
什么类型的二进制文件? ascii_bin、utf8_bin、latin1_bin 等...?以上是关于使用二进制排序规则有啥影响?的主要内容,如果未能解决你的问题,请参考以下文章