背景

当一个数据库中的表中有不同的字符集、排序规则时,sql联表查询的时候就有可能出错。如:Illegal mix of collations (utf8_bin ,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT)。

这是由于创建表时指定的排序规则不一致导致的,原因可能是创建表的不是同一拨人,或者是有部分表是程序自动创建的,导致不一致的。

查看数据库中的字符集

-- 查看数据库中的字符集
show variables where Variable_name like '%collation%'

数据库中的字符集

查看某个数据库的表的用的字符集

-- 查看某个数据库的表的用的字符集
SELECT TABLE_SCHEMA '数据库',TABLE_NAME '表',TABLE_COLLATION '原排序规则',CONCAT('ALTER TABLE ',TABLE_NAME, ' CHARACTER SET=utf8mb4,  COLLATE=utf8mb4_general_ci;') '修正SQL'
FROM information_schema.`TABLES` where TABLE_SCHEMA = '你的数据库名' and TABLE_COLLATION != 'utf8mb4_general_ci'

表字符修改

查看数据库中所有字段用的排序规则

-- 查看数据库中所有字段用的排序规则
SELECT
	TABLE_SCHEMA '数据库',
	TABLE_NAME '表',
	COLUMN_NAME '字段',
	CHARACTER_SET_NAME '原字符集',
	COLLATION_NAME '原排序规则',
	CONCAT(
	'ALTER TABLE ',
	TABLE_NAME,
	' MODIFY COLUMN ',
	COLUMN_NAME,
	' ',
	COLUMN_TYPE,
	-- - 设置新的编码和排序规则
	' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci',
	( CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END ),
	( CASE WHEN COLUMN_COMMENT = '' THEN ' ' ELSE concat( ' COMMENT''', COLUMN_COMMENT, '''' ) END ),
	';' 
) '修正SQL' 
FROM
	information_schema.`COLUMNS` 
WHERE
	-- -过滤正确排序规则
	COLLATION_NAME != 'utf8mb4_general_ci'
	-- -数据库名称
	AND TABLE_SCHEMA = '你的数据库名';

字段字符集修改

上面的sql可以根据自己的情况,增加where条件筛选需要操作的表。修改sql可以直接批量复制后运行,以防万一执行前请先备份相关数据

修改数据库的字符集及排序规则

ALTER DATABASE `shtp_sunhouse` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';

存储字符集

utf8 是 Mysql 中的一种字符集,只支持最长三个字节的 UTF-8 字符,也就是 Unicode 中的基本多文本平面。
要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以后的才支持。
为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8. 对于 CHAR 类型数据,utf8mb4 会多消耗一些空间,根据 Mysql 官方建议,使用 VARCHAR 替代 CHAR。
一般现在新建数据库都是使用8.0以上的,都使用utf8mb4即可。

排序字符集

utf8mb4_unicode_ci 和 utf8mb4_general_ci
1、准确性

  • utf8mb4_unicode_ci 是基于标准的 Unicode 来排序和比较,能够在各种语言之间精确排序
  • utf8mb4_general_ci 没有实现 Unicode 排序规则,在遇到某些特殊语言或者字符集,排序结果可能不一致。

但是绝大多数情况下,这些特殊字符的顺序并不需要那么精确。

2、性能

  • utf8mb4_general_ci 在比较和排序的时候更快
  • utf8mb4_unicode_ci 在特殊情况下,Unicode 排序规则为了能够处理特殊字符的情况,实现了略微复杂的排序算法。

但是在绝大多数情况下,不会发生此类复杂比较。相比选择哪一种 collation,使用者更应该关心字符集与排序规则在 db 里需要统一

utf8mb4_0900_ai_ci
推荐用 utf8mb4_unicode_ci,但是用 utf8mb4_general_ci 也没啥问题。

MySQL 8.0 默认的是 utf8mb4_0900_ai_ci,属于 utf8mb4_unicode_ci 中的一种,具体含义如下:

  • uft8mb4 表示用 UTF-8 编码方案,每个字符最多占 4 个字节。
  • 0900 指的是 Unicode 校对算法版本。(Unicode 归类算法是用于比较符合 Unicode 标准要求的两个 Unicode 字符串的方法)。
  • ai 指的是口音不敏感。也就是说,排序时 e,è,é,ê 和 ë 之间没有区别。
  • ci 表示不区分大小写。也就是说,排序时 p 和 P 之间没有区别。

默认字符集
utf8mb4 已成为默认字符集,在 MySQL 8.0.1 及更高版本中将 utf8mb4_0900_ai_ci 作为默认排序规则。以前,utf8mb4_general_ci 是默认排序规则。
由于 utf8mb4_0900_ai_ci 排序规则现在是默认排序规则,因此默认情况下新表格可以存储基本多语言平面之外的字符。现在可以默认存储表情符号。
如果需要重音灵敏度和区分大小写,则可以使用 utf8mb4_0900_as_cs 代替。

更多推荐