mysql安装后如何设置字符集和排序规则_mysql编码环境设置

16次阅读

MySQL 5.7+ 默认字符集不是 utf8mb4,而是 latin1;必须在 my.cnf 的 [client]、[mysql]、[mysqld] 三段统一配置 utf8mb4,并显式指定建库建表字符集及应用连接参数,否则仍会导致乱码。

mysql 安装后如何设置字符集和排序规则_mysql 编码环境设置

MySQL 5.7+ 启动时默认字符集不是 utf8mb4?

是的,默认不是。MySQL 5.7 默认 character_set_serverlatin1collation_serverlatin1_swedish_ci,哪怕你建库时指定了 utf8mb4,新创建的数据库、表、列仍可能继承服务端默认值,导致插入 中文乱码、emoji 存不进去、ORDER BY 排序异常等问题。

根本原因在于:MySQL 的字符集生效是分层的(服务器 → 数据库 → 表 → 列),且客户端连接时若未显式指定,会按服务端默认值协商 编码,造成「看起来能存,实际传输过程已损坏」。

  • 检查当前设置:SHOW VARIABLES LIKE 'character_set_%';SHOW VARIABLES LIKE 'collation_%';
  • 临时修改(重启失效):SET GLOBAL character_set_server = 'utf8mb4'; SET GLOBAL collation_server = 'utf8mb4_unicode_ci';
  • 真正生效必须写入 配置文件 并重启 mysqld

my.cnf 中该在哪几个段落写 charset 配置?

必须同时覆盖 [client][mysql][mysqld] 三个段落,缺一不可。只改 [mysqld] 只影响服务端,客户端(如 mysql 命令行、PHP PDO)仍可能用错编码握手。

[client] default-character-set = utf8mb4  [mysql] default-character-set = utf8mb4  [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect = 'SET NAMES utf8mb4' skip-character-set-client-handshake = FALSE
  • init_connect 确保普通用户连接后自动执行 SET NAMES,但对 root 或带 SUPER 权限用户无效(安全限制)
  • skip-character-set-client-handshake = FALSE 强制服务端以配置值响应客户端的编码协商请求(默认为 TRUE,即允许客户端“自说自话”)
  • 注意:MySQL 8.0+ 已废弃 init_connect 对 SUPER 用户的限制,但兼容性起见仍建议保留

建库建表时还要再指定 utf8mb4 吗?

要,而且必须显式指定。即使服务端已设为 utf8mb4,新建数据库若不声明,仍可能继承旧默认值(尤其升级或迁移环境时)。

  • 创建数据库:CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  • 创建数据表:CREATE TABLE t (c VARCHAR(100)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  • 已有表转换:ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(注意:该语句会重建表,大表慎用)
  • 特别注意 VARCHAR 字段长度:utf8mb4 下每个字符最多占 4 字节,InnoDB 单行最大 65535 字节限制下,VARCHAR(255) 实际占用字节数翻倍,极端情况下可能触发 Row size too large 错误

PHP/Python 连接时为什么还是乱码?

因为客户端驱动没传对编码参数,服务端配置只是基础,连接时的「协商」环节才是关键。

  • PHP mysqli:$mysqli = new mysqli($host, $user, $pass, $db); $mysqli->set_charset('utf8mb4'); 或在 DSN 中加 ;charset=utf8mb4
  • PHP PDO:new PDO($dsn, $user, $pass, [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4']);
  • Python PyMySQL:conn = pymysql.connect(……, charset='utf8mb4')
  • Node.js mysql2:{charset: 'utf8mb4'} 选项必须显式传入
  • 错误典型表现:???、插入成功但 SELECT 出来是空格或问号——大概率是连接层编码没对齐

实际部署中最容易漏掉的是客户端配置段落和应用层连接参数,服务端改完以为万事大吉,结果应用一连就出问题。字符集这事,得从 my.cnf、建表语句、连接初始化、甚至 前端 HTTP 头(Content-Type charset)全链路对齐才稳。

text=ZqhQzanResources