https://segmentfault.com/a/1190000018662023

MySQL使用时,有一件很痛苦的事情肯定是结果乱码。将编码格式都设置为UTF8可以解决这个问题,我们今天来说下为什么要这么设置,以及怎么设置。

MySQL字符格式

字符集

在编程语言中,我们为了防止中文乱码,会使用unicode对中文字符做处理,而为了降低网络带宽和节省存储空间,我们使用UTF8进行编码。对这两者有什么不同不够了解的同学,可以参考Unicode字符集和UTF8编码编码的前世今生这篇文章。

同样在MySQL中,我们也会有这样的处理,我们可以查看当前数据库设置的编码方式(字符集):

mysql> show variables like '%char%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.00 sec)

表中就是当前设置的字符集,先看不用关注的几个值:

  • character_set_filesystem | binary:文件系统上的存储格式,默认为binary(二进制)
  • character_set_system | utf8:系统的存储格式,默认为utf8
  • character_sets_dir | /usr/local/mysql/share/charsets/:可以使用的字符集的文件路径

剩下的几个就是日常影响读写乱码的参数了:
- character_set_client:客户端请求数据的字符集
- character_set_connection:从客户端接收到数据,然后传输的字符集
- character_set_database:默认数据库的字符集;如果没有默认数据库,使用character_set_server字段
- character_set_results:结果集的字符集
- character_set_server:数据库服务器的默认字符集

字符集的转换流程分为3步:

  1. 客户端请求数据库数据,发送的数据使用character_set_client字符集
  2. MySQL实例收到客户端发送的数据后,将其转换为character_set_connection字符集
  3. 进行内部操作时,将数据字符集转换为内部操作字符集:

    1. 使用每个数据字段的character set设定值
    2. 若不存在,使用对应数据表的default character set设定值
    3. 若不存在,使用对应数据库的default character set设定值
    4. 若不存在,使用character_set_server设定值
  4. 将操作结果值从内部操作字符集转换为character_set_results

字符序

说字符序之前,我们需要了解一点基础知识:

  • 字符(Character)是指人类语言中最小的表义符号。例如’A’、’B’等;
  • 给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符,这一数值就是字符的编码(Encoding)。例如,我们给字符’A’赋予数值0,给字符’B’赋予数值1,则0就是字符’A’的编码;
  • 给定一系列字符并赋予对应的编码后,所有这些字符和编码对组成的集合就是字符集(Character Set)。例如,给定字符列表为{‘A’,’B’}时,{‘A’=>0, ‘B’=>1}就是一个字符集;
  • 字符序(Collation)是指在同一字符集内字符之间的比较规则;
  • 确定字符序后,才能在一个字符集上定义什么是等价的字符,以及字符之间的大小关系;
  • 每个字符序唯一对应一种字符集,但一个字符集可以对应多种字符序,其中有一个是默认字符序(Default Collation)
  • MySQL中的字符序名称遵从命名惯例:以字符序对应的字符集名称开头;以_ci(表示大小写不敏感,case insensitive)、_cs(表示大小写敏感,case sensitive)或_bin(表示按编码值比较,binary)结尾。例如:在字符序“utf8_general_ci”下,字符“a”“A”是等价的;

因此字符序不同于字符集,用于数据库字段的相等或大小比较。我们查看MySQL实例设置的字符序:

mysql> show variables like 'collation%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

跟utf8对应的常用字符序是:utf8_unicode_ci/utf8_general_ci和utf8_bin等,那么他们的区别是什么呢?

  1. _bin是用二进制存储并比较,区别大小写,存储二进制内容时使用
  2. utf8_general_ci:校对速度快,但准确度稍差,使用中英文时使用
  3. utf8_unicode_ci:准确度高,但校对速度稍慢,使用德法俄等外语时使用

详细的区别可以参考 Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结

修改字符集和字符序

如果在MySQL连接时,出现了乱码的问题,那么基本可以确定是各个字符集/序设置不统一的原因。MySQL默认的latin1格式不支持中文,由于我们在中国,所以选择对中文和各语言支持都非常完善的utf8格式。所以,我们需要将需要关注的字符集和字符序都修改为utf8格式。

你也可以选择utf8mb4格式,这个格式支持保存emoji

