编程后端开发工程师

如何在SQL中使用不同的COLLATION(排序规则)实现有效的数据排序?对不同语言和字母表的支持有什么特点?

用 Hintsage AI 助手通过面试

回答

在处理文本数据时,通常需要支持不同的语言和字母表。为此,SQL使用排序规则——COLLATION。COLLATION定义了字符串的比较和排序方式。在列、表或查询级别正确设置COLLATION,以便正确处理语言特性(例如,ё ≠ е)。

示例:

SELECT * FROM users ORDER BY username COLLATE 'ru_RU.UTF8';

该查询按俄语字母顺序对用户进行排序。在不同的数据库管理系统中,collate的语法可能有所不同。

  • 对于MySQL:COLLATE utf8mb4_unicode_ciutf8mb4_ru_0900_as_cs来考虑大小写和语言。
  • 对于MSSQL:COLLATE Cyrillic_General_CS_AS——支持俄语,区分大小写(CS = case sensitive,AS = accent sensitive)。

重要提示: COLLATION也会影响搜索(LIKE、比较),不仅限于排序!

反问

在一个查询中,对不同COLLATION的字符串进行排序时会遇到什么问题?是否可以在没有显式转换的情况下聚合不同排序规则的数据?

错误:如果COLLATION不同(例如,一个列是utf8mb4_unicode_ci,另一个是utf8mb4_bin),则在尝试进行UNION或直接比较时,会抛出COLLATION不兼容的错误。

正确做法:始终通过COLLATE语法将字符串转换为统一的COLLATION。

SELECT name COLLATE 'utf8mb4_unicode_ci' FROM customers UNION SELECT name COLLATE 'utf8mb4_unicode_ci' FROM suppliers;

由于对主题细节的无知导致的实际错误示例


故事1

在一个大型电子商务平台上,在将俄语客户列表导出为Excel时,发现以'Ё'开头的用户显示在列表的最后,'Е'开头的用户则在最前面。原因是COLLATION的不同——使用了标准的拉丁字母,而非俄语的,排序未能符合惯常的字母顺序。用户对不明显的排序表示不满。


故事2

在医疗系统中,不同表格包含具有不同COLLATION(默认为和明确指定的俄语)的字符串字段。更改表格方案后,汇总报告停止工作,查询开始返回"COLLATION conflict"。技术支持不得不在数百个查询中显式指定COLLATE。


故事3

用于按姓氏搜索的API只对大小写字母的精确拼写有效(区分大小写),尽管用户期望不区分大小写。结果发现,列是以COLLATION _CS创建的,这使得搜索对大小写敏感。更改为_CI(不区分大小写)后,问题得以解决。