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

来源:这里教程网 时间:2026-02-28 20:45:06 作者:

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

是的,默认不是。MySQL 5.7 默认

character_set_server
latin1
collation_server
latin1_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)全链路对齐才稳。

相关推荐