MySQL乱码的原因和设置UTF8数据格式的更多相关文章

  1. Curl 采集乱码 gzip 原因及解决方案 utf-8

    用curl获取一个经过gzip压缩后的网页时返回乱码 原因大体就是服务器返回的Content-Encoding的值和网页的编码不同,造成curl解码出问题,直接将gzip或deflate编码的文件下载 ...

  2. 处理linux下面的mysql乱码问题(下面的utf8换成gb2312也是可以的)

    有时候因为编码需要修改mysql的编码,windows下修改有图文界面简单一些,linux大家就可以参考下面的方法   默认登录mysql之后可以通过SHOW VARIABLES语句查看系统变量及其值 ...

  3. mysql 中文出现?,设置utf8

    windows系统下的mysql: 1.找到mysql的配置文件:文件名可能不是my.ini(如my-default.ini),修改成my.ini. 打开配置文件,并编辑如下:(若是没有[client ...

  4. 10分钟学会理解和解决MySQL乱码问题

    在阅读本文之前,强烈建议对字符集编码概念还比较模糊的同学 阅读下博主之前对相关概念的一篇科普:十分钟搞清字符集和字符编码 本博客已经迁移至: http://cenalulu.github.io/ 为了 ...

  5. 理解和解决MySQL乱码问题【转】

    本文来自:http://www.cnblogs.com/cenalulu/p/4325693.html 要了解为什么会出现乱码,我们就先要了解从客户端发起请求,到MySQL存储数据,再到下次从表取回客 ...

  6. 理解和解决MySQL乱码问题

    本文将详细介绍MySQL乱码的成因和具体的解决方案 在阅读本文之前,强烈建议对字符集编码概念还比较模糊的同学 阅读下博主之前对相关概念的一篇科普:十分钟搞清字符集和字符编码 MySQL出现乱码的原因 ...

  7. mysql5.5字符集设置的一点变化(对于中文乱码问题,需要设置mysql字符集)

    工作中因为字符集问题没少头疼,还犯过一次错误,还好拯救及时,没有发生重大事故,唉,弄清楚点还是非常有必要的: 例如我的工作环境为CTR+redhat5+mysql5.5 在导入sql语句的时候必须要注 ...

  8. mysql保存中文乱码的原因和解决办法

    当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心.    也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类 ...

  9. 解决乱码的方法是,在执行SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集

    character-set-server/default-character-set:服务器字符集,默认情况下所采用的. character-set-database:数据库字符集. characte ...

随机推荐

  1. 严格次小生成树[BJWC2010]

    原文必点 原题链接 题目描述 给定一张\(N\) 个点$ M $条边的无向图,求无向图的严格次小生成树. 设最小生成树的边权之和为\(sum\),严格次小生成树就是指边权之和大于\(sum\)的生成树 ...

  2. less 分页显示文件内容

    1.命令功能 less 是more的增强版,可以分页显示文件内容,而且less打开文件的速度要比vi,more更快.less支持搜索功能,显示行号. 2.语法格式 less  option  file ...

  3. zencart批量评论插件Easy Populate CSV add reviews使用教程

    此插件在Easy Populate CSV 1.2.5.7b产品批量插件基础上开发,有1.3x与1.5x两个版本. zencart批量评论插件Easy Populate CSV add reviews ...

  4. Token认证的优势与劣势

    token 我们说的token,是指 访问资源的凭据 .使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录. 大致流程: 客户端使用用户名跟密码请求登录服务端收到请求,验证用户名与 ...

  5. R树-javascript代码实现过程分析(插入操作)

    R Tree 第一步,创建R树类. 构建一个RTree生成器.用以创建tree对象. 例子:var tree = new RTree(12) var RTree = function(width){ ...

  6. jquery中.each()方法遍历循环如何终止方法

    使用return false 终止循环 function checkStar(obj){ var flag=false; //获取本节点星级 var star = obj.getAttribute(& ...

  7. ubuntu16下安装MySQLdb

    2016年07月20日 10:37:04 tonydandelion2014 阅读数 3354更多 分类专栏: Python   1.使用pip安装 pip install mysql-python ...

  8. 第十一章 前端开发-bootstrap

    11.5.0 bootstrap 11.5.1 bootstrap的介绍和响应式 http://book.luffycity.com/python-book/95-bootstrap/951-boot ...

  9. Acwing-203-同余方程(扩展欧几里得)

    链接: https://www.acwing.com/problem/content/205/ 题意: 求关于x的同余方程 ax ≡ 1(mod b) 的最小正整数解. 思路: 首先:扩展欧几里得推导 ...

  10. 【JZOJ5605】【NOI2018模拟3.26】Arg

    题目描述 给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. 解题思路 如何求出一个序列的LIS? 对于二分的方法,每次插入一个数,将它放到第一个 ...