滚动新闻 →
笔记本充电口松动导致断充,接口损坏时应该如何确认 台风助长下 苗县公馆育苗场仓库火警浓烟蔽天 Windows 11 UAC 用户账户控制怎么设置?安全和便利应该怎样平衡 号称重返20岁 “尸皮针”原料来自逝者 38岁女被捕 MySQL 字符集怎么设置?中文网站避免乱码必须掌握的基础知识 从《岳阳楼记》看古代文人的责任意识 美军台海冲突应对方案:首日即启动全域作战部署 法国骚乱中抢夺iPhone遭反噬 暴徒意外发现手机成追踪定位器 花生在中国传统饮食中的历史 初学者如何选择第一本字帖 台湾艺人遭跨境暴力威胁 矢板明夫怒斥中共输出威权恐惧 希腊雅典市中心建筑爆炸致4人受伤 霍尔木兹海峡关闭致巴拿马运河货运量创新高 孩子总想争第一怎么办 台风蔷琵路径西调 台湾或于今午发布陆警 视频拍摄时存储卡应该如何选择 元朝为什么能够迅速建立横跨欧亚的帝国 PHP核心漏洞引发全球网络安全警报 七成网站面临风险 台湾相声演员因讽刺习遭跨境追杀 旧房家具太多应该如何重新布局 马斯克推动SpaceX与特斯拉合并计划 厄尔尼诺现象或创历史最强纪录 全球极端天气频发引警报 爱马仕柏金包热潮消退 二手市场价格回落 中共公安密件曝光 18种阴招打压“重点人” 包子为什么会遍布中国各地 美国退休教师史蒂芬·哈伯德结束四载俄方羁押返美 三峡工程能回本吗? 迎转机?普京同意三方谈判 泽连斯基愿冻结战线 川普在北卡州宣布半导体产业投资计划 坐在湖边看夕阳,加拿大基洛纳的葡萄园把秋天酿成了酒 苏丹无人机袭击阿卜耶伊市场 致153人遇难 俄罗斯苏-30SM战机坠毁 机组人员成功弹射逃生 美国五角大楼扩大制裁名单 新增65家涉华企业 纽约华人长者揭露:老人中心与药局回扣成灰色交易 台加联合研讨跨境洗钱应对策略 强调执法协作必要性 车辆防盗系统锁死后应该如何处理 前调查记者实名举报中国天眼牟利遭政法委调查 宜信暴雷事件引争议 离职顾问被追缴百万佣金 尊界杯托不密封 一杯咖啡漏进车身 纽约成人日托机构涉福利欺诈案引调查

MySQL 字符集怎么设置?中文网站避免乱码必须掌握的基础知识

发布时间: 2026-10-21 23:24:01    最后更新: 2026-10-22 00:22:01    阅读:5  约12 分钟阅读     

MySQL 字符集怎么设置?中文网站避免乱码必须掌握的基础知识
图片说明:示意图   图片来源:Public Domain(公有领域)
MySQL 中文网站出现乱码,通常不是单纯因为数据库“没有设置 UTF-8”,而是数据存储、数据库默认字符集、表和列定义、客户端连接以及网页输出之间存在不一致。真正稳定的做法,是把这些环节分别确认,而不是看到乱码后盲目执行一条转换命令。

字符集(Character Set)决定数据能够使用什么编码方式保存和传输;校对规则(Collation)则决定字符串如何比较、排序以及是否区分大小写、重音等。MySQL 对字符集和校对规则采用多层默认机制,包括服务器、数据库、表和列四个层级,同时还有一个经常被忽略的连接层。

对于现代中文网站,通常应优先考虑 utf8mb4。MySQL 所谓的 utf8 实际上对应旧的三字节 UTF-8 实现,不能完整覆盖 Unicode 的四字节字符;utf8mb4 才能够覆盖完整的 Unicode 范围。因此,包含中文、Emoji、部分特殊符号以及其他扩展字符的网站,没有继续使用 MySQL utf8 的必要。MySQL 从5.5系列开始提供 utf8mb4 支持。

如果希望服务器默认使用 utf8mb4,可以在 MySQL 配置文件中设置:

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_0900_ai_ci

不过,这个校对规则并不是所有 MySQL 版本都存在。utf8mb4_0900_ai_ci 是 MySQL 8.0 引入的新一代 Unicode 校对规则,MySQL 8.0 默认服务器字符集就是 utf8mb4,默认校对规则为 utf8mb4_0900_ai_ci。如果运行的是较老版本,就应该根据该版本实际支持的校对规则进行选择。

创建数据库时,也可以明确指定字符集和校对规则:

CREATE DATABASE mydb
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

数据库级设置主要是默认值。以后在这个数据库中创建表,如果没有另外指定字符集,相关字符列通常会继承数据库默认设置。因此,数据库设置正确以后,新表一般不需要每个字段都重复写一遍字符集。

创建表时可以进一步明确指定:

CREATE TABLE mytable (
id INT PRIMARY KEY,
content TEXT
) DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

如果某个字段需要特殊的字符集或校对规则,也可以在列级指定:

content TEXT
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci

列级定义的优先级高于表级默认值。因此,实际项目中没有必要为了“保险”而给每一个字段都重复指定 utf8mb4。只要数据库、表以及特殊字段的定义清楚即可。

校对规则不能简单理解成“支持中文”和“不支持中文”。例如 utf8mb4_bin 同样可以保存和排序中文,只是比较方式更接近按照字符编码值进行比较;它与 Unicode 语言校对规则得到的排序结果可能不同。因此,“utf8mb4_bin无法进行中文排序”是不准确的。

