MySQL 04-EMOJI 表情与 UTF8MB4 的故事

拓展阅读

MySQL View

MySQL truncate table 与 delete 清空表的区别和坑

MySQL Ruler mysql 日常开发规范

MySQL datetime timestamp 以及如何自动更新,如何实现范围查询

MySQL 06 mysql 如何实现类似 oracle 的 merge into

MySQL 05 MySQL入门教程(MySQL tutorial book)

MySQL 04- EMOJI 表情与 UTF8MB4 的故事

MySQL Expression 1 of ORDER BY clause is not in SELECT list,references column

emoji

想在 mysql 数据库插入 emoji 表情,结果报错:

### Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x8B' for column 'name' at row 1

错误原因很多小伙伴也知道,mysql 种的 utf8 和 java 的 utf-8 并不是完全对等的。

应该指定 mysql 的编码为 utf8mb4 才是正确的。

修改编码

查看编码

show variables like 'character_set_database'; # 查看数据库编码
show create table comment; # 查看表编码

修改数据库 & 表编码

可以在原来的基础上直接修改:

alter database <数据库名> character set utf8mb4; # 修改数据库
alter table <表名> character set utf8mb4; # 修改表
alter table <表名> change <字段名> <字段名> <类型> character set utf8mb4; # 修改字段

建表时指定

drop database echo_blog;
CREATE DATABASE echo_blog DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;drop table comment;
create table comment
(id int unsigned auto_increment comment '主键' primary key,create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间',update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
) comment '评论信息' ENGINE=Innodb default charset=UTF8MB4 auto_increment=1;

乱码问题

修改完成之后,插入成功。

但是数据库中全部是 ??? 之类的内容,而不是表情内容。

到底哪里出问题了呢?

mysql 编码问题

查看 mysql 编码

SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';

如下:

mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
+--------------------------+----------------------------------------------------+
| Variable_name            | Value                                              |
+--------------------------+----------------------------------------------------+
| character_set_client     | utf8mb4                                            |
| character_set_connection | utf8mb4                                            |
| character_set_database   | utf8mb4                                            |
| character_set_filesystem | binary                                             |
| character_set_results    | utf8mb4                                            |
| character_set_server     | utf8mb4                                            |
| character_set_system     | utf8                                               |
| character_sets_dir       | D:\tools\mysql\mysql-5.7.24-winx64\share\charsets\ |
| collation_connection     | utf8mb4_unicode_ci                                 |
| collation_database       | utf8mb4_unicode_ci                                 |
| collation_server         | utf8mb4_unicode_ci                                 |
+--------------------------+----------------------------------------------------+

属性说明:

character_set_client

主要用来设置客户端使用的字符集。通俗的讲就是mysql把客户端传递过来的数据都当成是utf8mb4

character_set_connection

主要用来设置连接数据库时的字符集,如果程序中没有指明连接数据库使用的字符集类型则按照这个字符集设置。

character_set_database

主要用来设置默认创建数据库的编码格式,如果在创建数据库时没有设置编码格式,就按照这个格式设置。

character_set_filesystem

文件系统的编码格式,把操作系统上的文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的。

character_set_results

数据库给客户端返回时使用的编码格式,如果没有指明,使用服务器默认的编码格式。通俗的讲就是mysql发送个客户端的数据是utf8mb4的

character_set_server

服务器安装时指定的默认编码格式,这个变量建议由系统自己管理,不要人为定义。

character_set_system

数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式。

character_sets_dir

这个变量是字符集安装的目录。

Mysql的字符集内部处理

1.mysql Server收到请求时将请求数据从 character_set_client 转换为 character_set_connection

2.进行内部操作前将请求数据从 character_set_connection 转换为内部操作字符集,步骤如下

  A. 使用每个数据字段的 CHARACTER SET 设定值;

  B. 若上述值不存在,则使用对应数据表的字符集设定值

  C. 若上述值不存在,则使用对应数据库的字符集设定值;

  D. 若上述值不存在,则使用 character_set_server 设定值。

3.最后将操作结果从内部操作字符集转换为 character_set_results

mysql charsets

临时修改配置

上面的配置都可以通过命令临时修改:

SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_database = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_server = utf8mb4;SET collation_connection = utf8mb4_unicode_ci;
SET collation_database = utf8mb4_unicode_ci;
SET collation_server = utf8mb4_unicode_ci;

当然,也可以通过修改 my.ini 配置文件。

修改 mysql 服务器配置文件

比如 windows 下个人的 mysql 安装目录为:D:\tools\mysql\mysql-5.7.24-winx64

那就在下面创建 my.ini(如果没有的话)。

内容如下:

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4[mysqld]
# 设置3306端口
port=3306
# 允许最大连接数
max_connections=20
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODBcollation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'character-set-client-handshake = FALSE
explicit_defaults_for_timestamp=true[client]
default-character-set=utf8mb4

修改完成后需要重启 mysql 服务。

可以在 bin 下执行 mysqld restart。这个实践下来只初始化了部分编码。

个人实在 windows services(服务) 下,把 mysql 服务进行了重新启动。

jdbc 配置

druid 数据源配置

spring:datasource:druid:username: rootpassword: xxxxxxurl: jdbc:mysql://localhost:3306/echo_blog?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCdriver-class-name: com.mysql.jdbc.Driverconnection-init-sqls: set names utf8mb4;

官方资料

https://dev.mysql.com/doc/connectors/en/connector-j-reference-charsets.html

Notes
For Connector/J 8.0.12 and earlier: In order to use the utf8mb4 character set for the connection, the server MUST be configured with character_set_server=utf8mb4; if that is not the case, when UTF-8 is used for characterEncoding in the connection string, it will map to the MySQL character set name utf8, which is an alias for utf8mb3.For Connector/J 8.0.13 and later:When UTF-8 is used for characterEncoding in the connection string, it maps to the MySQL character set name utf8mb4.If the connection option connectionCollation is also set alongside characterEncoding and is incompatible with it, characterEncoding will be overridden with the encoding corresponding to connectionCollation.Because there is no Java-style character set name for utfmb3 that you can use with the connection option charaterEncoding, the only way to use utf8mb3 as your connection character set is to use a utf8mb3 collation (for example, utf8_general_ci) for the connection option connectionCollation, which forces a utf8mb3 character set to be used, as explained in the last bullet.Warning
Do not issue the query SET NAMES with Connector/J, as the driver will not detect that the character set has been changed by the query, and will continue to use the character set configured when the connection was first set up.

说明:

提示
mysql-connector-java 版本在8.0.12之前的,包括8.0.12,服务端必须设置character_set_server=utf8mb4;如果不是的话,就算设置了characterEncoding=UTF-8,照样会被设置为MYSQL的 utf8字符集,也就是utf8mb3。对于8.0.13和以后的版本,如果设置了characterEncoding=UTF-8,他会映射到MYSQL的utf8mb4字符集。如果connectionCollation 也和characterEncoding一起设置了,但是不兼容,characterEncoding会被connectionCollation的设置覆盖掉。由于没有Java-Style的utfmb3对应的字符集名称可以用在connection选项charaterEncoding上,唯一的设置utf8mb3的方式就是在连接选项设置utf8mb3 collation(例如utf8_general_ci),这会强制使用utf8mb3字符集,正如上文所述。警告
不要通过Connector发起SET NAMES指令,因为driver不会检测字符集是不是被查询语句改动,并且当连接第一次建立之后,会继续使用当时的字符集设置。

可以发现 jdbc 中的配置 connection-init-sqls: set names utf8mb4; 这句话是没啥用的。

建议老老实实的修改 mysql 服务端的配置。

依然乱码

这个时候 java 客户端保存 emoji,依然有部分乱码。

比如:

💔✊💓💖😧😯 I Love this!

用命令行查看,数据库变成了:

 �✊���� I Love this!

部分乱码? what's up?

java 程序断点

在 java 应用中进行断点,发现内容是对的。

mysql 命令行插入

我们直接在 mysql 命令行执行插入:

insert into comment (content) values ('💔✊💓💖😧😯 I Love this!');

MD,发现无法执行,这条路走不通。

命令行终端不支持 emoji 表情。

乱码的原因

这个乱码是因为 mysql 终端导致的,还是别的原因?

我们测试一下,使用 java 程序对内容进行查询。

