目录
字符集... 1
mysql中的字符集和校对规则... 1
转换函数... 4
字符集是一个系统所支持的所有抽象字符的集合。
字符编码是将字符转换为特定的二进制序列,以便计算机识别。
编码字符集就是一种规则,它以特定的字符编码方案将字符转化为计算机能够识别的二进制码。通常所说的字符集就是指编码字符集。因为不同符集使用的编码方式不同,所以导致了不同字符集之间转换时会出现乱码。比如有两个字符集char1和char2,,在char1中,我们规定a(0001),b(0010),?(1111);在char2中,规定a(0101),c(1001),?(1111),这时如果需要在char1和char2之间进行转换,就有会出现问题。char1中的编码0001对应的字符是a,在转换为char2时,要将其编码为0101;对于char1中的1111,转换为char2时,其数值不变;而对于char1中的0010,其对应的字符b,但在char2中没有对应的字符,所以理论上无法转换,对于这类无法转换的情况,我们可以将它们统一转换为目标字符集中的一个特殊字符(“替换字符”),在这里我们可以将?作为替换字符,这时b就转换成?,出现了信息丢失和乱码。同样的道理,当将char2中的字符c转换为char1时,也会出现信息丢失。就是说,在字符集转换的过程中,如果源字符集中的某个字符在目标字符集中没有定义,将会出现信息丢失(乱码)。
1) MySQL字符集包括字符集(characterset)和校对规则(collation)两个概念。字符集用来定义mysql存储字符的编码规则。校对规则用来指定在字符集内部,字符的比较规则,如大小写不敏感、大小写敏感、二元(binary全部可能的规则中最简单的校对规则)。
2) SHOW CHARACTER SET;查看mysql支持的字符集和相应字符集的默认校对规则;
SHOW COLLATION;查看mysql支持的校对规则;
SHOW VARIABLES LIKE 'character%';查看当前状态字符集的设置情况;
SHOW GLOBAL VARIABLES LIKE ‘character%’;查看全局字符集的设置;
SHOW VARIABLES LIKE 'collation%';查看校对规则的设置,也可以通过查看datadir/db_name/db.opt文件来查看当前数据库的默认字符集和校对规则;
SHOW COLLATION LIKE ‘latin1%’;查看latin1字符集的校对规则。
SHOW CREATE DATABASE db_name;查看db_name数据库的字符集。
SHOW CREATE TABLE\G;查看表和列的字符集。
SHOW FULL COLUMNS FROM table_name FROMdb_name;查看列的详细信息。
3) mysql中的字符集和校对规则
MySQL中字符集和校对规则有4个级别的默认设置:服务器及、数据库级、表级和列级。
查看mysql的字符集设置:
mysql>show variables like 'character%';
+--------------------------+----------------------------+
|Variable_name | Value |
+--------------------------+----------------------------+
|character_set_client |utf8 | 客户端字符集
|character_set_connection | utf8 | 连接字符集
|character_set_database | latin2 | 数据库级字符集
|character_set_filesystem |binary | 文件系统字符集
|character_set_results |utf8 | 查询结果字符集
|character_set_server |latin1 | 服务器及字符集
| character_set_system |utf8 | 数据库元数据字符集(数据库的定义内容,列名、数据库名、用户名、版本、SHOW的内容、information_schema的内容)
|character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows inset (0.00 sec)
服务器级字符集和校对规则
启动时指定:
# mysqld –-user=root –character-set-server=latin1–collation-server=latin1_swedish_ci
#user指的是系统用户,不是mysql授权表中的用户. 如果是root用户,则强制使用此参数。测试结束后在datadir目录下执行 chown mysql:mysqlmysql-bin*。[①]注释
配置文件中指定:
shell>vi /etc/my.cnf #在[mysqld]下面添加default-character-set=latin1
#新版本的mysql为character_set_server=latin1
(重)编译时指定:
shell>./configure –with-charset=latin1 –with-collation=latin1_swedish_ci
运行时更改:
mysql>set global character_set_server=latin2; #global作用于新的连接,重启服务后失效
数据库级字符集和校对规则
数据库级字符集可以在CREATE DATABASE时指定,也可以使用ALTER DATABASE修改默认的字符集和校对规则。如果在CREATE DATABASE时没有指定默认的字符集和校对规则,这时会采用服务器的默认字符集和校对规则。[②]注释。也可以通过编辑datadir/db_name/db.opt文件来设置对应数据库的默认字符集和校对规则。
表级字符集和校对规则
CREATE TABLE时指定:
mysql>createtable t_charset(
>id int(3) auto_increment,
>name char(5),
>primary key(id))
>character set latin2
>collate latin2_general_ci;
QueryOK, 0 rows affected (0.00 sec)
使用ALTER TABLE更改:
mysql>altertable t_charset
>character set latin1
>collate latin1_swedish_ci;
如果建表时没有指定默认字符集和校对规则,系统会自动使用数据库紧急的默认设置。
列级字符集和校对
CREATE TABLE时指定:
mysql>createtable t_charset1(
>col1varchar(5)
>character set latin1
>collatelatin1_general_ci);
#int类型的列无法指定字符集类型
ALTER TABLE修改列的字符集:
mysql>alter table t_charset1
>change col1 col2char(10)
>character set latin1
>collationlatin1_general_ci;
如果没有指定 列字符集,则使用表字符集和校对规则的默认值。
连接字符集和校对
每个客户端都有一个与链接相关的字符集和校对规则。客户端登录到服务器所做的事情称为一个链接。客户端发送SQL语句,如查询,通过连接发送到服务器。服务器通过连接发送相应给客户端,如结果集。对于客户端连接,会涉及到与服务器之间字符集转换的问题,这些问题提由相应的系统变量来解决:
ü 当查询离开客户端后,在查询中使用哪种字符集:character_set_client指定。
ü server接收到查询后,转换为哪种字符集:character_set_connection和collation_connection指定。server将客户端发送的语句从character_set_client转换为character_set_connection。collation_connection对于比较字面值很重要。列值的比较会使用具有更高优先级的列校对规则。
ü server将结果集发送到客户端之前,转换为哪种字符集:character_set_results指示server返给client的结果集使用的字符集.包括结果数据,如列值,结果元数据。
设置连接字符集和校对:
ü SET NAMES ‘charset_name’;指定客户端发送的SQL语句使用的字符集、结果集的字符集、连接的字符集。set names ‘x’与这三个语句等价:
mysql>set character_set_client= x ;
mysql>setcharacter_set_results = x;
mysql>setcharacter_set_connection = x;
ü SET CHARACTER SET charset_name; 与这三个语句等价:
mysql>setcharacter_set_client = charset_name;
mysql>setcharacter_set_results=charset_name;
mysql>setcharacter_set_connection=@@character_set_database;
默认情况client、results、connection字符集使用操作系统LANG变量设置的字符集。如果在my.cnf配置文件中指定了[client]的default-character-set,则优先使用客户端字符集。
CONVERT()提供不同字符集之间转换数据的功能。
语法:CONVERT (expr USING transcoding_name);
例子:mysql>selectconvert(_latin1’Mumu’ USING utf8);
CAST()提供不同数据类型之间的转换
语法:CAST(char_string AS data_type CHARACTER SET charset_name)
# 将char_string转换为data_type的数据类型,字符集为charset_name
例子:mysql >select cast(_latin1’test’ as char(2) character set utf8);
[①] 我们知道每次重启mysql服务都会创建一个bin日志文件(datadir/mysql-bin.nnnnnn)。正常情况下启动数据库的系统用户为安装数据库时默认创建的mysql,启动mysql服务时创建的bin日志文件的所有者和组也是mysql,而现在启动mysqld服务指定了系统用户--user=root,生成的bin日志文件的所有者和所属组就变成了对应的root用户。这样就会导致无法以常规方式启动mysql数据库,比如service mysql start会提示server quit without updating PID file启动失败,err日志中提示无法找到最新的bin日志(mysql-bin.数字最大的,这与mysql-bin.index有关)。
[②] 我们知道如果使用SET GLOBAL character_set_server=latin2更改了全局系统变量,更改效果将作用于新连接,就是说如果具有create database权限的新session连接到mysql服务器,并且create database时没有指定字符集和校对规则,那么将会使用set global character_set_server中指定的字符集latin2和对应的校对规则,而不是服务器默认的字符集latin1。