如果网站主要面向中文内容,选择哪一种 collation,应根据实际搜索、排序和大小写敏感需求决定。utf8mb4_unicode_ci 是较常见的旧版 Unicode 校对规则,而 MySQL 8.0 系列还提供 utf8mb4_0900_ai_ci 以及其他更具体的 Unicode 校对规则。不要把某一个 collation 当成所有网站的唯一标准答案。

数据库设置正确以后,连接字符集仍然非常重要。MySQL 为每一个客户端连接维护 character_set_client、character_set_connection 和 character_set_results 等会话变量。客户端发送 SQL、服务器解释 SQL 以及服务器返回结果时,都涉及连接字符集。

PHP PDO 最简单的做法,是直接在 DSN 中指定:

$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8mb4';

$pdo = new PDO(
$dsn,
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]
);

PDO 官方文档明确提供了 DSN 的 charset 参数,因此如果已经在连接字符串中指定 charset=utf8mb4,通常不需要再额外执行一遍 SET NAMES utf8mb4。

如果使用 MySQLi,则建议直接使用:

mysqli_set_charset($conn, 'utf8mb4');

这比单纯执行:

$conn->query("SET NAMES utf8mb4");

更适合作为 PHP MySQLi 连接初始化方式。PHP 官方文档特别指出,mysqli_set_charset() 会影响连接使用的字符集,而单纯通过 SQL 执行 SET NAMES 并不会改变 mysqli_real_escape_string() 所使用的字符集。

命令行工具也存在连接字符集问题。例如使用 mysqldump 时,可以明确指定:

mysqldump -u user -p --default-character-set=utf8mb4 mydb > dump.sql

恢复时同样要注意导入端的字符集配置。否则即使数据库和表本身全部采用 utf8mb4,数据在导出、传输或者导入过程中仍然可能出现编码转换问题。

排查乱码时,不要只检查 character_set_server。首先查看服务器和当前连接:

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

如果只想检查当前连接,还可以查看:

SHOW SESSION VARIABLES LIKE 'character_set_%';
SHOW SESSION VARIABLES LIKE 'collation_%';

MySQL 官方建议通过连接会话变量检查客户端和服务器之间实际使用的字符集。

然后检查数据库:

SELECT
SCHEMA_NAME,
DEFAULT_CHARACTER_SET_NAME,
DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'mydb';

检查表结构:

SHOW CREATE TABLE mytable;

检查具体字段:

SELECT
COLUMN_NAME,
CHARACTER_SET_NAME,
COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'mydb'
AND TABLE_NAME = 'mytable';

这一步比单纯检查服务器默认字符集更重要,因为一个已经存在的旧表完全可能继续使用 latin1 或 MySQL utf8mb3,即使服务器现在已经改成 utf8mb4。

对于新建网站,建议从数据库、表到应用连接统一规划。例如:

CREATE DATABASE mydb
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;

然后:

CREATE TABLE articles (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content LONGTEXT NOT NULL,
PRIMARY KEY (id)
) CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;

PHP连接:

$pdo = new PDO(
'mysql:host=localhost;dbname=mydb;charset=utf8mb4',
$username,
$password
);

网页输出则明确声明:

header('Content-Type: text/html; charset=UTF-8');

这里需要特别区分两个概念:MySQL 中的字符集名称通常写成 utf8mb4,HTTP 和 HTML 中则通常写成 UTF-8。它们属于不同层面的表示方式,并不矛盾。

如果旧网站已经存在乱码,最不能做的事情就是看到乱码以后立即执行:

ALTER TABLE mytable
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

这个语句适合在原有数据编码正确、只是列或表字符集需要转换的情况下使用。它并不是“乱码修复按钮”。MySQL 官方明确说明,字符集转换要求非二进制字符串列中的内容本身应该按照原字符集正确编码。如果数据库中已经混入错误解释后的数据,直接转换可能无法恢复原始文字。

例如数据库中原本应该是“中文”,却已经显示成 中文,首先应该判断这是 UTF-8 字节被错误地按照另一种字符集解释,还是数据在写入时已经真正损坏。两种情况的处理方法完全不同。

因此,修复旧数据库前应该先备份数据库,再抽取少量问题数据进行测试,确认原始字节、字段字符集、连接字符集以及导入导出过程以后,再决定是否执行 ALTER TABLE ... CONVERT TO CHARACTER SET。字符集转换涉及表结构和数据重建,实际操作还需要考虑索引长度、表规模、锁和业务停机窗口。MySQL 文档也指出,字符集转换可能导致表重建。

还有一个常见误区,是认为“只要数据库使用 utf8mb4,中文网站就不会乱码”。实际上,一个完整的网站至少存在浏览器、HTML/HTTP、PHP字符串、数据库连接、MySQL字段、导入导出工具等多个编码边界。任何一个边界出现不一致,都可能产生乱码。

因此,真正可靠的配置原则不是简单地把所有地方机械地改成一个字符串,而是确认每一个数据传递环节使用了正确且一致的字符编码。对于现代 MySQL 中文网站,utf8mb4 通常是合理的基础选择;校对规则根据 MySQL 版本和业务排序需求选择;应用连接明确指定字符集;旧数据转换前先确认实际编码状态。

只要把“存储字符集”“连接字符集”“校对规则”和“网页输出编码”分开检查,MySQL 中文乱码问题就不再是一个只能靠反复试错解决的问题,而会变成一个可以沿着数据链路逐段定位的工程问题。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP