滚动新闻 →
密西西比州参议员科洛姆获川普公开肯定 民主党中期选举成果显现 SpaceX星舰第15次试飞突破轨道技术 机械哥斯拉首次亮相 唐元隽因涉嫌为中共搜集美国异议人士信息被纽约法院判缓刑三年 欧洲参与俄乌和谈遭分歧 战俘交换后冲突再升级 美国财长:伊朗黑客利用中国AI攻击法国超市冷藏系统 唐元隽涉非法搜集海外异议人士信息被判缓刑 双黄丑闻蔓延白宫 卢特尼克或因放水被问责 黄仁勋辞任事件引安全担忧 中共渗透手段升级 加拿大政界呼吁彻查中共海外警务据点 清华特等奖学金评选引争议 AI方向占比近全 前CIA局长之子因传播儿童色情制品被起诉 突发:新奥尔良港油轮撞上客船 多人落水 美国联邦航空总署实施全国航班停飞措施 退伍军人事务部长披露福利审批通过率高达94% 黄仁勋被美众议院三大委员会要求出席闭门听证会 法国10月通胀率突破3.7% 创近3年新高 山西男子砍伤妻岳母未被批捕 释放后勒死妻子引争议 黄仁勋辞职引台湾日本政界高度关注 唐元隽因向中共提供情报获三年缓刑 欧几里得望远镜发布首批观测数据 助力探索暗宇宙之谜 内蒙古化工厂氨气泄漏事件引争议,官方称属无毒催泪弹演练 英伟达共谍风暴升级 高阶芯片流向成焦点 西安村民因欠款问题冲击政务中心 无锡超算中心遭黑客入侵数据遭出售 网民质疑掩盖真相 Anthropic IPO超额认购六倍 加拿大各界在老兵纪念日缅怀阵亡将士并致敬军人 习近平称继承孙中山理念 学者质疑历史背离 孙中山纪念大会异常引关注 习健康状况引猜测 中国AI模型被指用于伊朗网络攻击 法国超市遭大规模破坏 雕刻大师现场展示技艺 纽约跨年水晶球亮相时代广场 Google Distributed Cloud 是什么,无法全部迁移到公有云的企业可以怎样部署 新疆库车市发生5.0级地震 乌鲁木齐民众普遍感知明显 美以海军高层会谈 土耳其卡塔尔签署防御协议 涉嫌为中共搜集情报 唐元隽纽约获三年缓刑 上海交大基因编辑实验致女童死亡 处罚仅限开除引争议 民主党参议院领袖选举引争议 范霍伦挑战舒默权威 江苏句容城管强抢餐车引摊贩冲突 中共借孙中山纪念进行统战操作 学者质疑继承论述模糊 黄乐与华为关联引调查 深圳数据中心牵出供应链疑云 京沪高铁山东段故障引争议 施工挖断电缆遭质疑

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

发布时间: 2026-10-21 23:24:01    最后更新: 2026-11-13 15:20:54    阅读:82  约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 中文乱码问题就不再是一个只能靠反复试错解决的问题,而会变成一个可以沿着数据链路逐段定位的工程问题。
本文作者
程越(Kevin Cheng)
IT与人工智能技术资深编辑

喜欢这篇报道?

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

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

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