一.内容概述

在MySQL的使用过程中,了解字符集、字符序的概念,以及不同设置对数据存储、比较的影响非常重要。不少同学在日常工作中遇到的“乱码”问题,很有可能就是因为对字符集与字符序的理解不到位、设置错误造成的。

本文由浅入深,分别介绍了如下内容:

字符集、字符序的基本概念及联系

MySQL支持的字符集、字符序设置级,各设置级别之间的联系

server、database、table、column级字符集、字符序的查看及设置

应该何时设置字符集、字符序

二.字符集、字符序的概念与联系

在数据的存储上,MySQL提供了不同的字符集支持。而在数据的对比操作上,则提供了不同的字符序支持。

MySQL提供了不同级别的设置,包括server级、database级、table级、column级,可以提供非常精准的设置。

什么是字符集、字符序?简单的来说:

字符集(character set):定义了字符以及字符的编码。

字符序(collation):定义了字符的比较规则。

举个例子:

有四个字符:A、B、a、b,这四个字符的编码分别是A = 0, B = 1, a = 2, b = 3。这里的字符 + 编码就构成了字符集(character set)。

如果我们想比较两个字符的大小呢?比如A、B,或者a、b,最直观的比较方式是采用它们的编码,比如因为0 < 1,所以 A < B。

另外,对于A、a,虽然它们编码不同,但我们觉得大小写字符应该是相等的,也就是说 A == a。

这上面定义了两条比较规则,这些比较规则的集合就是collation。

同样是大写字符、小写字符,则比较他们的编码大小;

如果两个字符为大小写关系,则它们相等。

三、MySQL支持的字符集、字符序

MySQL支持多种字符集 与 字符序。

一个字符集对应至少一种字符序(一般是1对多)。

两个不同的字符集不能有相同的字符序。

每个字符集都有默认的字符序。

上面说的比较抽象,我们看下后面几个小节就知道怎么回事了。

1.查看支持的字符集

可以通过以下方式查看MYSQL支持的字符集。

方式一:

mysql> SHOW CHARACTER SET;

+----------+-----------------------------+---------------------+--------+

| Charset | Description | Default collation | Maxlen |

+----------+-----------------------------+---------------------+--------+

| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |

| dec8 | DEC West European | dec8_swedish_ci | 1 |

...省略

方式二:

mysql> use information_schema;

mysql> select * from CHARACTER_SETS;

+--------------------+----------------------+-----------------------------+--------+

| CHARACTER_SET_name | DEFAULT_COLLATE_name | DESCRIPTION | MAXLEN |

+--------------------+----------------------+-----------------------------+--------+

| big5 | big5_chinese_ci | Big5 Traditional Chinese | 2 |

| dec8 | dec8_swedish_ci | DEC West European | 1 |

...省略

当使用SHOW CHARACTER SET查看时,也可以加上WHERE或LIKE限定条件。

例子一:使用WHERE限定条件。

mysql> SHOW CHARACTER SET WHERE Charset="utf8";

+---------+---------------+-------------------+--------+

| Charset | Description | Default collation | Maxlen |

+---------+---------------+-------------------+--------+

| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |

+---------+---------------+-------------------+--------+

1 row in set (0.00 sec)

例子二:使用LIKE限定条件。

mysql> SHOW CHARACTER SET LIKE "utf8%";

+---------+---------------+--------------------+--------+

| Charset | Description | Default collation | Maxlen |

+---------+---------------+--------------------+--------+

| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |

| utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 |

+---------+---------------+--------------------+--------+

2 rows in set (0.00 sec)

2.查看支持的字符序

类似的,可以通过如下方式查看MYSQL支持的字符序。

方式一:通过SHOW COLLATION进行查看。

可以看到,utf8字符集有超过10种字符序。通过Default的值是否为Yes,判断是否默认的字符序。

mysql> SHOW COLLATION WHERE Charset = 'utf8';

+--------------------------+---------+-----+---------+----------+---------+

| Collation | Charset | Id | Default | Compiled | Sortlen |

+--------------------------+---------+-----+---------+----------+---------+

| utf8_general_ci | utf8 | 33 | Yes | Yes | 1 |

