Mysql中各种与字符编码集(character_set)有关的变量含义
mysql涉及到各种字符集,在此做一个总结。
字符集的设置是通过环境变量来设置的,环境变量和linux中的环境变量是一个意思。mysql的环境变量分为两种:session和global。session变量是仅在这次会话红中有效,在mysql中,一次会话可以理解为当前连接(除非reload,否则,一次会话就只有一次连接)。global环境变量则是确定了下一个新建立的session的变量值。使用show variables可以查看session值,如果要查看global的环境变量,则用show golbal variables语句。设置session环境变量用set variablename=value,设置global环境变量用set global variablename=value。
环境变量可以在服务启动后用set来设置,有些(主要是和数据库服务器有关的)也可以在启动服务时用命令行参数指定,还可以在配置文件中设置(my.cnf)。
mysql提供了四个等级的默认字符集以及比较规则,分别是服务器、数据库、表、列级别的。文档原话是:There are default settings for character sets and collations at four levels: server, database, table, and column. The description in the following sections may appear complex, but it has been found in practice that multiple-level defaulting leads to natural and obvious results.
一个字符集(character set)对应了一个默认的字符排序码规则(collation),当改变了一个等级的默认编码集时,与它同等级的默认字符排序规则也会变成该字符集对应的字符排序规则。
除了有这四个等级的默认字符编码和排序规则,还可以指定具体某一段字符的编码以及他的排序规则,指定字符编码是直接在他前面加上_utf8就可以了,指定排序规则在后面加上collate<排序规则>,如下这样: SELECT _utf8'abc' COLLATE utf8_danish_ci; 注意,如果有转义字符,那么转义字符是不会收字符串指定编码集影像的,而是和character_set_connection一致,如下:
mysql> SET NAMES latin1;
mysql> SELECT HEX('à\n'), HEX(_sjis'à\n');
返回的结果中\n仍然是换行符,因为\用的是latin1的字符集,在latin1中,它是换行符,而_sijis字符集中,\不是转移字符,而是6E。
结果:
+------------+-----------------+
| HEX('à\n') | HEX(_sjis'à\n') |
+------------+-----------------+
| E00A | E00A |
+------------+-----------------+
如果要查看所有的字符集,用show character set语句,查看所有的collation,用show collation语句。
字符集的设定不仅影响着存储,还会影响客户端和数据库服务器的通信,关于数据编码,mqsql中涉及到下面几个问题:
1、客户端发过来的数据使用什么字符集编码的?
2、接收到数据之后,应该用什么编码格式编码之后再将数据插入到mysql server中?
3、执行查询之后,查询出来的结果应该用什么编码集编码之后再返回?
4、数据库的各种表的数据,应该用什么字符集编码,以及它们用什么排序?
5.查询语句的字符串比较时,应该在哪一个标准里面来比较,比如:'Mueller' = 'Müller'是为真还是假?
6.数据库的各种元数据,包括表名、数据库名、密码、用户名、以及comment等,用什么字符集表示?
针对这四个问题,mysql就提供了不同的环境变量来进行跟踪,这些变量为:
|
变量名 |
含义 |
|
character_set_server |
默认的内部操作字符集 |
|
character_set_client |
客户端来源数据使用的字符集,也就是客户端发过来的查询语句使用的什么字符集 |
|
character_set_connection |
MySQL接受到用户查询后,按照character_set_client将其转化为character_set_connection设定的字符集。 |
|
character_set_results |
查询结果编码的字符集 |
|
character_set_database |
当前选中数据库的默认字符集 |
|
character_set_system |
系统元数据(字段名等)字符集 |
|
collation_connection |
执行字符比较时采用的编码规则 |
在mysql中,可以为数据库指定默认的字符编码,成为该数据库中每个新建表的默认字符编码集,但是对于已经建立的表则不受影响。在新建一个表时,也可以使用DEFUALT CHARACTER SET=xxx来指定表的字符编码。
在数据库的查询(select update insert)操作中,涉及到的字符编码有character_set_client, character_set_connnection, character_set_result三个变量,这是三个变量是需要建立连接之后进行设置的.
1、针对第一个问题,使用character_set_client环境变量来回答:
character_set_client ,这是用户告诉服务器,客户端发过来的SQL语句是用的什么字符集,要和客户端发出去的字节流采用的编码集一致,如果是shell,那么就是和shell的编码集一致,中文windows的cmd就是gbk。但是对于使用_utf8'xxx'标记的字符,则用标记的字符集解码。
2、针对第二个问题,使用character_set_connetion环境变量来回答:
character_set_connection ,MySQL server 接收到用户查询后,按照character_set_client将其转化为character_set_connection设定的字符集,一般就是所操作的表对应的编码集。
3、针对第三个问题,使用character_set_result环境变量来回答:
character_set_results , MySQL将存储的数据转换成character_set_results中设定的字符集发送给用户,客户端获取到的结果就是以这种形式编码的。
4.针对第四个问题,使用上面提到的四个等级的默认字符集以及排序规则,即character_set_server、character_set_database以及建立表时的DEFAULT CHARACTER SET=xxx和指定字段时的DEFAULT CHARACTER SET=xxx来回答:
character_set_server决定了服务器的默认编码,character_set_database决定了新建数据库的默认字符集,而数据库的字符集又决定了新建表的默认字符集,而表的字符集又决定了字段的默认字符集,如果没有通过DEFAULT CHARACTER SET=xxx来改变表的字符集,则新表就使用character_set_database指定的字符集。
5.针对第五个问题,使用collation_connection来回答:
collation_connection变量制定了比较的规则。collation_connection的值得形式如下:字符集_语言_ci(大小不写敏感) 或字符集_语言_cs(大小写敏感),像中文这样的,没有大小写,所以只能是ci,比如set collatioin_connection=gbk_chinese_ci。就是设置成中文字典的排序规则。除了按具体语言排序,还可以按照二进制的位置排序,比如utf8_bin。
character_set_connection和collatioin_connection是一体的,设置了character_set_connection之后,collation_connection会跟着变成对应的默认排序规则,反之亦然。如果要显示的设置排序规则,可以用 SET NAMES 'charset_name' COLLATE 'collation_name' 。
但是如果查询语句的字符串和表的字段比较,则collation_connection不适用,因为表的字段有它自己的字符排序规则,而它自己的排序规则优先级高于collation_connection。
6.针对第六个问题,使用character_set_system来回答:
character_set_system表示元数据的字符集,默认就是utf8,而且不要去更改它,否则,因为类似于用户名密码这种东西,可能用各种奇葩的字符去表示,只有utf8能够容纳它们。如果变成了别的字符集,那么用户名和密码就不能用你想要的字符去表示了。需要注意的是,这个character_set_system也好,character_set_dababase、character_set_server也好,都指标是在数据库内部的保存格式,而不是返回到客户端的编码格式,返回到客户端的结果都会转化为character_set_results指定的字符集之后再返回,官方文档原话是“Storage of metadata using Unicode does not mean that the server returns headers of columns and the results of DESCRIBE functions in the character_set_system character set by default. When you use SELECT column1 FROM t, the name column1 itself is returned from the server to the client in the character set determined by the value of the character_set_results system variable, which has a default value of latin1.”。
另外,如果要临时设置返回值的编码,可以用set names charset_name'来临时改变character_set_results以及其他相关变量的值为charset_name。set names 'charset_name'等价于下面三条语句的结合:
SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;
SET CHARACTER SET和 SET NAMES 很像,但是是把 character_set_connection 和 collation_connection 分别设置为 character_set_database 和 collation_database一样,SET CHARACTER SET 等同于以下三条语句的结合。charset_name
SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET collation_connection = @@collation_database;
所以,set character set 'charset_name'要更常用。
顺便提一句,mysql的错误日志意识utf8格式产生的,但是如果把它输出到客户端,它就会转场character_set_results的编码格式再传到客户端(所有传到客户端的东西都会转码成character_set_results的)。
还可以加入启动参数skip-character-set-client-handshake来使客户端的编码和数据库保持一致。
通常,客户端的字符集可以通过操作系统来获取,从而使得字符集的分配和客户端一致。
参考:1、Connection Character Sets and Collations
3、What are character sets and collations
5、Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结
Mysql中各种与字符编码集(character_set)有关的变量含义的更多相关文章
- mysql中设置默认字符编码为utf-8
使用过Linux的同志就知道,在Linux下安装mysql,尤其是使用yum安装的时候,我们是没法选择其默认的字符编码方式.这个就是一个比较头痛的问题,如果Linux数据库中使用到中文的时候,乱码问题 ...
- mysql字符编码集(乱码)问题解决
1.创建数据库 CREATE DATABASE `test` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; 创建表 CREATE TABLE tp_w ...
- Java web应用中的常见字符编码问题的解决方法
以下是 Java Web应用的常见编码问题 1. html页面的编码 在web应用中,通常浏览器会根据http header: Content-type的值来决定用什么encoding, 比如遇到Co ...
- [转载]Java web应用中的常见字符编码问题的解决方法
以下是 Java web应用的常见编码问题 1. html页面的编码 在web应用中,通常浏览器会根据http header: Content-type的值来决定用什么encoding, 比如遇到Co ...
- Python 2中万恶的字符编码
Python2中如果文件存在中文,必须要指定#-*- coding:utf8 -*-或#coding:utf8,否则会报错.那这是为什么呢? 一.原理解析 我们知道,在计算机发展初期,计算机只能识别字 ...
- MySQL查看和修改字符编码
MySQL的默认编码是Latin1,不支持中文,要支持中午需要把数据库的默认编码修改为gbk或者utf8. 1.需要以root用户身份登陆才可以查看数据库编码方式(以root用户身份登陆的命令为:&g ...
- MySQL学习笔记之一---字符编码和字符集
前言: 一般来说,出现中文乱码,都是客户端和服务端字符集不匹配导致的原因. (默认未指定字符集创建的数据库表,都是latinl字符集, 强烈建议使用utf8字符集) 保证不出现乱码的思想:保证客户 ...
- mysql 5.5 修改字符编码
修改/etc/mysql/my.cnf 配置文件: 最后重启mysql 服务,再查看: 编码已经改好了,可以支持中文字符编码了.
- mysql命令行修改字符编码
1.修改数据库字符编码 mysql> alter database mydb character set utf8 ; 2.创建数据库时,指定数据库的字符编码 mysql> create ...
随机推荐
- 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架 - LinFx
LinFx 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架,遵循领域驱动设计(DDD)规范约束,提供实现事件驱动.事件回溯.响应式等特性的基础设施.让开发者享受到正真意义的面向对象 ...
- C# LINQ(5)
目前都是说的单数据差距,如果多数据进行查询LINQ该如何呢? 那么LINQ就应该使用关键字 join on equals 现有代码: static void Main(string[] args) { ...
- 「BZOJ 3123」「SDOI 2013」森林「启发式合并」
题意 你有一个森林,你需要支持两个操作 查询两个结点路径上权值第\(k\)小 两个点之间连一条边 强制在线,结点数\(\leq 8\times 10^4\) 题解 如果可以离线,这就是一个主席树板子题 ...
- BZOJ2668:[CQOI2012]交换棋子(费用流)
题目描述 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. 输入输出格式 输入格式: 第一行 ...
- iOS 开发之 GCD 不同场景使用
header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...
- [Swift]八大排序算法(三):选择排序 和 简单选择排序
排序分为内部排序和外部排序. 内部排序:是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 外部排序:指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存 ...
- UML之用例图详解
原文链接:https://blog.csdn.net/mj_ww/article/details/53020080 UML,即Unified Model Language,统一建模语言.百度百科对他的 ...
- java 读取excel 2007 .xlsx文件 poi实现
工作需要读取excel里面的行内容,使用java实现较为简单. 在最开始,尝试使用 jxl-2.6.12 来实现读取excel 的行内容.但是按照网上的方法,程序根本无法正确处理文件流.经过谷姐的一番 ...
- 老男孩Day16作业:登录、注册、后台管理页面(动态)
一.作业需求: 1.后台管理主界面(左边菜单框.(全选.反选)框.返回顶部按钮) 2.老男孩登录.注册页面 二.博客地址:https://www.cnblogs.com/catepython/p/93 ...
- Effective Java 3rd.Edition 翻译
推荐序 前言 致谢 第一章 引言 第二章 创建和销毁对象 第1项:用静态工厂方法代替构造器 第2项:遇到多个构造器参数时要考虑使用构建器 第3项:用私有构造器或者枚举类型强化Singleton属性 第 ...