如何修复MySQL函数在处理中文字符截取时出现的乱码问题?

胖墨小哥_5696

胖墨小哥_5696

2026-06-25

176人浏览

原创

substring_index在中文字段中返回乱码的根本原因是字符集上下文不匹配:当字段为utf8mb4而会话字符集为latin1或旧utf8时,mysql错误解码字节导致分隔符定位偏移,进而截取乱码。

如何修复mysql函数在处理中文字符截取时出现的乱码问题?

SUBSTRING_INDEX 在中文字段里返回乱码,不是函数本身有 bug,而是它被放在了错误的字符集上下文中运行。


确认当前会话字符集是否匹配 utf8mb4

乱码最常见源头是 character_set_client、character_set_connection 和 character_set_results 三者不一致,且其中至少一个为 latin1 或旧版 utf8(即最多 3 字节的伪 UTF-8)。这种情况下,MySQL 会把一个 utf8mb4 中文字符(如“订”,占 3 字节)误拆成多个单字节单位处理,导致分隔符定位偏移。

执行这条命令验证:

SHOW VARIABLES LIKE 'character_set_%';

重点关注这三项值是否都为 utf8mb4。如果不是:

  • 连接时加参数:JDBC 用 ?useUnicode=true&characterEncoding=utf8mb4;PHP PDO 加 PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
  • 临时修复:在查询前手动执行 SET NAMES utf8mb4;
  • 永久修复:修改 MySQL 配置文件 my.cnf 的 [client] 和 [mysqld] 段,加入 default-character-set = utf8mb4 和 collation-server = utf8mb4_unicode_ci

SUBSTRING_INDEX 处理中文分隔符时必须显式转换字段

即使表定义了 CHARACTER SET utf8mb4,SUBSTRING_INDEX 仍按当前会话字符集解析字符串长度和分隔符位置。中文分隔符(如“/”、“-”、“|”)在 latin1 会话中会被当成单字节处理,而实际占 3 字节,造成截断点错位。

错误写法(会话为 latin1 时):

SELECT SUBSTRING_INDEX('订单-2024-05-01', '-', 2);

安全写法(强制字段以 utf8mb4 解析):

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • SUBSTRING_INDEX(CONVERT(your_column USING utf8mb4), '-', 2)
  • SUBSTRING_INDEX(CAST(your_column AS CHAR CHARACTER SET utf8mb4), '/', -1)
  • 若字段可能为空或 NULL,建议先用 IFNULL 包裹,避免 CONVERT 返回 NULL 导致整行失效

提取中文路径末段时的典型失败现象

比如字段存着 http://example.com/用户中心/订单管理,想用 SUBSTRING_INDEX(url, '/', -1) 取出“订单管理”,结果却是“单管理”或空值——这是因斜杠位置被算在某个中文字符中间字节上。

验证是否已发生字节错位:

SELECT LENGTH('用户中心'), CHAR_LENGTH('用户中心');

若前者是 12、后者是 4,说明是 utf8mb4 编码;若两者都是 4,可能是旧 utf8(不支持 emoji),但对常用中文也够用;若前者是 4、后者也是 4,那大概率是 latin1 上下文在骗你。

此时不能只靠 SET NAMES,必须字段级兜底:

  • 用 CONVERT(col USING utf8mb4) 强制重编码再切
  • 避免用 SUBSTRING_INDEX 处理含 emoji 或混合符号的路径(如 ?/用户中心/✅订单),改用应用层解析更可靠

当 SUBSTRING_INDEX 不可靠时,替代方案怎么选

如果字段含 emoji、中英文混排、第三方 ETL 工具直连无法控制客户端字符集,SUBSTRING_INDEX 就容易失效——它本质是字节偏移计算,不是语义切分。

可考虑:

  • 应用层处理:Python 用 str.rsplit('/', 1)[-1],Java 用 url.substring(url.lastIndexOf('/') + 1),完全绕过 MySQL 字符集陷阱
  • MySQL 8.0+ 可用正则: REGEXP_SUBSTR(url, '[^/]+$'),但需确保 collation 是 utf8mb4 相关,否则正则仍会错位
  • 预处理字段:建触发器或 ETL 步骤,在入库时就把路径末段单独存为新列,避免每次查询都现场切

真正棘手的不是函数不会用,而是你以为它在按“字符”切,其实它在按“字节”跳——而中文字符的字节数,取决于你此刻坐在哪个字符集的椅子上。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2173

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1339

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

775

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2972

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

5008

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1139

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

5271

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

4622

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

6114

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 183人学习