MySQL 字符集概念、原理及如何配置 — 图文详解

news2024/12/30 2:56:12

目录

一、字符集概念

1、字符(Character)

2、字符编码

3、字符集(Character set)

二、字符集原理

1. ASCII字符集

2、GB2312

3、GBK

4、GB18030

5、BIG5

6、Unicode 编码

三、字符序

四、MySQL字符集 & 字符序

1、mysql 字符集

2、mysql 字符序

3、字符集与字符序的关系

五、MySQL 数据存储字符集

1. 字符集层级关系

2、如何设置字符集

2.1 服务器字符集设置

2.2 数据库字符集设置

2.3 数据表字符集设置

2.4 字段字符集设置

3、多级的字符集 & 多个字符集的作用

六、MySQL 客户端与服务端交互字符集

1、交互示意图

2、如何设置字符集


    我们在使用 MySQL 的过程中,经常会碰到诸如乱码之类的问题。字符编码与字符集密切相关,MySQL 支持种类繁多的字符集类型,这些字符集到底如何影响 MySQL 数据存储与数据传输的呢?我们该如何选择正确的字符集?那就通过这篇文章来帮你捋清细节和解除困扰吧!

本文依赖以下环境:

操作系统:MAC OS 10.11.6

MySQL:Server version: 5.6.21 MySQL Community Server (GPL)

一、字符集概念

1、字符(Character)

字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字、😀(emoji表情)等属于字符的范畴。

2、字符编码

计算机是通过 BIT 来存储数据的,将人类可识别的字符转换成计算机能够存储的形式,这个过程就是字符编码。

3、字符集(Character set)

字符集是多个字符的集合,包含一组字符以及对应的编码方式。字符集种类较多,每个字符集包含的字符个数和编码方式不同,常见字符集名称:ASCII 字符集、GB2312 字符集、BIG5 字符集、 GB18030 字符集、Unicode 字符集等。

二、字符集原理

1. ASCII字符集

我们熟知的 ASCII 字符集是一种现代美国英语适用的字符集。包括的字符有数字、大小写字母、分号、换行之类的符号,编码方式是用一个 7bit 表示一个字符,例如A的编码是 65,b 的编码是 98。

ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,主要编码表如下图所示。

2、GB2312

GB2312 字符集是一种对汉字比较友好的字符集,共收录 6700 多个汉字,基本涵盖了绝大部分常用汉字。不过,GB2312 字符集不支持绝大部分的生僻字和繁体字。对于英语字符,GB2312 编码和 ASCII 码是相同的,1 字节编码即可。对于非英字符,需要 2 字节编码。

3、GBK

GBK 字符集可以看作是 GB2312 字符集的扩展,兼容 GB2312 字符集,共收录了 20000 多个汉字。GBK 中 K 是汉语拼音 Kuo Zhan(扩展)中的 “Kuo” 的首字母。

4、GB18030

GB18030 完全兼容 GB2312 和 GBK 字符集,纳入中国国内少数民族的文字,且收录了日韩汉字,是目前为止最全面的汉字字符集,共收录汉字 70000 多个。

5、BIG5

BIG5 主要针对的是繁体中文,收录了 13000 多个汉字。

6、Unicode 编码

ASCII 只对英文符号和英文字母做了编码,GB2312对英文符号,英文字母,汉字做了编码。每个国家为了更加适合本国语言,都有一套自己的字符集。不同的字符集可以表示的字符范围以及编码规则存在差异。同一个编码,对于不同的字符集来说就可能代表不同的字符:

这就导致了一个非常严重的问题:使用错误的编码方式查看一个包含字符的文件就会产生乱码现象。就比如说你使用 UTF-8 编码方式打开 GB2312 编码格式的文件就会出现乱码。示例:“牛”这个汉字 GB2312 编码后的十六进制数值为 “C5A3”,而 “C5A3” 用 UTF-8 解码之后得到的却是 “ţ”

