什么是低级别的整理?

What is collation at a low level?

假设我有两个 tables:

CREATE TABLE `table_1` (
  `field` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `table_2` (
  `field` varchar(20) COLLATE utf8_unicode_520_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_520_ci;

table 除了它们的字段排序规则之外是相同的。第一个 table 使用(默认)utf_general_ci,第二个 table 使用 utf8_unicode_520_c1.

并且我已将值 abcdé 插入到两个 table 中。我会假设(可能不正确)这两个字符都将以二进制值存储:61 62 63 C3A9。并且 tables return 这样做的结果是:

select field, hex(field) from table_1;
# abcé  616263C3A9

select field, hex(field) from table_2;
# abcé  616263C3A9

# Both return the same result

这是否意味着该值存储为该二进制值,或者关于如何存储 utf-8 字符串还有更多内容?现在,当我尝试执行 UNIONJOIN 时,由于排序规则的混合,它不允许我这样做:

select field, hex(field) from table_1 union
select field, hex(field) from table_2;

Illegal mix of collations for operation 'UNION'

为什么会出现这种情况,回到我最初的问题:lower/storage 级别的排序规则是什么意思?我认为它只是用于 'sort'(即,不是在存储级别,而是在 query/algorithmic 级别)。

您对整理对 JOINUNION 的影响感兴趣吗?

首先回顾charset/collation... C3A9是编码,由utf8或utf8mb4的CHARACTER SET表示。 COLLATION 说明是 é > e 还是 é < e 或 é = e。或者任何其他字符。它是一种算法,而不是编码。在英语中,排序规则说明是否 A = a(区分大小写)。

对于JOIN...

FROM a
JOIN b  ON a.x = b.x

优化器需要两个 table 中的 x 具有相同的字符集和排序规则。这样,INDEX(x) 可用于有效地执行 JOIN..ON.

对于UNION DISTINCT ...

需要比较DISTINCTifying中涉及的列。使用索引进行比较是有效的。如果没有相同的排序规则,可能会出现做什么的定义问题。

对于UNION ALL ...

结果是带有列的“table”。这些列的数据类型 包括排序规则 。简单的方法是要求所有排序规则都相同。更复杂的是即时转换。

手册(在 UNION 上)说(不准确)“例如,第一个语句选择的第一列应该与其他语句选择的第一列具有相同的类型。如果数据类型相应的 SELECT 列不匹配,UNION 结果中列的类型和长度考虑了所有 SELECT 语句检索的值。"