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 ...
随机推荐
- Boosting and Its Application in LTR
1 Boosting概述 2 Classification and Regression Tree 3 AdaBoost 3.1 算法框架 3.2 原理:Additive Modeling 4 Gra ...
- ubuntu 下安装ffmpeg
FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视 频的完整解决方案.它包含了非常先进的音频/视频编解码库 ...
- Android 监听事件
安卓中监听事件的三种实现方式 1.匿名内部类的实现方式 2.独立类的实现方式 3.实现接口方式实现 一.匿名内部类的实现 1.首先声明一个Button //声明一个Button private But ...
- Lua入门(一)
嵌入式语言 作为一门扩展式语言,Lua 没有 "main" 程序的概念: 它只能 嵌入 一个宿主程序中工作, 该宿主程序被称为 被嵌入程序 或者简称 宿主 . 宿主程序可以调用函数 ...
- L - Ch’s gift HDU - 6162
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- Resurrectio-capserjs的自动化脚本录制工具
[根据github上的文档说明整理] Phantom下的任何操作都可以录制 Resurrectio是一个Chrome插件,他可以记录浏览器的操作,并转化成对应的casperjs脚本 Resurrect ...
- Difference **面向过程(或者叫结构化)分析方法**面向对象分析方法
面向过程和面向对象的区别 面向过程是分析出解决问题所需要的步骤,然后一步步实现,面向对象是把构成问事件分解成各个对象,建立对象的目的是为了描述某个事物在整个解决问题的步骤中的行为. 可以说面向对象是从 ...
- 5、用Numpy实现结构体
1.结构数组: 在C语言中我们可以通过struct关键字定义结构类型,结构中的字段占据连续的内存空间,每个结构体占用的内存大小都相同,因此可以很容易地定义结构数组.和C语言一样,在NumPy中也很容易 ...
- 多线程 GCD 的使用
参考:http://www.jianshu.com/p/2d57c72016c6 GCD 的两个核心概念: 队列 与 任务 一.队列 队列分为串行队列和并发队列, 队列的作用是管理开发者提交的任务,在 ...
- C++_类继承6-继承和动态内存分配
如果基类使用动态内存分配,并重新定义赋值和复制构造函数,这将怎样影响派生类的实现?这个问题的答案取决于派生类的属性.如果派生类也使用动态内存分配,那就需要注意学习新的小技巧. 派生类不适用new // ...