为了解决不同语言编码之间不兼容的问题,Unicode 出现了。Unicode 字符集致力于为全世界每一个语言的每一个字符都有统一且唯一的编码,Unicode 字符序号的范围是 0x000000 到0x10FFFF,可以容纳110多万个字符。UTF8、UTF16、UTF32是Unicode编码的不同实现方式:

  • UTF-8 使用 1 到 4 个字节为每个字符编码, UTF-16 使用 2 或 4 个字节为每个字符编码,UTF-32 固定位 4 个字节为每个字符编码。
  • UTF-8 可以根据不同的符号自动选择编码的长短,像英文字符只需要 1 个字节就够了,这一点 ASCII 字符集一样 。因此,对于英语字符,UTF-8 编码和 ASCII 码是相同的。
  • UTF-32 的规则最简单,不过缺陷也比较明显,对于英文字母这类字符消耗的空间是 UTF-8 的 4 倍之多。
     

三、字符序

一个字符集中有多个字符,那么如何对其中的字符进行排序呢?这就是字符序。简单来说,字符序就是字符排序的规则集合。

一个字符集中有多个字符,那么如何对其中的字符进行排序呢?这就是字符序。比如一个字符集有下面几个字符以及字符编码:

我们可以直接按照 A > B > a > b 的规则来进行排序,这就是这个简单字符集的一个字符序。如果想让小写字母放在前面,比如 a > b > A > B,这又是一种字符序。如果还想加上大小写无关或大小写相关,这就产生了不同的字符序。

四、MySQL字符集 & 字符序

接下来我们来看看 MySQL 的字符集与字符序。MySQL 目前支持多种字符集,支持在不同的字符集之间转换(便于移植和支持多语言)。

1、mysql 字符集

通过命令: mysql -u[username] -p[password]  连接上MySQL后,用下面命令查询MySQL 支持的字符集:

SHOW CHARACTER SET;

结果:

指定条件查询: 

SHOW CHARACTER SET LIKE 'utf%';

结果:

字段含义:

  • Charset: 字符集的名称;
  • Description:字符集的简单描述;
  • Default collation:该字符集的默认字符序;
  • Maxlen:该字符集中字符最大存储长度。

2、mysql 字符序

每个字符集都对应一个或多个字符序,可以通过下面的语句查看所有的字符序:

SHOW COLLATION;

结果(部分展示):

 指定条件查询:

SHOW COLLATION WHERE Charset = 'utf8mb4';

结果:

字段含义: 

  • Collation:字符序名称;
  • Charset:该字符序关联的字符集;
  • Id:字符序ID;
  • Default:该字符序是否是所关联的字符集的默认字符序。比armscii8_general_ci就是armscii8的默认字符序,而armscii8_bin就不是;
  • Compiled:字符集是否已编译到服务器中;
  • Sortlen:这与对以字符集表示的字符串进行排序所需的内存量有关;
  • Pad_attribute:这表明了字符序在比较字符串时对末尾padding的处理。NO PAD表明在比较字符串时,末尾的padding也会考虑进去,否则不考虑。

每个字符序都是以该字符序所关联的字符集为前缀的,同时还有一些有规律的后缀:

  • bin:二进制;
  • ci:大小写不敏感;
  • cs:大小写敏感;
  • ai:口音(Accent)不敏感;
  • as:口音敏感;
  • ks:假名(Kanatype)敏感。

同时有的字符序是面向某种语言的,也会在字符序名字中有所体现,比如big5_chinese_ci。
 

3、字符集与字符序的关系

字符集与字符序的关系可以上面的图来表示:

  • 每个字符集都有一个或多个字符序;
  • 每个字符集都有一个默认的字符序;
  • 每个字符序都关联一个且只有一个字符集;
  • 两个不同的字符集没有相同的字符序。

五、MySQL 数据存储字符集

1. 字符集层级关系

MySQL 是按层级来设定字符集与字符序的,MySQL 可以设置:服务器级字符集、数据库级字符集、数据表级字符集、表列级别字符集。实际上,最终使用字符集的地方是存储字符的列,它决定了数据库中存储的数据采用哪个字符集的编码和字符序。

结构图:

 层级图:

如上图所示:

上一层级如果没有指定字符集与字符序,就采用下一层级的字符集与字符序。也就是说:新建数据库时没有指定字符集,就默认设置为服务器的字符集;如果新建数据表时没有指定字符集,就默认设置为数据库的字符集;如果向数据表添加新列时没有指定列的字符集,那么这些列就默认设置为数据表的字符集。与字符集相同,如果不特别指定,字符序也采取了默认值继承的方式。

