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 ...
随机推荐
-
DS28E01芯片解密DS28E01-100单片机解密多少钱?
DS28E01芯片解密DS28E01-100单片机解密多少钱? DS28E01-100将1024位EEPROM与符合ISO/IEC 10118-3安全散列算法(SHA-1)的质询响应安全认证结合在一起 ...
-
定时5秒之后驻留在元素ID为content元素的内容
如果我只能刷新一个特定的页面的一部分,这将是很大的,例如:仪表盘上的交通灯显示系统状态. 这是很容易通过使用jQuery JavaScript库,只刷新页面的一部分.一旦我们纳入我们的页面的jQuer ...
-
angularjs的ng-repeat指令下的scope作用域
ng-repeat指令在迭代的时候,每次迭代都会创建一个新的scope,比如下面的代码: <div ng-repeat="list in lists" ng-controll ...
-
pg_stat_statements
Functions pg_stat_statements_reset() returns void pg_stat_statements_reset discards all statistics g ...
-
01.JSP基础语法
本章主要讲解Java Web与JSP的入门内容,适合有JSP或Java Web基础的读者学习. 1.Web应用与web.xml文件 (1)Java Web应用程序的结构 Java We ...
-
Java集合中对象排序
集合中的对象排序需求还是比較常见的.当然我们能够重写equals方法,循环比較:同一时候Java为我们提供了更易使用的APIs.当须要排序的集合或数组不是单纯的数字型时,通常能够使用Comparato ...
-
beforeunload
<!DOCTYPE html> <html> <head> <title>BeforeUnload Event Example</title> ...
-
centos 7 运行Quartus ii 17.0 标准版,下载程序时遇到错误error (209053): unexpected error in jtag server -- error code 89
对于错误error (209053): unexpected error in jtag server -- error code 89,它产生的原因在于,在linux系统下,Quartus ii的驱 ...
-
ajax常用实例代码总结新手向参考(一)
http的交互方法有四种:get.post.put(增加数据).delete(删除数据) put和delete实现用的是get和post get方式 页面不能被修改,只是获取查询信息.但是提交的数 ...
-
[LeetCode] Cut Off Trees for Golf Event 为高尔夫赛事砍树
You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-nega ...