首页 > 解决方案 > MySQL create table 语句包含每个 char、varchar 和 text 列的冗余排序规则声明是否正常?

问题描述

运行时SHOW CREATE TABLE `my_table`;,我注意到表格COLLATE utf8mb4_unicode_ci中的每个charvarchartext列都显示了 。这似乎有点多余,因为排序规则已经在 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 中都很明显,因此很可能在其他版本中也是如此。

这种行为是正常且可接受的,还是表、数据库或 MySQL 实例配置错误的症状?

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

标签: mysqldatabase-designcollation

解决方案


你只触及了冰山一角。

  • 我认为表上的设置只是没有字符集或排序规则定义的列的默认值。
  • 同上ALTER TABLE ADD COLUMN-- 将从表默认值继承。
  • 我认为列设置已放入information_schema.COLUMNS表中,并且不会随ALTER TABLE .. MODIFY COLUMN ..

类似地,字符集和排序规则继承自数据库定义,并在定义表时被冻结。

关于默认值:

  • 旧的默认字符集是latin1
  • 当前默认值为utf8mb4; 这在未来不太可能改变。
  • 每个排序规则仅适用于一个字符集,并且字符集名称是排序规则名称的开头。
  • 每个字符集都有一个“默认”排序规则: latin1_swedish_ci, utf8_unicode_ci,utf8mb4_0900_ai_ci等。
  • 该默认排序规则(对于给定的字符集)很少(如果有的话)改变。也许唯一的变化是 utf8mb4 在 5.7 和 8.0 之间?

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

最佳实践:始终为每个字符串列显式设置CHARSET和。COLLATE

次要考虑:

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

推荐阅读