| utf8_bin | utf8 | 83 | | Yes | 1 |

...略

方式二:查询information_schema.COLLATIONS。

mysql> USE information_schema;

mysql> SELECT * FROM COLLATIONS WHERE CHARACTER_SET_name="utf8";

+--------------------------+--------------------+-----+------------+-------------+---------+

| COLLATION_name | CHARACTER_SET_name | ID | IS_DEFAULT | IS_COMPILED | SORTLEN |

+--------------------------+--------------------+-----+------------+-------------+---------+

| utf8_general_ci | utf8 | 33 | Yes | Yes | 1 |

| utf8_bin | utf8 | 83 | | Yes | 1 |

| utf8_unicode_ci | utf8_name | 192 | | Yes | 8 |

3.字符序的命名规范

字符序的命名,以其对应的字符集作为前缀,如下所示。比如字符序utf8_general_ci,标明它是字符集utf8的字符序。更多规则可以参考 官方文档。

MariaDB [information_schema]> SELECT CHARACTER_SET_name, COLLATION_name FROM COLLATIONS WHERE CHARACTER_SET\_name="utf8" limit 2;

+--------------------+-----------------+

| CHARACTER_SET_name | COLLATION_name |

+--------------------+-----------------+

| utf8 | utf8_general_ci |

| utf8 | utf8_bin |

+--------------------+-----------------+

2 rows in set (0.00 sec)

四.server的字符集、字符序

用途:当你创建数据库,且没有指定字符集、字符序时,server字符集、server字符序就会作为该数据库的默认字符集、排序规则。

如何指定:MySQL服务启动时,可通过命令行参数指定。也可以通过配置文件的变量指定。

server默认字符集、字符序:在MySQL编译的时候,通过编译参数指定。

character_set_server、collation_server分别对应server字符集、server字符序。

1.查看server字符集、字符序

分别对应character_set_server、collation_server两个系统变量。

mysql> SHOW VARIABLES LIKE "character_set_server";

mysql> SHOW VARIABLES LIKE "collation_server";

2.启动服务时指定

可以在MySQL服务启动时,指定server字符集、字符序。如不指定,默认的字符序分别为latin1、latin1_swedish_ci

mysqld --character-set-server=latin1 \

--collation-server=latin1_swedish_ci

单独指定server字符集,此时,server字符序为latin1的默认字符序latin1_swedish_ci。

mysqld --character-set-server=latin1

3.配置文件指定

除了在命令行参数里指定,也可以在配置文件里指定,如下所示。

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8

[mysqld]

collation-server = utf8_unicode_ci

init-connect='SET NAMES utf8'

character-set-server = utf8

4.运行时修改

例子:运行时修改(重启后会失效,如果想要重启后保持不变,需要写进配置文件里)

mysql> SET character_set_server = utf8 ;

5.编译时指定默认字符集、字符序

character_set_server、collation_server的默认值,可以在MySQL编译时,通过编译选项指定:

cmake . -DDEFAULT_CHARSET=latin1 \

-DDEFAULT_COLLATION=latin1_german1_ci

五.database的字符集、字符序

用途:指定数据库级别的字符集、字符序。同一个MySQL服务下的数据库,可以分别指定不同的字符集/字符序。

1.设置数据的字符集/字符序

可以在创建、修改数据库的时候,通过CHARACTER SET、COLLATE指定数据库的字符集、排序规则。

创建数据库:

CREATE DATABASE db_name

[[DEFAULT] CHARACTER SET charset_name]

[[DEFAULT] COLLATE collation_name]

修改数据库:

ALTER DATABASE db_name

[[DEFAULT] CHARACTER SET charset_name]

[[DEFAULT] COLLATE collation_name]

例子:创建数据库test_schema,字符集设置为utf8,此时默认的排序规则为utf8_general_ci。

CREATE DATABASE `test_schema` DEFAULT CHARACTER SET utf8;

2.查看数据库的字符集/字符序

有3种方式可以查看数据库的字符集/字符序。

例子一:查看test_schema的字符集、排序规则。(需要切换默认数据库)

mysql> use test_schema;

Database changed

mysql> SELECT @@character_set_database, @@collation_database;