另一方面,直接改变这四个层次的编码并不会改变它们各自所有下层对象的当前编码。比如修改 Server 级,那么所有已经存在的数据库、数据表、表、列的字符集都不会发生改变。同时,数据表中每一条现有记录的字符字段仍然是按原来的编码存储的。

2、如何设置字符集

我们先来看下,MySQL 刚安装完,MySQL 字符集的的初始字符集和字符序是什么?

查看字符集变量:

SHOW VARIABLES LIKE 'character_set\_%';

查看字符序变量:

SHOW VARIABLES LIKE '%collation%';

查询结果:

character_set_server:服务器的字符集是 latin1

collation_server: 服务器的字符序是 latin1_swedish_ci

character_set_database:数据库的字符集是 latin1

collation_database:数据库的字符序是 latin1_swedish_ci

从上图可以看出,MySQL 服务器安装后已经初始化了服务器和数据库的默认字符集和字符序,另外,我们在创建数据库、表、添加字段时,都可以默认采用上一级的字符集和字符序,也可以在创建时自行指定:

2.1 服务器字符集设置

通过 character_set_server 变量的设定字符集的几个方式:

方式1:在 my.cnf 中配置

[mysqld]
character-set-server=utf8

方式2:启动时配置参数

mysqld --charater-set-server=utf8

方式3:编译时指定

[root@database-one ~]# cmake . -DDEFAULT_CHARSET=utf8

2.2 数据库字符集设置

// -- 示例: 创建数据库

create database if not exists dbtest character set utf8;

// -- 示例:修改数据库

ALTER DATABASE dbtest CHARACTER SET 'utf8';

2.3 数据表字符集设置

// -- 创建表时:DEFAULT CHARSET=utf8mb4 设置字符集

CREATE TABLE `t_employee` (

  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '员工ID',

  `code` varchar(10) NOT NULL COMMENT '员工编码',

  `name` varchar(10) NOT NULL COMMENT '员工姓名',

  `age` int(10) unsigned DEFAULT NULL COMMENT '年龄',

  `sex` int(10) unsigned DEFAULT NULL COMMENT '性别',

  `cert_type` int(10) unsigned DEFAULT NULL COMMENT '证件类型',

  `cert_no` varchar(20) DEFAULT NULL COMMENT '证件号',

  `birthday` date DEFAULT NULL COMMENT '生日',

  `income_date` date DEFAULT NULL COMMENT '入职日期',

  PRIMARY KEY (`id`),

  UNIQUE KEY `code` (`code`),

  UNIQUE KEY `cert_type` (`cert_type`,`cert_no`)

) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COMMENT='员工表';



// -- 修改表的字符集

ALTER TABLE `dbtest`.`t_employee` CHARACTER SET = utf8mb4;

2.4 字段字符集设置

// -- 创建表时:CHARACTER SET utf8mb4指定字段字符集

CREATE TABLE `t_employee` (

  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '员工ID',

  `code` varchar(10) NOT NULL COMMENT '员工编码',

  `name` varchar(10) NOT NULL COMMENT '员工姓名',

  `age` int(10) unsigned DEFAULT NULL COMMENT '年龄',

  `sex` int(10) unsigned DEFAULT NULL COMMENT '性别',

  `cert_type` int(10) unsigned DEFAULT NULL COMMENT '证件类型',

  `cert_no` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '证件号',

  `birthday` date DEFAULT NULL COMMENT '生日',

  `income_date` date DEFAULT NULL COMMENT '入职日期',

  PRIMARY KEY (`id`),

  UNIQUE KEY `code` (`code`),

  UNIQUE KEY `cert_type` (`cert_type`,`cert_no`)

) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='员工表';



// -- 修改字段的字符集:CHARACTER SET utf8mb4

ALTER TABLE `dbtest`.`t_employee` 

MODIFY COLUMN `cert_no` varchar(20) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '证件号' AFTER `cert_type`;

3、多级的字符集 & 多个字符集的作用

多级继承的字符集与字符序:可以方便快捷的确定下一层级的字符集和字符序,比如一个数据库下面有很多张表,只需要将数据库的字符集设置为 UTF8,所有表创建时就指定了默认的字符集。

