1. 背景
utf8mb3 字符集, 对于 繁体、少数民族文字、Emoji 等支持较差。新业务应当优先使用 utf8mb4 字符集。
对于已经使用 utf8mb3 的数据库,可以通过下面的方式进行转换。下面记录了转换方法以及可能遇到的问题。
2. 技术方案
数据备份 | 为了避免可能得数据丢失,进行变更前的数据备份是
表字段字符集变更
有下面 2 种方案,可以根据自身情况评估。
方案 | 全表变更 | 按字段变更 |
---|---|---|
SQL | ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ALTER TABLE tbl_name CHANGE c_name c_name VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; |
优点 | 1. 快速、便捷(不需要关心原始字段定义,不容易写错 SQL) 2. 安全(不容易写错 SQL) 3. 一步到位,避免后续持续有字段需要变更 | 1. 影响范围较小 |
缺点 | 1. 变更范围较大,对于有 join 操作的字段,需要所有表均变更 2. 执行时间较长 | 1. SQL 容易写错,需要仔细核对(原始的 字段类型、长度、注释、非空、默认值等需要跟原来写的一致) |
最佳实践 | 建议数据库所有表全部一起变更,避免出现 join 、比较失败 |
3. 风险须知
- 变更过程中会锁表,应该避免业务流量高峰时段。
- 对于需要进行比较的字符类型字段,如果字符集、排序方式不一致,可能导致无法比较、无法 join、不走索引等情况。因此对于需要比较(=、 >、 <)、join、concat 的字段,需要保证他们的类型和排序方式一致
- varchar 字段在变更之后超过长度,需要提前进行"扩容"
4. 相关 SQL 、脚本
- 当前编码查看
-- 查看数据库编码
SHOW CREATE DATABASE db_name;
-- 查看表编码
SHOW CREATE TABLE tbl_name;
-- 查看字段编码
SHOW FULL COLUMNS FROM tbl_name;
-- 查看系统编码
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
-- 查看数据库表大小 (评估变更时间)
SELECT TABLE_SCHEMA, TABLE_NAME,
sum(DATA_LENGTH) / (1024 * 1024 * 1024) AS DATA_LENGTH_GB
FROM information_schema.tables
group by TABLE_SCHEMA, TABLE_NAME order by 3 desc;
- 生成当前数据库下所有的转换表 SQL
SELECT concat("ALTER TABLE `", TABLE_NAME ,"` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as s from information_schema.TABLES WHERE TABLE_SCHEMA="customer"