+--------------------------+----------------------+

| @@character_set_database | @@collation_database |

+--------------------------+----------------------+

| utf8 | utf8_general_ci |

+--------------------------+----------------------+

1 row in set (0.00 sec)

例子二:也可以通过下面命令查看test_schema的字符集、数据库(不需要切换默认数据库)

mysql> SELECT SCHEMA_name, DEFAULT_CHARACTER_SET_name, DEFAULT_COLLATION_name FROM information_schema.SCHEMATA WHERE schema_name="test_schema";

+-------------+----------------------------+------------------------+

| SCHEMA_name | DEFAULT_CHARACTER_SET_name | DEFAULT_COLLATION_name |

+-------------+----------------------------+------------------------+

| test_schema | utf8 | utf8_general_ci |

+-------------+----------------------------+------------------------+

1 row in set (0.00 sec)

例子三:也可以通过查看创建数据库的语句,来查看字符集。

mysql> SHOW CREATE DATABASE test_schema;

+-------------+----------------------------------------------------------------------+

| Database | Create Database |

+-------------+----------------------------------------------------------------------+

| test_schema | CREATE DATABASE `test_schema` /*!40100 DEFAULT CHARACTER SET utf8 */ |

+-------------+----------------------------------------------------------------------+

1 row in set (0.00 sec)

3.database字符集、字符序是怎么确定的

创建数据库时,指定了CHARACTER SET或COLLATE,则以对应的字符集、排序规则为准。

创建数据库时,如果没有指定字符集、排序规则,则以

character_set_server、collation_server为准。

六.table的字符集、字符序

创建表、修改表的语法如下,可通过CHARACTER SET、COLLATE设置字符集、字符序。

CREATE TABLE tbl_name (column_list)

[[DEFAULT] CHARACTER SET charset_name]

[COLLATE collation_name]]

ALTER TABLE tbl_name

[[DEFAULT] CHARACTER SET charset_name]

[COLLATE collation_name]

1.创建table并指定字符集/字符序

例子如下,指定字符集为utf8,字符序则采用默认的。

CREATE TABLE `test_schema`.`test_table` (

`id` INT NOT NULL COMMENT '',

PRIMARY KEY (`id`) COMMENT '')

DEFAULT CHARACTER SET = utf8;

2.查看table的字符集/字符序

同样,有3种方式可以查看table的字符集/字符序。

方式一:通过SHOW TABLE STATUS查看table状态,注意Collation为utf8_general_ci,对应的字符集为utf8。

MariaDB [blog]> SHOW TABLE STATUS FROM test_schema \G;

*************************** 1. row ***************************

Name: test_table

Engine: InnoDB

Version: 10

Row_format: Compact

Rows: 0

Avg_row_length: 0

Data_length: 16384

Max_data_length: 0

Index_length: 0

Data_free: 11534336

Auto_increment: NULL

Create_time: 2018-01-09 16:10:42

Update_time: NULL

Check_time: NULL

Collation: utf8_general_ci

Checksum: NULL

Create_options:

Comment:

1 row in set (0.00 sec)

方式二:查看information_schema.TABLES的信息。

mysql> USE test_schema;

mysql> SELECT TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = "test_schema" AND TABLE\_name = "test_table";

+-----------------+

| TABLE_COLLATION |

+-----------------+

| utf8_general_ci |

+-----------------+

方式三:通过SHOW CREATE TABLE确认。

mysql> SHOW CREATE TABLE test_table;

+------------+----------------------------------------------------------------------------------------------------------------+

| Table | Create Table |

+------------+----------------------------------------------------------------------------------------------------------------+

