设为首页 加入收藏

TOP

MySQL字符集编码(二)
2015-07-24 10:26:00 来源: 作者: 【 】 浏览:2
Tags:MySQL 字符集 编码
cter_set_server指定的编码.而如果我们使用"create database t2",则通过"show create database t2"可以看到t2的编码为character_set_server定的编码.

同理,mysql表也可以有自己独立的编码,在创建表的时候可以指定,如果没有指定,则默认采用数据库的编码.比如我们再之前的数据库t1创建表t11,"create table t11(i int) character set utf8",则表t11的编码为utf8,如果不指定编码则编码为数据库t1的编码gbk.

此外,mysql表中的字段也可以有自己的编码,如果不指定字段编码,则字段编码与表的编码一致.

3.MySQL连接字符集

前面谈到的编码内容基本都不会产生乱码问题,mysql中容易产生乱码的地方在character_set_client, character_set_connection, character_set_results这三个变量的设定.可以简单的通过set names utf8或者charset utf8命令来一次设置这三个参数.

刚刚接触这几个变量的时候我完全没有看懂,后来查找了不少资料,姑且算是理解了一点,当然也可能是错的,因为没有看过mysql源码,具体的原理还是请大神们指教.

从文档中的解释来看,mysql连接字符集转换主要包括下面三个步骤:

  • 1.character_set_client是客户端发送过来的sql语句的编码,因为服务端本身并不知道客户端的sql语句的编码是什么,所以是以这个变量作为客户端sql语句的初始编码.而服务端接收到sql语句后,则会将sql语句转换为character_set_connection指定的编码(注意,对于字面值字符串,如果前面有introducer标记如latin1或utf8,则不会进行这一步转换).转换完成,才会真正执行sql语句.
  • 2.进行内部操作前将sql语句中的数据从character_set_connection转换为数据表中相应字段的编码.
  • 3.将操作结果从内部字符集编码转换为character_set_results编码.

    更加详细的转换过程如下:

    Client program sends SQL statement

    |

    | Encoding: A, defined as "character_set_client"

    v

    MySQL server - Convertion from encoding A to encoding B

    |

    | Encoding: B, defined as "character_set_connection"

    v

    MySQL server - Execution to store data

    MySQL server - Conversion from encoding B to encoding C

    |

    | Encoding: C, defined by text column encoding

    v

    MySQL server - Storage

    ...

    MySQL server - Storage

    |

    | Encoding: C, defined by text column encoding

    v

    MySQL server - Execution to fetch data

    MySQL server - Convertion from encoding C to encoding D

    |

    | Encoding: D, defined as "character_set_results"

    v

    Client program receives result set

    接下来就实例分析下mysql可能乱码的情况以及我认为的原因,不对之处请指出.

    4.MySQL乱码实例分析

    4.1 问题实例

    我们创建一个测试的数据库db1,数据库编码为latin1,注意当前我的机器的终端编码为zh_CN.UTF-8,数据库的编码设定如下所第1部分所示,然后中db1中创建一个表test,sql语句如下:

    CREATE TABLE `test` (

    `gbk` varchar(2) CHARACTER SET gbk DEFAULT NULL,

    `utf8` varchar(2) CHARACTER SET utf8 DEFAULT NULL,

    `latin_utf8` varchar(6) DEFAULT NULL

    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

    注意到我们的表的编码是latin1,而表中三个字段的编码各不相同,分别为gbk编码,utf8编码以及latin1编码.之所以这样创建正是为了验证mysql字符集编码的转换过程.好了,重点来了,现在我们在mysql客户端执行:

    mysql> insert into test values("中文", "中文", "中文");

    Query OK, 1 row affected, 1 warning (0.00 sec)

    安装了mysql的筒子可以测试下,在mysql没有开启strict模式的时候,这个插入语句会报一个警告,内容如下:

    mysql> show warnings;

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

    | Level | Code | Message |

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

    | Warning | 1366 | Incorrect string value: '\xE4\xB8\xAD\xE6\x96\x87' for column 'latin_utf8' at row 1 |

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

    我们可以先select看看test表中的内容:

    mysql> select * from test;

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

    | gbk | utf8 | latin_utf8 |

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

    | 中文 | 中文 | ?? |

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

    我们还可以查看下test表中实际存储的内容:

    mysql> select hex(gbk), hex(utf8), hex(latin_utf8) from test;

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

    | hex(gbk) | hex(utf8) | hex(latin_utf8) |

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

    | D6D0CEC4 | E4B8ADE69687 | 3F3F |

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

    可以发现直接select查看的时候latin_utf8字段乱码了,而通过hex函数查看发现原来latin_utf8字段存储的内容有问题. 出现这个问题的原因就是编码转换过程出了错,按照之前

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇MySQL中数据表的查操作 下一篇Canrenametablebutcannottruncate..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·bios设置按什么选择 (2025-12-26 17:20:08)
·知乎 - 知乎 (2025-12-26 17:20:04)
·http://和www.前缀网 (2025-12-26 17:20:01)
·Python爬虫教程(从 (2025-12-26 16:49:14)
·【全269集】B站最详 (2025-12-26 16:49:11)