早期只支持有限数量和编码字符集,后来不断的扩展,例如早期的 UTF8(阉割版本,早期 MySQL 版本为了节省存储空间,最多三个字节)完全够用了,后面出现了 EMOJI 表情符号,又不能满足要求了,于是有 utf8mb4 字符集。并且支持在同一个服务器下数据库有不同的字符集,同一个数据库下的不同表也可以设定不同的字符集,同一个表的不同字段也可以设定不同的字符集,都是为了方便业务的移植和扩展。(例如以前一个业务只覆盖了欧洲英文国家,采用 ladin 1字符集就足够了,但是后来有扩展到中国,于是需要将字符集扩展到 UTF8;之前全部采用UTF8字符集,但是发现用户注册的昵称使用了 EMOJI 表情符号,于是将 nickname 字段的字符集修改为 utf8mb4)。

六、MySQL 客户端与服务端交互字符集

上面 4 种级别的字符集都是用于数据保存的,其实客户端和服务器之间的交互也受到字符集和校对规则的影响。

MySQL提供了character_set_client、character_set_connection 和 character_set_results 三个参变量:

  • character_set_client
  • character_set_connection
  • character_set_results

1、交互示意图

既:

  1. 客户端的语句从客户端出发时,使用的字符集是 character_set_client
  2. 语句到达服务器时,服务器将语句转换成 character_set_connection字符集;
  3. 服务器执行完,将结果返回给客户端时,使用的是 character_set_results字符集。

2、如何设置字符集

方式1:在 MySQL 配置文件中设置 my.cnf:

[client]
default-character-set=utf8

方式2:在客户端执行:

SET NAMES utf8;

方式3:在连接地址配置:

jdbc:mysql://localhost:3306/mydatabase?useUnicode=true&characterEncoding=utf8

以上三种方式等效于在客户端同时执行三条命令:

SET character_set_client utf8;

SET character_set_connection utf8;

SET character_set_results utf8;

参考:

MySQL配置文件my.ini详解

你真的搞懂MySQL的字符集了吗?

MySQL字符集的不同级别和效果

深入理解MySQL字符集及校对规则(一)

MySQL的字符编码体系(一)——数据存储编码

MySQL-解析客户端SQL执行字符集参数设置

MySQL中的字符集与字符序

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

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

相关文章

web基础+HTTP协议+httpd详细配置

目目录录 一、Web基础1.1 HTML概述1.1.1 HTML的文件结构1.1.2 HTML中的部分基本标签 1.3 MIME1.4 URI 和 URL1.4 定义1.4.2 URI 和 URL 的区别 二、静态资源和动态资源2.1 静态资源2.2 动态资源 三、HTTP协议3.1 HTTP协议简介3.2 HTTP协议版本3.2 HTTP方法3.3 HTTP请求访问的完…

李宏毅机器学习笔记:结构学习,HMM,CRF

李宏毅机器学习笔记:结构学习,HMM,CRF 1、隐马尔可夫模型HMM1.1Sequence2Sequence1.2 HMM1.3 Viterbi算法1.3 HMM模型的缺点 1、隐马尔可夫模型HMM 1.1Sequence2Sequence 什么是Seq2Seq问题呢?简单来说,就是输入是一…

RTSP/Onvif视频服务器EasyNVR安防视频云服务调用接口录像会被自动删除的问题解决方案

EasyNVR安防视频云服务是基于RTSP/Onvif协议接入的视频平台,可支持将接入的视频流进行全平台、全终端的分发,分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等。平台丰富灵活的视频能力,可应用在智慧校园、智慧工厂、智慧水利等…

Python“牵手”京东商品详情数据采集方法,京东API申请步骤说明

京东平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范。 京东API接口是指通过编程的方式,让开发者能够通过HTTP协议直接访问京东平台的数据,包括商品信息、店铺信息、物流信息等,从而实现京东平台的数据开…

自动驾驶合成数据科普一:不做真实数据的“颠覆者”,做“杠杆”

前言: 在7月底的一篇文章中,九章智驾提到,数据闭环能力是自动驾驶下半场的“入场券”,这一观点在行业内引起了广泛共鸣。 在数据闭环体系中,仿真技术无疑是非常关键的一环。仿真的起点是数据,而数据又分为真…

回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图&#…

短视频seo源码矩阵系统开源---代码php分享