| test_table | CREATE TABLE `test_table` (

`id` int(11) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

+------------+----------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

3.table字符集、字符序如何确定

假设CHARACTER SET、COLLATE的值分别是charset_name、collation_name。如果创建table时:

明确了charset_name、collation_name,则采用charset_name、collation_name。

只明确了charset_name,但collation_name未明确,则字符集采用charset_name,字符序采用charset_name对应的默认字符序。

只明确了collation_name,但charset_name未明确,则字符序采用collation_name,字符集采用collation_name关联的字符集。

charset_name、collation_name均未明确,则采用数据库的字符集、字符序设置。

七.column的字符集、排序

类型为CHAR、VARCHAR、TEXT的列,可以指定字符集/字符序,语法如下:

col_name {CHAR | VARCHAR | TEXT} (col_length)

[CHARACTER SET charset_name]

[COLLATE collation_name]

1.新增column并指定字符集/排序规则

例子如下:(创建table类似)

mysql> ALTER TABLE test_table ADD COLUMN char_column VARCHAR(25) CHARACTER SET utf8;

2.查看column的字符集/字符序

例子如下:

mysql> SELECT CHARACTER_SET_name, COLLATION_name FROM information_schema.COLUMNS WHERE TABLE_SCHEMA="test_schema" AND TABLE_name="test_table" AND COLUMN_name="char_column";

+--------------------+-----------------+

| CHARACTER_SET_name | COLLATION_name |

+--------------------+-----------------+

| utf8 | utf8_general_ci |

+--------------------+-----------------+

1 row in set (0.00 sec)

3.column字符集/排序规则确定

假设CHARACTER SET、COLLATE的值分别是charset_name、collation_name:

如果charset_name、collation_name均明确,则字符集、字符序以charset_name、collation_name为准。

只明确了charset_name,collation_name未明确,则字符集为charset_name,字符序为charset_name的默认字符序。

只明确了collation_name,charset_name未明确,则字符序为collation_name,字符集为collation_name关联的字符集。

charset_name、collation_name均未明确,则以table的字符集、字符序为准。

八.选择:何时设置字符集、字符序

一般来说,可以在三个地方进行配置:

创建数据库的时候进行配置。

mysql server启动的时候进行配置。

从源码编译mysql的时候,通过编译参数进行配置

1.方式一:创建数据库的时候进行配置

这种方式比较灵活,也比较保险,它不依赖于默认的字符集/字符序。当你创建数据库的时候指定字符集/字符序,后续创建table、column的时候,如果不特殊指定,会继承对应数据库的字符集/字符序。

CREATE DATABASE mydb

DEFAULT CHARACTER SET utf8

DEFAULT COLLATE utf8_general_ci;

2.方式二:mysql server启动的时候进行配置

可以添加以下配置,这样mysql server启动的时候,会对character-set-server、collation-server进行配置。

当你通过mysql client创建database/table/column,且没有显示声明字符集/字符序,那么就会用character-set-server/collation-server作为默认的字符集/字符序。

另外,client、server连接时的字符集/字符序,还是需要通过SET NAMES进行设置。

[mysqld]

character-set-server=utf8

collation-server=utf8_general_ci

3.方式三:从源码编译mysql的时候,通过编译参数进行设置

编译的时候如果指定了-DDEFAULT_CHARSET和-DDEFAULT_COLLATION,那么:

创建database、table时,会将其作为默认的字符集/字符序。

client连接server时,会将其作为默认的字符集/字符序。(不用单独SET NAMES)

shell> cmake . -DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci

九.写在后面

本文较为详细地介绍了MySQL中字符集、字符序相关的内容,这部分内容主要针对的是数据的存储与比较。其实还有很重要的一部分内容还没涉及:针对连接的字符集、字符序设置。

由于连接的字符集、字符序设置不当导致的乱码问题也非常多,这部分内容展开来讲内容也不少,放在下一篇文章进行讲解。

篇幅所限,有些内容没有细讲,感兴趣的同学欢迎交流,或者查看官方文档。如有错漏,敬请指出。

参考

mysql中charset()作用_Mysql系列(四) —— MySQL的Charset和Collation相关推荐

  1. delimiter在mysql中的作用_细细研究MySql中delimiter起到的作用_MySQL

    MySql中delimiter究竟可以起到些什么作用呢?可能不少人都有这样的疑惑,下文就为您介绍MySql中delimiter的作用,供您参考. MYSQL导出一个SQL后: DELIMITER $$ ...

  2. mysql中leave和_MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法

    本文主要向大家介绍了MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. DELIMITER ...

  3. MySQL中DQL查询数据——(四)

    MySQL中DQL查询数据--(四) 本篇博客,是个人根据 西部开源-秦疆老师的教学视频整理出的笔记,想看最详细的教学笔记和提供的SQL语句素材,请点击如下链接: https://www.cnblog ...

  4. mysql中基字符集_Mysql中的字符集

    1.字符集基础 在计算机的眼中只有0和1,但是在人类世界中却有上百种语言,每种语言又有成千上万的文字,那么如何在计算中表示人类世界中的这些文字呢? 在上个世纪60年代的时候,美国首先定义了一套规则,在 ...

  5. 重音符accent 符号在mysql中的作用

    重音符accent 符号在mysql中的作用 ` 是 MySQL 的转义符,避免和 mysql 的本身的关键字冲突,只要你不在列名.表名中使用 mysql 的保留字或中文,就不需要转义. 所有的数据库 ...

  6. mysql vip的作用_MySQL用户与权限的管理

    用户连接到MySQL,可以做各种查询,这都是MySQL用户与权限功能在背后维持着操作. 用户与数据库服务器交互数据,分为两个阶段: (1)你有没有权连接上来 (2)你有没有权执行本操作 1.你有没有权 ...

  7. MySql中的日期处理(适用于 MySQL 5.X 及以上版本)

    MySql中的日期处理(适用于 MySQL 5.X 及以上版本) 一.日期相关函数 date_format(date, format)MySQL日期格式化unix_timestamp()str_to_ ...

  8. mysql中的nan_使用python-cod将MySql列中的“NAN”值转换为NULL

    我通过python在MySql中编写/存储数据.如果MySql中的列数据包含"NAN",那么我如何处理它们.目前我知道如何处理空白或无值,但在这里我被卡住了.数据看起来像这样# f ...

  9. mysql null的作用_MySQL中对于NULL值的理解和使用教程

    NULL值的概念是造成SQL的新手的混淆的普遍原因,他们经常认为NULL是和一个空字符串''的一样的东西.不是这样的!例如,下列语句是完全不同的: ?12mysql>INSERT INTO my ...

最新文章

  1. 机器学习也能套模版:在线选择模型和参数,一键生成demo
  2. python PyQt5中文教程☞【第二节】PyQt5基本功能(创建窗口、应用程序图标、显示提示语、通过按钮关闭窗口、消息框(关闭窗口确认框)、窗口显示在屏幕中间【居中显示】)
  3. 极客马拉松JUNCTION✖️TIANJIN
  4. iOS GCD, 同步,异步,串行队列,并行队列,dispatch_group
  5. ajax创建对象,ajax创建对象
  6. 计算机网络实验进入实时模式,计算机网络实验1 PacketTrace基本使用.doc
  7. python根据列表绘制柱状图_python把一个列表画柱状图
  8. .net core 装了没生效_王者荣耀:辅助装出现惊天bug?辅助光环对自己无效?
  9. mysql config type_mysql_config_editor用法举例
  10. mysql cluster 子查询速度很慢
  11. 推荐支持 azw3 、epub 和 mobi 格式的阅读器:FBReader
  12. 两台服务器安装redis集群_两台服务器六节点redis集群环境搭建
  13. android view 前景色,Android开发中的一些小技巧
  14. 达梦数据库报网络通讯异常排查步骤
  15. VB代码窗口鼠标滚轮的使用
  16. MySql重装出错, Staring the server出错,日志3306 with user root with no password...
  17. Java面试题大全(2021版)
  18. Solidity 投票案例
  19. HQPlayer常见问题及解决方案
  20. 微信公众号历史数据采集和推文监控

热门文章

  1. 你最想去的城市有哪些?有哪些好的旅游城市?
  2. 弹力球c语言代码运行,弹力球游戏c语言代码
  3. 玩转Unity中的ML-Agents 机器学习(三):BallacceBall 案例训练
  4. Java中的三种输出print、printf、println
  5. 手写微信外卖cps小程序
  6. mysql smack_centos下安装和使用mysql测试工具super-smack
  7. 5个小众化的自媒体网站,速速收藏起来
  8. MESI高速缓存一致性协议
  9. 自动控制原理期末复习(Part2数学模型)
  10. SqlServer存储过程入门