MySQL create table 语句包含每个 char、varchar 和文本列的冗余排序规则声明是否正常?

Is it normal for a MySQL create table statement to include redundant collation declarations for every char, varchar, and text column?

当 运行 SHOW CREATE TABLE `my_table`; 时,我注意到 COLLATE utf8mb4_unicode_ci 显示在每个 charvarchartext 列中table。这似乎有点多余,因为排序规则已经在 create 语句的 table_option 部分中声明。

mysql> SHOW CREATE TABLE `my_table`;
| Table    | Create Table
| my_table | CREATE TABLE `my_table` (
...
  `char_col_1` char(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `varchar_col_1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `varchar_col_2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `varchar_col_3` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `text_col_1` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
...
) ENGINE=InnoDB AUTO_INCREMENT=1816178 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

此行为在 MySQL 5.7 和 MySQL 8.0 中都很明显,因此在其他版本中也很可能存在。

此行为是否正常并接受table,或者它是否是 table、数据库或 MySQL 实例配置错误的症状?

另一方面,由于可以为任何特定列单独设置排序规则,也许最好明确显示每个列的排序规则以避免任何歧义或假设,即使在列排序规则匹配的情况下table?

的排序规则

是的,CHARACTER SETCOLLATION 在 table 定义和列定义中相同是多余的。

具有明确的列定义意味着任何人更改 CHARACTER SETCOLLATION 的 table 定义,该列将保持不变。

您所触及的只是冰山一角。

  • 我认为 table 上的设置只是未定义字符集或整理的列的默认值。
  • 同上 ALTER TABLE ADD COLUMN -- 将从 table 默认值继承。
  • 我认为列设置已放入 information_schema.COLUMNS table 并且不会随着 ALTER TABLE .. MODIFY COLUMN ..
  • 而改变

同样,table charset 和 collat​​ion 继承自 database 定义,将被冻结为 table 已定义。

关于默认值:

  • 旧的默认字符集是 latin1
  • 当前默认为utf8mb4;这在未来不太可能改变。
  • 每个归类只适用于一个字符集,字符集名称是归类名称的开头。
  • 每个字符集只有一个 "default" 排序规则:latin1_swedish_ciutf8_unicode_ciutf8mb4_0900_ai_ci
  • 默认排序规则(对于给定的字符集)很少(如果有的话)改变过。也许唯一的变化是 utf8mb4 在 5.7 和 8.0 之间??

(我实验的越多,我对这一切就越不确定。)

最佳做法:始终为每个字符串列显式设置 CHARSETCOLLATE

次要考虑因素:

  • 如果可用,对大多数字符串 (VARCHAR / TEXT) 使用 utf8mb4
  • 使用最新可用的排序规则(Unicode 不断改进它);目前 utf8mb4_0900_ai_ci.
  • 使用 ascii 用于显然只有 ascii 的东西——国家代码、postal_code、十六进制等。大多数情况下这些可以使用 CHAR(..)
  • 使用ascii_general_ciascii_bin,取决于是否需要大小写折叠。