MySql 8.0 字符编码utf8mb4小实验

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: MySql 8.0 字符编码utf8mb4小实验

在某次数据处理过程中,需要将所有的英文括号"()"替换成中文括号"()",处理的过程中发现在进行 or 条件判断时,条件的顺序不同会导致查询的结果不一致,但是同样的sql在 mysql 5.7 中是可以正常查询出结果的,于是就做了一下实验。

1、创建数据表

CREATE TABLE `mytable` (

 `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK,自增,企业ID',

 `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '企业名称',

 PRIMARY KEY (`id`),

 KEY `ux_name_isdelete` (`name`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

2、插入实验数据

INSERT INTO `mytable` (`id`,`name` )VALUES (61405,'test1英文括号d()ceshi');

INSERT INTO `mytable` (`id`,`name`) VALUES (12706,'蓝莓d()英文括号');

3、前置条件

在进行查询前,我们先进行以下几点确认:

  • 数据库的编码为 utf8
  • 客户端连接的编码为 utf8mb4

4、字符和字节

简单来说字符就是不管中英文你数这个字符串有多少就是多少个字符。而字节就不一样了,不同的编码会影响它的长度。在utf8编码中,中文是占3个字节,其他数字、英文、符号占一个字节;而utf8mb4编码中,中文占3个字节,emoji符号、复杂的文字、繁体字占4个字节。

select char_length('test1英文括号d()ceshi🍄') as 字符,length('test1英文括号d()ceshi🍄') as 字节;

结果:

上述字符串中包含6个中文、11个英文+数字、1个emoji,所以在计算字节时,结果为:6*3 + 11 + 4 = 33。

5、实验

1)单纯的括号查询

-- 前英文后中文

select '('='(';

结果:

select '()'='()'

结果:

select '()'='()'

结果:

2)英文汉字混合查询

select 'test1英文括号d()ceshi' = 'test1英文括号d()ceshi'


3)做where条件查询

  • 条件 a :

SELECT * FROM mytable WHERE name= 'test1英文括号d()ceshi';

结果:

  • 条件 b:

SELECT * FROM mytable WHERE name= 'test1英文括号d()ceshi';

结果:

进行字符替换后,我们将中文替换为英文(即上述条件 a)放在 or 条件之前:

SELECT name

,replace( replace('test1英文括号d()ceshi', "(", "("), ")", ")") a

,replace(replace('test1英文括号d()ceshi', "(", "("), ")", ")") b

 FROM mytable

WHERE

    ( name= replace( replace('test1英文括号d()ceshi', "(", "("), ")", ")")) -- a

or   (name= replace( replace('test1英文括号d()ceshi', "(", "("), ")", ")")) -- b

;

结果:

进行字符替换后,我们将英文替换为中文(即上述条件 b)放在 or 条件之前:

SELECT name

,replace( replace('test1英文括号d()ceshi', "(", "("), ")", ")") a

,replace( replace('test1英文括号d()ceshi', "(", "("), ")", ")") b

 FROM mytable

WHERE

(name= replace( replace('test1英文括号d()ceshi', "(", "("), ")", ")")) -- b

    or

    ( name= replace(replace('test1英文括号d()ceshi', "(", "("), ")", ")")) -- a

;

结果:


从上述的结果可以看出,当服务器编码为 utf8 客户端编码为 utf8mb4 时,中文和英文的字符串被认为是相同的,但是当把这个字符串去和 uf8 编码的表中数据进行比较时是被判定为不同的。

要解决这种问题需要统一客户端与服务端的编码:

  • 将客户端的链接设置为 utf8

set names  utf8;

  • 将数据表设置为utf8mb4

ALTER TABLE `mytable`

DEFAULT CHARACTER SET=utf8mb4,

COLLATE=utf8mb4_unicode_ci,

MODIFY COLUMN `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业名称' AFTER `id`

;

关于更多编码的内容可以查看 Mysql 8.0 的官方说明文档:

https://dev.mysql.com/doc/refman/8.0/en/charset-mysql.html

https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb4.html

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
存储 关系型数据库 MySQL
Mysql中utf8和utf8mb4区别
Mysql中utf8和utf8mb4区别
40 0
|
9月前
|
存储 关系型数据库 MySQL
MySQL数据库实验九 MySQL应用系统开发
MySQL数据库实验九 MySQL应用系统开发
191 0
|
18天前
|
存储 Java 关系型数据库
实验设备管理系统【GUI/Swing+MySQL】(Java课设)
实验设备管理系统【GUI/Swing+MySQL】(Java课设)
10 0
|
3月前
|
存储 自然语言处理 关系型数据库
👨‍💻如何使用MySQL存储Emoji表情,UTF-8和UTF-8MB4字符编码有何区别?
👨‍💻如何使用MySQL存储Emoji表情,UTF-8和UTF-8MB4字符编码有何区别?
93 1
|
9月前
|
安全 关系型数据库 MySQL
MySQL数据库实验七 MySQL安全管理
MySQL数据库实验七 MySQL安全管理
98 0
|
9月前
|
存储 关系型数据库 MySQL
MySQL数据库实验六 MySQL并发事务与锁机制
MySQL数据库实验六 MySQL并发事务与锁机制
50 0
|
9月前
|
关系型数据库 MySQL 数据库
MySQL数据库实验三 MySQL查询
MySQL数据库实验三 MySQL查询
228 0
|
4月前
|
关系型数据库 MySQL Serverless
|
6月前
|
关系型数据库 MySQL 索引
MySQL命中索引代码实验案例
MySQL命中索引代码实验案例
|
8月前
|
关系型数据库 MySQL Linux
mysql 8中utf8和utf8mb4运行时的编码警告提醒[Warning]——my.ini配置问题
mysql 8中utf8和utf8mb4运行时的编码警告提醒[Warning]——my.ini配置问题