一文搞懂MySQL字符集

字符集和字符编码

Unicode:

也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准。是一个包含上百万字符的字符集。 Unicode(统一码)是计算机科学领域的一项国际化字符编码标准,旨在为全球所有文字系统(如中文、英文、日文、阿拉伯文等)提供唯一的数字编号(码点), 从而解决多语言文本的存储、交换和显示问题。 强调其是字符集,而不是编码方案。只是统一一个标准,比如大写字母A的编码或者叫做码点是U+0041,对应十进制65,Unicode只负责定义这个码点,而具体在计算机中怎么存储和传输,而、是使用编码方案来实现,比如在计算机中占几个字节,具体按照什么规则进行翻译,都是编码方案来实现的,其中编码方案有ASCII 、UTF8等编码方案。


编码方案:

  • ASCII :是1963年制定的单字节编码标准,最初用于英语文本的电子化表示。它使用 7位二进制数(范围 0x00 到 0x7F)表示字符,共支持 128 个字符。
  • UTF8: 是一种变长编码,用于表示 Unicode 标准中的所有字符(包括 ASCII、中文、日文、表情符号等)。它使用 1 到 4 字节表示一个字符,兼容 ASCII 并支持全球语言。
  • MySQL中的UTF8:是阉割版的UTF8,只用1到3个字节编码字符,所以设置字符编码为UTF8默认就是UTF8mb3。mysql8.0中已经替换成了UTF8mb4为默认字符编码。

MySQL中字符集的作用

在使用mysql服务的过程中,有很多地方涉及到字符的编码和解码过程,比如连接数据库服务,发送请求以及sql服务返回请求结果的操作。还有字符类型的数据存入数据库中的解码和编码。 通过以下指令我们可以查看到mysql相关字符集设置的编码方式:

sql 复制代码
-- 查看当前连接的相关字符集编码属性
show variables like 'character_%';
-- 查看全局系统变量字符集编码属性
show global variables like 'character_%';

通常使用show global variables like 'character_%';查看系统级别的字符集设置。 输出结果:

Variable_name Value
character_set_client utf8mb4
character_set_connection utf8mb4
character_set_database utf8mb4
character_set_results utf8mb4
character_set_server utf8mb4

以上5个系统变量,决定了以下相关行为当中的字符解码编码标准:

客户端发请求---按照操作系统默认编码将请求体编码成对应字符集--->服务器根据character_set_client编码方式把客户端发过来的请求体解码出来--->服务器按照character_set_connection编码成对应字符集去数据库里进行数据查询修改等操作。如果是查询语句,character_set_connection设置的编码和存入表里的编码character_set_database或者character_set_server对应不上,查询就会出错。--->再根据character_set_results返回结果到客户端

设置字符集编码方式

方式一:逐一设置,服务重启后会失效

js 复制代码
set character_set_server=utf8mb4;

方式二:相当于设置了character_set_client、character_set_connection、 character_set_results这三个属性,重启后失效

js 复制代码
set NAMES utf8mb4;

方式三:在配置文件里设置,重启有效

js 复制代码
控制所有MySQL客户端工具(如mysql命令行、mysqldump、mysqladmin等)与服务器通信时的字符集行为。
会将下面三个全局系统变量同步
character_set_client
character_set_connection
character_set_results
[client] 
default-character-set=utf8mb4


仅控制mysql命令行客户端(即通过终端直接输入mysql -u root -p启动的交互式工具)的字符集行为。
优先级高于[client]:如果同时配置了[client]和[mysql],[mysql]的配置会覆盖[client]对mysql客户端的影响。
没有影响到上面几个变量的值
[mysql]
default-character-set=utf8mb4

控制MySQL服务器本身的字符集行为,包括:
服务器默认字符集(影响新创建的数据库/表)。
服务器与客户端通信时的初始字符集协商(除非显式禁用协商)。
内部数据存储和处理的字符集(如排序、比较等)。
会将下面两个个全局系统变量同步:
character_set_server
character_set_database
[mysqld]
character-set-server=utf8mb4

方式四:通过jdbc url连接参数指定字符集

js 复制代码
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=UTC

数据库、表和字段设置字符集

在创建数据库、表和字段时可以指定默认字符集,在不设置字符集的情况下,字段的默认字符集跟随表,表的字符集跟随库,库的字符集跟随character_set_database的字符集,如果character_set_database没设置则跟随character_set_server。

js 复制代码
-- 创建数据库时指定字符集
CREATE DATABASE 数据库名
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

-- 示例:创建支持完整Unicode的数据库
CREATE DATABASE myapp_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

-- 创建表时指定字符集
CREATE TABLE 表名 (
    字段定义
) 
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

-- 示例:创建用户表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    bio TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) 
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

-- 创建字段时指定字符集
CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
    description TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
    price DECIMAL(10,2)
);

已经创建的库、表和字段修改字符集

js 复制代码
-- 修改数据库默认字符集
ALTER DATABASE 数据库名 
CHARACTER SET 字符集名称 
COLLATE 校对规则;

-- 示例:将数据库mydb的字符集改为utf8mb4
ALTER DATABASE mydb 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;


-- 修改表的默认字符集
ALTER TABLE 表名 
CONVERT TO 
CHARACTER SET 字符集名称 
COLLATE 校对规则;

-- 示例:将表users的字符集改为utf8mb4
ALTER TABLE users 
CONVERT TO 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;

-- 修改单个字段的字符集
ALTER TABLE 表名 
MODIFY COLUMN 字段名 字段类型 
CHARACTER SET 字符集名称 
COLLATE 校对规则;

-- 示例:将users表的name字段改为utf8mb4
ALTER TABLE users 
MODIFY COLUMN name VARCHAR(100) 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;

记录学习,仅供参考
进制转换小技巧记录: 一个8进制数可以用3位二进制表示,一个16进制数可以用4位二进制表示。 然后二进制到10进制用8421法进行转换。 eg: 二进制转换位10进制:1011 对应十进制分别是 8 4 2 1。因为4对应的位置是0,所以1011=8+2+1=11 二进制转换位8进制:1011,每三位对应一个8进制数,从低到高进行分组,1 011 ,011是4、2、1 ,4位置对应的是0,所以011=2+1=3。然后最前面还剩一个1,补齐三位就是001=4、2、1 就是001=1,最后把001 和011组合在一起就是对应的8进制数13。 二进制转换为16进制,同理,不赘述了。1011对应8421=8+2+1=11,对应16进制a。

相关推荐
苏小瀚1 小时前
[MySQL] 初识数据库
数据库·mysql
还是奇怪1 小时前
SQL注入的“无影脚”:详解空格绕过WAF的N种方法
数据库·sql·安全·web安全
xcg3401232 小时前
Spring boot中 限制 Mybatis SQL日志的大字段输出
spring boot·sql·mybatis·大字段打印
lagelangri6662 小时前
MySql的存储过程以及JDBC实战
android·数据库·mysql
程序视点10 小时前
MySQL COUNT(*)性能对比:MyISAM为何比InnoDB快?全面解析与优化方案
mysql
lang2015092814 小时前
MySQL InnoDB备份恢复全指南
数据库·mysql
孟意昶16 小时前
Spark专题-第三部分:性能监控与实战优化(1)-认识spark ui
大数据·数据仓库·sql·ui·spark·etl
比特森林探险记17 小时前
MySQL 架构全景解析
数据库·mysql·架构
橄榄熊18 小时前
Docker MySQL 使用全流程
mysql·docker·容器
阿巴~阿巴~19 小时前
MySQL复合查询(重点)
服务器·数据库·sql·mysql·ubuntu