测试代码

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class CommentServiceTest {@Autowiredprivate CommentService commentService;@Testpublic void selectTest() {Comment comment = commentService.selectById(20);System.out.println(comment);}}

测试效果

日志如下:

Comment{id=20, content=💔✊💓💖😧😯 I Love this!, ackFlag=N, createTime=Sun Aug 15 10:13:56 CST 2021, updateTime=Sun Aug 15 10:13:56 CST 2021}

可以发现,存储的数据本身是没有问题的。

是命令行终端的问题。

命令行的问题

已有的命令行

一开始使用的是 windows10 自带的 cmd,发现不行。

使用 cmder 命令行,还是不行。

powershell

我们测试下微软商店的 Terminal 命令行,也就是新版本的 powershell。

cd D:\tools\mysql\mysql-5.7.24-winx64\bin
.\mysql -uroot -p

登录后执行查询,结果如下:

💔✊💓💖😧😯 I Love this! 

纠结了半天的乱码,经确认是命令行终端的问题。

参考资料

MySQL的utf8、utf8mb4、编码问题详解

mysql字符集utf8mb4失效踩坑

Mysql UTF-8mb4字符集的问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL基础练习题:习题21-25

这部分主要是为了帮助大家回忆回忆MySQL的基本语法&#xff0c;数据库来自于MySQL的官方简化版&#xff0c;题目也是网上非常流行的35题。这些基础习题基本可以涵盖面试中需要现场写SQL的问题。 列出在部门sales工作的员工的姓名&#xff0c;假定不知道销售部的部门编号 sele…

产品思维训练 | 熊孩子任性打赏从产品角度有哪些方法可以规避?

本周话题&#xff1a; 抖音回应10岁儿童打赏主播10万&#xff1a;已全额退款。正值特殊时期&#xff0c;小朋友们花费在直播APP中的时间也不少。 对于打赏等行为&#xff0c;当然需要家长加强监督&#xff0c;除此之外&#xff0c;产品方面可以做什么措施&#xff0c;压制住胡…

【JS】获取接口返回 EventStream 结构的数据(即接收读取 stream 流)

文章目录 EventStream 是一种服务器推送的数据格式&#xff0c;可以用于实时数据传输。 接口返回的示例图 获取示例&#xff1a; // 这里的 url 为虚拟的&#xff0c;仅供演示用 fetch(https://test.cn.com/api/agent/2, {method: POST,headers: {Content-Type: applicatio…

Docker部署前后端项目

使用Docker部署前后端项目的全面指南 在现代软件开发中&#xff0c;Docker已经成为了部署应用程序的一种流行方式。它提供了一种轻量级的、可移植的、自给自足的解决方案&#xff0c;可以在不同的环境中一致地运行应用程序。本文将详细介绍如何使用Docker来部署一个包含前端和…

Hudi原理学习

Hudi原理学习 一、Hudi是什么 Hudi&#xff08;Hadoop Upsert Delete and Incremental&#xff09;是什么&#xff1a;围绕数据库内核构建的流式数据湖平台&#xff08;Streaming Data Lake Platform&#xff09; 简而言之&#xff0c;它是一个对计算和存储进行解耦的数据湖方…

提取图片地理位置

引言 在数字化时代&#xff0c;图片已经成为我们生活中不可或缺的一部分。然而&#xff0c;如何从图片中提取有用的信息&#xff0c;尤其是地址信息&#xff0c;一直是一个具有挑战性的问题。Python作为一种强大的编程语言&#xff0c;为我们提供了丰富的工具和库来解决这个问…

【SGDR】《SGDR:Stochastic Gradient Descent with Warm Restarts》

arXiv-2016 code: https://github.com/loshchil/SGDR/blob/master/SGDR_WRNs.py 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metric5.2 Single-Model Results5.3 Ensemble Results5.4 Experiment…

智慧污水井物联网远程监控案例

智慧污水井物联网远程监控案例 在当今数字化转型的浪潮中&#xff0c;智慧水务已成为城市基础设施建设的重要组成部分。其中&#xff0c;基于物联网技术的智慧污水井远程监控系统以其高效、精准、实时的特性&#xff0c;在提升污水处理效能、保障城市水环境安全、实现精细化管…