前言:短视频seo源码 短视频seo矩阵系统源码私有化部署 短视频seo源码 短视频seo矩阵系统源码私有化怎么部署? 首先我们来给大家普及一下什么是短视频seo矩阵系统?视频矩阵分为多平台矩阵与一个平台多账号矩阵,加上seo排名优化&…

EasyPOI 实战总结

EasyPOI实战总结 简介 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法 使用EasyPOI 环境搭建 # 1.引入相关依…

R包开发一:R与Git版本控制

目录 1.安装Git 2-配置Git(只需配置一次) 3-用SSH连接GitHub(只需配置一次) 4-创建Github远程仓库 5-克隆仓库到本地 目标:创建的R包,包含Git版本控制,并且能在远程Github仓库同步,相当于发布在Github。…

基于Spring Boot的游泳馆管理系统的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频: 基于Spring Boot的游泳馆管理系统的设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java spring…

R语言机器学习方法在生态经济学领域

近年来,人工智能领域已经取得突破性进展,对经济社会各个领域都产生了重大影响,结合了统计学、数据科学和计算机科学的机器学习是人工智能的主流方向之一,目前也在飞快的融入计量经济学研究。表面上机器学习通常使用大数据&#xf…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 四)

Observed装饰器和ObjectLink装饰器:嵌套类对象属性变化 上文所述的装饰器仅能观察到第一层的变化,但是在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数…

pycharm远程连接docker容器

pycharm远程连接docker容器 1.根据镜像创建容器2.进入容器3.修改容器的root密码4. 容器安装openssh-server和openssh-client5.修改SSH配置文件6.重启ssh服务7. 退出测试8.配置pycharm并连接docker容器9. 选择docker环境 1.根据镜像创建容器 sudo docker run -itd --nameconn_t…

【目标检测】“复制-粘贴 copy-paste” 数据增强实现

文章目录 前言1. 效果展示代码说明3. 参考文档4. 不合适点 前言 本文来源论文《Simple Copy-Paste is a Strong Data Augmentation Method for Instance Segmentation》(CVPR2020),对其数据增强方式进行实现。 论文地址:https:/…

uniapp国际化npm install vue-i18n报错

npm install vue-i18n //npmyarn add vue-i18n //yarn在vue2环境下,默认安装 npm install vue-i18n 的版本是 vue-i18n9.1.9,所以报错。 npm view vue-i18n versions --json 用以上命令查看版本: vue2建议5.0版本 npm install vue-i1…

认识Junit

1. 前言 2. Junit注解 2.1. 常用的注解 2.1.1. Test 表示当前方法是一个测试方法(不需要main来执行) Test void Test01() throws InterruptedException {System.out.println("测试用例1");WebDriver webDriver new ChromeDriver();webDriver.get("https:/…

【从零开始的rust web开发之路 二】axum中间件和共享状态使用

系列文章目录 第一章 axum学习使用 第二章 axum中间件使用 文章目录 系列文章目录前言一、中间件是什么二、中间件使用常用中间件使用中间件使用TraceLayer中间件实现请求日志打印自定义中间件 共享状态 前言 上篇文件讲了路由和参数相应相关的。axum还有个关键的地方是中间件…

ceph集群的扩容缩容

文章目录 集群扩容添加osd使用ceph-deploy工具手动添加 添加节点新节点前期准备新节点安装ceph,出现版本冲突 ceph-deploy增加节点 集群缩容删除osd删除节点 添加monitor节点删除monitor节点使用ceph-deploy卸载集群 实验所用虚拟机均为Centos 7.6系统,8…

sql2008 开启端口1433,进行远程连接SQL服务器

设置完成后,接着重启SQL服务器 注意本机测试的话,必须要关闭防火墙,如果是腾讯云或阿里云的话,必须开启1433端口。否则无法远程连接到SQL服务器的。 但是这里我们对于外网的项目,基本不会在客户端上直接用 这种模式去…

flutter get 命令行工具

mac终端执行: flutter pub global activate get_cli这个安装完以后会提示英文提示你要把一个 目录添加到mac环境变量中,下面的目录是你安装完以后提示你放到环境变量里的目录 export PATH"$PATH":"$HOME/.pub-cache/bin"mac13系统以后环境变量的2个文件如…