1. 项目概述:为什么MySQL Workbench和命令行里中文总变问号、乱码或空格?
“MySQL Workbench 和mysql command之中的中文显示???解决!”——这个标题背后,藏着成千上万开发者、DBA、数据分析初学者在日常工作中反复踩坑的真实痛感。不是不会建库建表,不是写不出SQL,而是刚插入一条带中文的记录,SELECT出来一看:????、æç¨æ·、``,或者干脆字段值全为空;更尴尬的是,Workbench里看着好好的中文,一用命令行mysql -u root -p连进去,SHOW CREATE TABLE出来的建表语句里中文注释全没了,DESCRIBE字段名也变成乱码……这种“数据明明存进去了,却看不见”的错觉,比报错还折磨人。
我带过不少刚接触数据库的学员,90%以上都在前两周被这个问题卡住超过3小时。有人重装Workbench,有人换终端字体,有人改系统区域设置,甚至有人怀疑自己键盘坏了——其实问题根本不在输入端,而在于字符集(Character Set)与排序规则(Collation)在客户端、连接层、服务端、表结构四个层级之间没有形成闭环一致。这就像四个人用不同方言开会:服务端说粤语(utf8mb4),Workbench客户端说闽南语(latin1),命令行客户端说四川话(gbk),中间连接协议又没配翻译官(character_set_client/connection/results),结果谁都听不懂谁。
核心关键词就三个:MySQL Workbench、mysql命令行、中文显示。它们分别代表两类最常用交互入口——图形化GUI工具和原生命令行终端。而“显示异常”本质是编码链路断裂,不是功能缺陷,也不是Bug,而是MySQL默认配置对中文支持极不友好(尤其5.7及更早版本)。本文不讲抽象理论,只聚焦实操:从你双击打开Workbench那一刻起,到你在终端敲下mysql -u root -p回车之后,每一步该看哪里、改什么、验证什么,全部拆解到像素级。适合所有角色:刚学SQL的小白、转岗做数据运维的测试工程师、需要快速交付报表的BI分析师,以及被业务方追问“为啥导出Excel中文是方块”的后端开发。
2. 字符集链路深度拆解:四个层级如何协同,又为何常断链?
要真正解决问题,必须把MySQL的字符集流转机制刻进DNA。它不是单点配置,而是一条贯穿客户端→连接→服务端→存储的完整流水线。任何一个环节掉队,中文就会在半路“失联”。我们按实际数据流向,逐层拆解:
2.1 客户端层(Client Layer):你看到的“界面”决定第一印象
这是用户最直接感知的层级。Workbench和命令行mysql都是客户端程序,它们各自独立维护一套字符集设置,且互不影响。
MySQL Workbench:作为Java/Swing应用,其字符集行为由两部分控制:
(1)GUI界面渲染层:依赖操作系统字体+JVM默认编码。例如Windows默认GBK,macOS默认UTF-8,Linux终端常为UTF-8。若系统字体不支持中文(如某些精简版Linux未安装文泉驿微米黑),即使数据正确,界面上也会显示方块。
(2)MySQL连接会话层:Workbench在建立连接时,会向服务端发送SET NAMES utf8mb4指令(可配置),但该指令是否生效,取决于服务端是否允许及客户端自身是否执行成功。很多用户没注意到Workbench右下角状态栏有个小齿轮图标,点击后能看到当前连接的实际character_set_client、character_set_results值——这才是真实生效的客户端编码。mysql命令行客户端:行为更“原始”,完全依赖启动参数和环境变量。它不读取系统区域设置,而是优先检查:
(1)启动时显式指定的--default-character-set=utf8mb4参数;
(2)配置文件my.cnf中[mysql]段落的default-character-set;
(3)环境变量MYSQL_CHARSET(极少用);
(4)最后才 fallback 到编译时的默认值(老版本常为latin1)。提示:很多人以为
export LANG=zh_CN.UTF-8就能解决命令行中文问题,这是典型误区。LANG只影响shell提示符、错误信息等系统级文本,完全不参与MySQL协议的数据编码转换。MySQL命令行客户端有自己的编码体系,与系统locale无关。
2.2 连接层(Connection Layer):协议握手决定“翻译标准”
当客户端发起TCP连接,服务端响应时,双方会进行一次“字符集协商”。这个过程在MySQL协议中称为Handshake Initialization Packet。关键字段是character_set_client、collation_connection、character_set_results,它们共同构成本次连接的“会话级字符集三件套”。
character_set_client:服务端认为客户端发送过来的SQL语句是用什么编码写的。比如你用Workbench执行INSERT INTO user(name) VALUES('张三'),服务端必须知道这串字节是UTF-8还是GBK,才能正确解码成Unicode字符再存入。collation_connection:影响字符串比较、排序时的规则,比如utf8mb4_unicode_ci和utf8mb4_bin对大小写、重音符号的处理完全不同。character_set_results:服务端返回查询结果(字段名、字段值、警告信息)时,用什么编码打包发给客户端。如果这里设成latin1,哪怕数据本身是UTF-8存的,返回给Workbench的也是乱码字节流。
这三个变量在连接建立后可通过SET NAMES utf8mb4一键同步设置(等价于SET character_set_client = utf8mb4, character_set_results = utf8mb4, collation_connection = utf8mb4_unicode_ci)。但注意:SET NAMES只对当前会话有效,关闭连接即失效。
2.3 服务端层(Server Layer):全局默认值是“兜底保险”
MySQL服务端启动时,会从配置文件(my.cnf或my.ini)加载全局字符集参数。最关键的两个是:
character_set_server:新创建数据库的默认字符集。如果你执行CREATE DATABASE test;没指定CHARACTER SET,就用这个值。collation_server:对应默认排序规则。
这两个参数不直接影响现有连接的行为,只作为“默认模板”存在。很多教程让你改character_set_server=utf8mb4,却忽略了:即使服务端设成utf8mb4,如果客户端连接时声明自己用latin1,服务端依然会按latin1去解码——因为连接层的character_set_client优先级高于服务端全局设置。
注意:MySQL 8.0+已将默认
character_set_server改为utf8mb4,但大量生产环境仍在用5.7,其默认值仍是latin1。这就是为什么新装8.0基本不乱码,而升级5.7到8.0后反而出现乱码——旧配置文件里的latin1残留还在起作用。
2.4 存储层(Storage Layer):表与列的字符集才是“最终归宿”
数据真正落盘时,编码由列定义(Column Definition)决定,而非数据库或表级别。这是最容易被忽略的致命点。
- 创建表时若未显式指定
CHARACTER SET,则继承自数据库默认字符集(即character_set_server); - 但即使数据库是
utf8mb4,如果某列定义为VARCHAR(100) CHARACTER SET latin1,那这一列永远只能存latin1字符,存中文必然失败或截断; - 更隐蔽的是:
TEXT/TINYTEXT/MEDIUMTEXT/LONGTEXT类型,其字符集必须与所在列的字符集一致,不能单独设置。
验证方法极其简单:执行SHOW CREATE TABLE your_table\G,重点看CREATE TABLE语句末尾的ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci,以及每个VARCHAR字段后的CHARACTER SET utf8mb4。如果这里出现latin1或空白(即继承了错误的默认值),前面所有配置都白搭。
这四个层级的关系,可以用一个生活化类比理解:
假设你要寄一封中文信(数据)。
- 客户端层是你写字的纸和笔(Workbench界面或命令行终端);
- 连接层是邮局收件时贴的“收件语言标签”(
SET NAMES);- 服务端层是邮局总部规定的“全国通用信纸标准”(
character_set_server);- 存储层是收件人家里书桌抽屉里专门放中文信的格子(列定义的
CHARACTER SET)。
如果你用英文信纸(latin1)写中文,邮局标签却写“中文信”(utf8mb4),总部标准是中文信纸,但收件人抽屉里只有英文格子——信肯定被退回或撕碎。
3. 实操全流程:从诊断到修复,每一步都附验证命令与现场截图逻辑
现在进入硬核实操环节。我会以零预设环境为前提(即你刚装好MySQL,尚未做任何字符集配置),手把手带你走完诊断→定位→修复→验证的完整闭环。所有命令均可直接复制粘贴,所有验证点都给出预期输出,避免“你以为修好了,其实只是掩盖了问题”。
3.1 第一步:快速诊断——三秒定位问题出在哪一层
别急着改配置,先用三条命令精准“CT扫描”当前环境。打开你的命令行终端(非Workbench),执行:
# 1. 查看当前连接的会话级字符集(最关键!) mysql -u root -p -e "SELECT @@character_set_client, @@character_set_connection, @@character_set_results;" # 2. 查看服务端全局默认值 mysql -u root -p -e "SELECT @@character_set_server, @@collation_server;" # 3. 查看某个具体表的列定义(替换your_db.your_table) mysql -u root -p -e "SHOW CREATE TABLE your_db.your_table\G"预期正常输出应类似:
@@character_set_client, @@character_set_connection, @@character_set_results utf8mb4, utf8mb4, utf8mb4 @@character_set_server, @@collation_server utf8mb4, utf8mb4_0900_ai_ci Table: your_table Create Table: CREATE TABLE `your_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci如果任意一项出现latin1、utf8(注意不是utf8mb4)、?或空白,就找到了病灶。
常见异常组合及对应层级:
@@character_set_client=latin1→ 客户端层或连接层问题;@@character_set_server=latin1→ 服务端配置文件未更新;SHOW CREATE TABLE中列无CHARACTER SET utf8mb4→ 存储层定义错误,需重建表或修改列。
实操心得:我曾帮某公司排查一个线上故障,
SELECT @@character_set_client显示utf8mb4,但SELECT name FROM user仍显示????。最后发现是应用代码里执行了SET NAMES latin1,覆盖了Workbench的默认设置。所以永远以SELECT @@xxx的实时查询结果为准,不要相信配置文件或UI界面的“看起来正常”。
3.2 第二步:Workbench专项修复——不只是改配置,更要绕过GUI陷阱
Workbench的字符集问题有两大顽疾:一是新连接默认不启用utf8mb4,二是其内部缓存可能导致配置修改后不立即生效。修复分三步:
3.2.1 永久修改连接模板(一劳永逸)
- 打开Workbench → 左上角
Database→Manage Connections...; - 选中你的目标连接 → 点击
Edit; - 切换到
Advanced选项卡; - 在
Others文本框中,追加一行:
(注意:不是charset=utf8mb4default-character-set=utf8mb4,Workbench只认charset=); - 点击
Test Connection确认能连上,再点OK保存。
为什么是
charset=utf8mb4?因为Workbench底层使用MySQL C Connector,该参数会直接传递给mysql_real_connect()函数的mysql->charset字段,强制覆盖客户端声明。这是最底层、最可靠的设置方式。
3.2.2 清除GUI缓存(解决“改了配置没反应”)
Workbench会缓存连接元数据,包括字符集信息。即使你改了配置,旧连接可能仍用缓存值。必须:
- 关闭所有Workbench窗口;
- 删除缓存目录:
- Windows:
%APPDATA%\MySQL\Workbench\cache\下所有.xml文件; - macOS:
~/Library/Application Support/MySQL/Workbench/cache/; - Linux:
~/.mysql/workbench/cache/;
- Windows:
- 重启Workbench,新建连接测试。
3.2.3 验证Workbench是否真生效
不要只看SELECT结果,要查底层会话变量:
- 连接成功后,新建SQL Tab;
- 执行:
SELECT @@character_set_client AS client_charset, @@character_set_connection AS connection_charset, @@character_set_results AS results_charset, @@collation_connection AS collation; - 正确结果必须全为
utf8mb4相关值(如utf8mb4_0900_ai_ci)。 - 再执行插入测试:
如果CREATE DATABASE IF NOT EXISTS test_charset DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; USE test_charset; CREATE TABLE t1 (id INT, name VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (1, '中文测试'); SELECT * FROM t1;SELECT显示中文测试,说明Workbench链路已通。
3.3 第三步:mysql命令行终极修复——告别临时SET,实现永久生效
命令行的问题根源在于:每次启动都是“裸连”,不读取任何配置。必须让mysql客户端启动即加载正确字符集。
3.3.1 方法一:修改全局配置文件(推荐,一劳永逸)
找到MySQL客户端配置文件:
- Linux/macOS:
/etc/my.cnf或~/.my.cnf(用户级,优先级更高); - Windows:
C:\ProgramData\MySQL\MySQL Server X.X\my.ini或C:\Users\用户名\my.ini;
在文件末尾添加(若无[mysql]段落则新建):
[mysql] default-character-set = utf8mb4为什么是
default-character-set而不是charset?因为mysql命令行客户端只识别default-character-set参数。charset=是Workbench专用,mysql不认识。
3.3.2 方法二:启动时显式指定(应急,无需改配置)
如果无法修改配置文件(如共享服务器),每次连接时加参数:
mysql -u root -p --default-character-set=utf8mb43.3.3 验证命令行是否生效
同样执行会话变量查询:
mysql -u root -p --default-character-set=utf8mb4 -e "SELECT @@character_set_client, @@character_set_results;"输出必须为utf8mb4。再执行插入测试,确保SELECT结果正常。
注意:
--default-character-set=utf8mb4必须放在-u和-p之后,否则会被当作用户名解析。这是新手最高频的拼写错误。
3.4 第四步:服务端与存储层加固——防止新表再掉坑
即使客户端和连接层都设对了,如果服务端默认值还是latin1,新创建的数据库、表、列依然会继承错误编码。必须彻底清理。
3.4.1 修改服务端配置文件
编辑my.cnf(Linux/macOS)或my.ini(Windows),在[mysqld]段落下添加:
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_0900_ai_ci为什么选
utf8mb4_0900_ai_ci?这是MySQL 8.0+默认排序规则,支持emoji、生僻汉字、大小写不敏感、重音不敏感(ai=accent insensitive)。utf8mb4_unicode_ci在旧版本中更常见,但0900_ai_ci排序更准,性能更好。
3.4.2 重启MySQL服务(必须!)
配置文件修改后,必须重启MySQL服务,否则character_set_server不会更新:
# Linux sudo systemctl restart mysqld # macOS (Homebrew) brew services restart mysql # Windows net stop MySQL && net start MySQL3.4.3 修复现有表的字符集(数据迁移核心步骤)
这是最危险也最关键的一步。如果已有表用了latin1,直接ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4可能因数据损坏导致不可逆丢失。必须分三步走:
第一步:备份!备份!备份!
mysqldump -u root -p --databases your_db > your_db_backup.sql第二步:检查现有数据是否已损坏
执行:
SELECT HEX(name) AS hex_name, name AS raw_name FROM your_table WHERE name REGEXP '[^\x00-\x7F]';- 如果
hex_name显示C3A4C2B8C2A1(这是UTF-8编码的“张”字),说明数据本身是UTF-8存的,只是显示层错了; - 如果
hex_name显示E5BCA0(这是GBK编码的“张”字),说明数据是GBK存的,需按GBK修复; - 如果
hex_name全是3F3F3F(即?的十六进制),说明数据已损坏,只能从备份恢复。
第三步:安全转换(以UTF-8存、latin1声明的场景为例)
这是最常见情况:数据是UTF-8字节,但列定义为latin1,导致服务端错误解码。修复命令:
-- 1. 先将列声明改为BLOB(绕过字符集校验) ALTER TABLE your_table MODIFY name BLOB; -- 2. 再将BLOB按UTF-8重新解释为字符串 ALTER TABLE your_table MODIFY name VARCHAR(100) CHARACTER SET utf8mb4;原理:BLOB类型不涉及字符集转换,只是原样存储字节。第二步MODIFY ... CHARACTER SET utf8mb4告诉MySQL:“这些字节本来就是UTF-8,请按UTF-8解读”。这样就避免了CONVERT TO的双重解码风险。
实操心得:我在某电商项目迁移时,遇到一张千万级订单表,
CONVERT TO跑了2小时还卡住。改用BLOB中转法,15分钟完成,且零数据丢失。关键点在于:永远先用HEX()确认数据原始编码,再选择转换路径。
4. 常见问题与排查技巧实录:那些官方文档不会写的血泪经验
以下是我过去十年处理过的高频问题,按发生频率排序,每个都附真实场景、错误现象、根因分析和独家解决方案。这些内容在MySQL官方手册里找不到,却是实战中最容易卡住你的地方。
4.1 问题1:Workbench里中文正常,命令行SELECT显示????,但INSERT中文又成功
现象描述:
- Workbench执行
INSERT INTO t1 VALUES (1, '你好')→ 成功; - Workbench执行
SELECT * FROM t1→ 显示你好; - 命令行执行
mysql -u root -p -e "SELECT * FROM t1;"→ 显示????; - 命令行执行
INSERT也成功,但SELECT还是????。
根因分析:
Workbench连接时自动执行了SET NAMES utf8mb4,而命令行客户端启动时character_set_results仍是latin1,导致服务端用latin1编码返回结果,命令行按latin1解码失败。但INSERT之所以成功,是因为character_set_client在命令行里可能也是utf8mb4(由配置文件设定),所以服务端能正确解码插入。
独家解决方案:
在命令行配置文件~/.my.cnf中,不仅加[mysql]段落,还要加[client]段落:
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4[client]段落会影响所有MySQL客户端工具(包括mysql、mysqldump),而[mysql]只影响mysql命令行。两者都设,确保万无一失。
4.2 问题2:SET NAMES utf8mb4后SELECT正常,但一退出重连又变乱码
现象描述:
在命令行执行SET NAMES utf8mb4,立刻SELECT显示正常;但关闭终端再重连,一切回到原点。
根因分析:SET NAMES只对当前会话有效,属于临时设置。用户误以为这是永久方案,却忽略了客户端配置文件的缺失。
避坑技巧:
不要依赖SET NAMES做长期修复!它只适合:
- 临时调试;
- 应用代码中连接池初始化时执行(如Java的
initSql); - 无法修改配置文件的受限环境。
永久方案永远是配置文件[mysql]段落。如果公司安全策略禁止改/etc/my.cnf,就让用户级~/.my.cnf,权限600(chmod 600 ~/.my.cnf),既安全又生效。
4.3 问题3:utf8mb4设对了,但微信昵称、emoji表情仍存不进去,报错Incorrect string value
现象描述:
执行INSERT INTO user(nick) VALUES ('👨💻'),报错:ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x91\xA8\xE2\x80\x8D...' for column 'nick' at row 1
根因分析:
这是utf8mb4的“经典陷阱”。MySQL的utf8(注意不是utf8mb4)只支持最多3字节UTF-8字符(即BMP平面),而emoji、部分生僻汉字需要4字节。utf8mb4虽支持4字节,但必须同时满足三个条件:
- 列定义为
CHARACTER SET utf8mb4; - 排序规则为
utf8mb4_*_ci(如utf8mb4_0900_ai_ci),不能是utf8mb4_general_ci(旧版,不完全支持4字节); - 连接层
character_set_client和character_set_results必须为utf8mb4。
终极修复命令:
-- 修改列,指定现代排序规则 ALTER TABLE user MODIFY nick VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;补充知识:
utf8mb4_0900_ai_ci是MySQL 8.0引入的Unicode 9.0排序规则,全面支持4字节UTF-8。utf8mb4_unicode_ci基于Unicode 4.0,对emoji支持不全。务必用前者。
4.4 问题4:Linux终端里mysql命令行中文显示为方块,但echo "中文"正常
现象描述:
- 终端执行
echo "测试"→ 正常显示; - 执行
mysql -u root -p→ 连接成功,但SELECT中文显示为□□□□; SELECT @@character_set_results显示utf8mb4。
根因分析:
终端本身支持UTF-8,但mysql客户端输出时,将UTF-8字节流直接发给终端,而终端字体缺少对应字形(glyph)。这不是MySQL问题,是字体问题。
实测有效的解决方案:
- Linux(GNOME/KDE):
- 打开终端设置 → 字体 → 选择
Noto Sans CJK SC(谷歌思源黑体)或WenQuanYi Micro Hei(文泉驿微米黑); - 若无这些字体,安装:
sudo apt install fonts-wqy-microhei(Ubuntu)或sudo yum install wqy-microhei-fonts(CentOS)。
- 打开终端设置 → 字体 → 选择
- macOS:
- 终端偏好设置 → 描述文件 → 文本 → 字体 → 选择
PingFang SC或Heiti SC;
- 终端偏好设置 → 描述文件 → 文本 → 字体 → 选择
- Windows(WSL):
- WSL本身无GUI,需在Windows Terminal中设置:设置 → 字体 → 选择
Microsoft YaHei或NSimSun。
- WSL本身无GUI,需在Windows Terminal中设置:设置 → 字体 → 选择
关键区别:
echo调用的是shell的本地输出,而mysql输出是通过MySQL协议传输的字节流,对终端字体要求更高。选对字体,立竿见影。
4.5 问题5:PHP/Python应用连MySQL,中文存取正常,但Workbench里查看是乱码
现象描述:
- PHP代码
$pdo->exec("INSERT INTO t1 VALUES (1, '测试')")→ 成功; - PHP
SELECT→ 显示正常; - 但Workbench连接同一数据库,
SELECT显示æµè¯。
根因分析:
应用代码里显式设置了连接字符集(如PHP的PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"),而Workbench连接时没设,导致同一张表在不同客户端看到不同结果。这是典型的“多客户端环境不一致”。
统一治理方案:
在MySQL服务端配置中,强制所有新连接默认使用utf8mb4:
[mysqld] # 强制新连接的默认字符集 init_connect='SET NAMES utf8mb4' # 跳过对root用户的init_connect(避免root登录失败) skip-character-set-client-handshakeinit_connect会在每个非root用户连接成功后自动执行该SQL,skip-character-set-client-handshake则跳过客户端声明,强制服务端按init_connect设置。这样,无论Workbench、命令行、还是应用,只要连上,就自动SET NAMES utf8mb4。
注意:
init_connect对SUPER权限用户(如root)不生效,这是安全设计。所以root登录时仍需手动SET NAMES,但普通应用账号已全自动。
5. 经验总结与延伸思考:从解决一个问题,到建立字符集防御体系
写到这里,你已经掌握了从诊断到修复的全套技能。但我想分享一个更深层的认知:字符集问题从来不是孤立的技术点,而是一个系统性工程能力的试金石。它逼你去理解协议、客户端、服务端、存储的协作关系,逼你养成“验证优于假设”的习惯,逼你在改配置前先备份,在执行ALTER TABLE前先HEX()探查。
我自己在带团队时,会把字符集配置作为新人入职的“首考题”。不是考他会不会改my.cnf,而是给他一个乱码环境,让他用SELECT @@xxx定位,用HEX()分析数据,用ALTER TABLE ... MODIFY BLOB安全迁移。能独立完成这套流程的人,通常对MySQL的整体架构已经有了一定直觉。
最后,分享一个我坚持了八年的习惯:所有新项目初始化脚本,第一行必是字符集声明。例如:
-- 初始化数据库脚本 init.sql SET NAMES utf8mb4; CREATE DATABASE IF NOT EXISTS myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; USE myapp; CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;这三行代码,省去了未来三个月排查乱码的时间。技术债不体现在报错里,而体现在那些“为什么明明写了中文却看不到”的深夜疑问中。
如果你正在部署一个新系统,现在就打开你的my.cnf,加上那四行配置;如果你正被一个老系统的乱码困扰,就从SELECT HEX()开始,一步步逆向追踪。字符集没有魔法,只有清晰的链路和扎实的验证。当你能说出character_set_client和character_set_results的区别时,你就已经超越了90%的同行。