每日一题 — 水果成篮

思路&#xff1a; 通过阅读上面文字得出问题&#xff1a;就去只有两个种类的最大长度的连续子数组&#xff0c;这时我们可以想到用哈希表来存储数据&#xff0c;记录数据的种类和每个种类的数量。 解法一&#xff1a;暴力递归&#xff08;right每次遍历完都回退&#xff09; 解…

oceanbase一键安装

安装文档&#xff1a;https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000642554 软件下载 https://www.oceanbase.com/softwarecenter 安装obd yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/oceanbase/OceanBa…

Hystrixd的概念、作用、使用方法

概念&#xff1a; Hystrix是Netflix开源的一个用于分布式系统的延迟和容错库&#xff0c;其主要目的是提供容错能力&#xff0c;防止分布式系统中的雪崩效应。它通过对服务调用进行隔离、降级、断路器等处理&#xff0c;确保系统在异常情况下依然能够提供基本的功能。 在微服…

今日总结2024/4/12

明天蓝桥杯,祝看到此帖的会的都写出来&#xff0c;不会能暴力出来。 应该是第一次也是最后一次打了 P8602 [2013 省 A] 大臣的旅费 本题是图的邻接表的vector加pair存储形式&#xff0c;用来存储权值 本题概念为树的直径&#xff0c;可以先任选一个点找到距离这个点最远的点…

无线游戏手柄的测试(Windows11系统手柄调试方法)

实物 1、把游戏手柄的无线接收器插入到电脑usb接口中 2、【控制面板】----【查看设备和打印机】 3、【蓝牙和其它设备】--【更多设备和打印机设置】 4、鼠标右键【游戏控制器设置】 5、【属性】 6、【测试】&#xff08;每个按键是否正常&#xff09; 7、【校准】&#xff08;…

稀碎从零算法笔记Day46-LeetCode:互质树

这几天有点懈怠了 题型&#xff1a;树、DFS、BSF、数学 链接&#xff1a;1766. 互质树 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个 n 个节点的树&#xff08;也就是一个无环连通无向图&#xff09;&#xff0c;节点编号从 0 到 …

使用Python快速模拟前端常用页面数据格式

1.模拟表格数据格式 import random data [] num_records 10 for _ in range(num_records):record {}record["name"] "Person" str(random.randint(1, 100)) # 随机生成姓名record["age"] random.randint(20, 60) # 随机生成年龄record[…

从“黑箱”到“透明”:云里物里电子标签助力汽车总装数字化转型

“汽车总装”指“汽车产品&#xff08;包括整车及总成等&#xff09;的装配”&#xff0c;是把经检验合格的数以百计、或数以千计的各种零部件按照一定的技术要求组装成整车及发动机、变速器等总成的工艺过程&#xff0c;是汽车产品制造过程中最重要的工艺环节之一。 其中&…

全量知识系统 程序详细设计 之 三种“活物” 之1(QA百度文库 2 )

前面一篇整理完之后&#xff0c;发现有些内容有问题。下面是重新就这个话题沟通的内容。 Q1. 三种 的进一步表述&#xff1a;KE “态”套件-情境演算&#xff08;“特征”Strcture::Class&#xff09;“全局global 垂直 等价” 丄<<Coreference>> (KE主目命名惯式…

算法 囚犯幸存者

题目 主类 public static List<Prisoner> prisoners new ArrayList<Prisoner>(); public static List<Prisoner> remainPrisoners new ArrayList<Prisoner>(); public static Prisoner lastPrisoner null;public static void main(String[] args) …

props组件传值(子串子)

父组件 <version :show"versionShow" closeVersion"versionShow false" data"onData"></version> <footBar url"index" :footShow"footShow"></footBar>第一个version 组件 this.$emit(data, fals…

一款自研Python解释器

项目简介: PikaScript是一个完全重写的超轻量级python引擎,具有完整的解释器,字节码和虚拟机架构,可以在少于4KB的RAM下运行,用于小资源嵌入式系统。相比同类产品,如MicroPython,LuaOS等,资源占用减少85%以上。 入选2021年度 Gitee最有价值开源项目,加入RT-Thread嵌入…