charset,即字符集。

  collation,用于指定数据集如何排序,以及字符串的比对规则,即排序规则。

  prefix,即数据库里表使用的前缀。

/****************************************************************************************/

  基本概念

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

  1. <character set>_<language/other>_<ci/cs>

  2. <character set>_bin

  以_ci(表示大小写不敏感)、_cs(表示大小写敏感)或_bin(表示按编码值比较)结尾。例如:在字符序“utf8_general_ci”下,字符“a”和“A”是等价的;

  • 系统变量:
  – character_set_server:默认的内部操作字符集
  – character_set_client:客户端来源数据使用的字符集
  – character_set_connection:连接层字符集
  – character_set_results:查询结果字符集
  – character_set_database:当前选中数据库的默认字符集
  – character_set_system:系统元数据(字段名等)字符集
  – 还有以collation_开头的同上面对应的变量,用来描述字符序。

  • 用introducer指定文本字符串的字符集:
  – 格式为:[_charset] ’string’ [COLLATE collation]
  – 例如:
         SELECT _latin1 ’string’;
         SELECT _utf8 ‘你好’ COLLATE utf8_general_ci;
  – 由introducer修饰的文本字符串在请求过程中不经过多余的转码,直接转换为内部字符集处理。

  MySQL中的字符集转换过程

    1. MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection;
    2. 进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:
         - 使用每个数据字段的CHARACTER SET设定值;
         - 若上述值不存在,则使用对应数据表的DEFAULT CHARACTER SET设定值(MySQL扩展,非SQL标准);
         - 若上述值不存在,则使用对应数据库的DEFAULT CHARACTER SET设定值;
         - 若上述值不存在,则使用character_set_server设定值。

    3. 将操作结果从内部操作字符集转换为character_set_results。

  产生乱码的问题:
          a 我们的字段没有设置字符集,因此使用表的数据集
          b 我们的表没有指定字符集,默认使用数据库存的字符集
          c 我们的数据库在创建的时候没有指定字符集,因此使用character_set_server设定值
          d 我们没有特意去修改character_set_server的指定字符集,因此使用mysql默认
          e mysql默认的字符集是latin1,因此,我们使用了latin1字符集,而我们character_set_connection的字符集是UTF-8,插入中文乱码也再所难免了。

  使用MySQL字符集时的建议
      • 建立数据库/表和进行数据库操作时尽量显式指出使用的字符集,而不是依赖于MySQL的默认设置,否则MySQL升级时可能带来很大困扰;
      • 数据库和连接字符集都使用latin1时,虽然大部分情况下都可以解决乱码问题,但缺点是无法以字符为单位来进行SQL操作,一般情况下将数据库和连接字符集都置为utf8是较好的选择;
   
  • 使用mysql
CAPI(mysql提供C语言操作的API)时,初始化数据库句柄后马上用mysql_options设定
MYSQL_SET_CHARSET_NAME属性为utf8,这样就不用显式地用SET
NAMES语句指定连接字符集,且用mysql_ping重连断开的长连接时也会把连接字符集重置为utf8;
      • 对于mysql PHP API,一般页面级的PHP程序总运行时间较短,在连接到数据库以后显式用SET NAMES语句设置一次连接字符集即可;但当使用长连接时,请注意保持连接通畅并在断开重连后用SET NAMES语句显式重置连接字符集。

  其他注意事项
      • my.cnf中的default_character_set设置只影响mysql命令连接服务器时的连接字符集,不会对使用libmysqlclient库的应用程序产生任何作用!
      • 对字段进行的SQL函数操作通常都是以内部操作字符集进行的,不受连接字符集设置的影响。
      • SQL语句中的裸字符串会受到连接字符集或introducer设置的影响,对于比较之类的操作可能产生完全不同的结果,需要小心!

  MySQL默认字符集
  MySQL对于字符集的指定可以细化到一个数据库,一张表,一列.传统的程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置。

  (1)编译MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;

  (2)安装MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;

  (3)启动mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的配置,此时 character_set_server 被设定为这个默认的字符集;

  (4)安装 MySQL选择多语言支持,安装程序会自动在配置文件中把default_character_set 设置为 UTF-8,保证缺省情况下所有的数据库所有表的所有列的都用 UTF-8 存储。

  修改默认字符集
  (1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值,
       如    default-character-set = utf8
              character_set_server =  utf8
       修改完后,重启mysql的服务
  (2) 还有一种修改字符集的方法,就是使用mysql的命令
     mysql> SET character_set_client = utf8 ;
     mysql> SET character_set_connection = utf8 ;
     mysql> SET character_set_database = utf8 ;
     mysql> SET character_set_results = utf8 ;
     mysql> SET character_set_server = utf8 ;
     mysql> SET collation_connection = utf8 ;
     mysql> SET collation_database = utf8 ;
     mysql> SET collation_server = utf8 ;

  设置了表的默认字符集为utf8并且通过UTF-8编码发送查询,存入数据库的仍然是乱码。那connection连接层上可能出了问题。解决方法是在发送查询前执行一下下面这句: SET NAMES 'utf8';它相当于下面的三句指令:
  SET character_set_client = utf8;
  SET character_set_results = utf8;
  SET character_set_connection = utf8;

/****************************************************************************************/  

  (1)在 charset 中,通常使用的是utf-8,Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三 个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显 示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。

  UTF-8编码是可变长度的编码,根据所要编码的字元来确定其具体长度,以前有个认识误区,以为UTF-8存储数据时的长度是固定的。 

  (2)在 collation 中,类型如下:

  utf8_bin:二进制排序

  utf8_general_ci:普通字母排序,不区分大小写,是一个遗留的 校对规则,不支持扩展。它仅能够在字符之间进行逐个比较。这意味着utf8_general_ci校对规则进行的比较速度很快,但是与使用utf8_unicode_ci的校对规则相比,比较正确性较差。

  utf8_unicode_ci:普通字母排序,不区分大小写,校对规则仅部分支持Unicode校对规则算法。一些字符还是不能支持。并且,不能完全支持组合的记号。这主要影响越南和俄罗斯的一些少数民族语言,如:Udmurt 、Tatar、Bashkir和Mari。utf8_unicode_ci的最主要的特色是支持扩展,即当把一个字母看作与其它字母组合相等,例如,在德语和一些其它语言中‘ß’等于‘ss’。

 

mysql的 charset、collation、prefix了解的更多相关文章

  1. Mysql系列(四) —— MySQL的Charset和Collation

    本文转载自:再见乱码:5分钟读懂MySQL字符集设置 一.内容概述 在MySQL的使用过程中,了解字符集.字符序的概念,以及不同设置对数据存储.比较的影响非常重要.不少同学在日常工作中遇到的" ...

  2. MySQL基础知识:Character Set和Collation

    A character set is a set of symbols and encodings. A collation is a set of rules for comparing chara ...

  3. mysql 5.7 laravel json类型数据相关操作

    2018年10月16日18:14:21 官方文档中文翻译版 原文:https://dev.mysql.com/doc/refman/5.7/en/json.html 最后有部分实例和一个小总结 11. ...

  4. 学习笔记:The Best of MySQL Forum

    http://mysql.rjweb.org/bestof.html I have tagged many of the better forum threads. 'Better' is based ...

  5. 从一个慢查询到MySQL字符集编码

    从一个慢查询到MySQL字符集编码 目录 从一个慢查询到MySQL字符集编码 1. 问题起源 2. MySQL字符集和字符集排序规则 2.1 字符集相关概念 2.2 MySQL中的字符集和字符集排序规 ...

  6. nodejs项目mysql使用sequelize支持存储emoji

    nodejs项目mysql使用sequelize支持存储emoji 本篇主要记录nodejs项目阿里云mysql如何支持存储emoji表情. 因由 最近项目遇到用户在文本输入emoji进行存储的时候导 ...

  7. centos6.3安装python2.7, pip2.7, mysql

    参考: https://github.com/h2oai/h2o-2/wiki/Installing-python-2.7-on-centos-6.3.-Follow-this-sequence-ex ...

  8. MySQL Information Functions

    Table 12.18 Information Functions Name Description BENCHMARK() Repeatedly execute an expression CHAR ...

  9. MySQL中DATE_FORMATE函数内置字符集解析

    今天帮同事处理一个SQL(简化过后的)执行报错: 代码如下 复制代码 mysql> select date_format('2013-11-19','Y-m-d') > timediff( ...

随机推荐

  1. UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie

    input n 2<=n<=4000 s1 s2 ... sn 1<=len(si)<=1000 output 输出用strcmp()两两比较si,sj(i!=j)要比较的次数 ...

  2. 在Javascript中使用protobuf与c++进行通信

    环境:Win7_64旗舰版,VS2013 最近在研究Webkit,已经编译成功,接下来就是Javascript与c++如何传输数据,立刻就想到了protobuf,但是谷歌不支持Javascript,百 ...

  3. SSH整合中为获取表单对象Action类实现的接口及拦截器配置

    保存员工或者用户信息时,以员工为例,是通过表单收集信息的,需要把这些信息赋给一个对象,然后保存到数据库中.对应的Action类须实现Preparable接口及ModelDriven接口,且在Actio ...

  4. php薪资

    2千的php程序员就是可以用cms,做一个小企业的门户网站. 3千的php程序员,可以自己写代码开发php软件,但是这样程序员写的代码非常混乱,通常只能写数千行代码的小软件,并且痛苦的完工. 4K的p ...

  5. HDU1114--Piggy-Bank(完全背包变形)

    Piggy-Bank   Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

  6. Boyer Moore算法(字符串匹配)

    上一篇文章,我介绍了KMP算法. 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boyer-Mo ...

  7. Fragment里面嵌套Fragment的问题

    最近两天做项目时,要在fragment里面嵌套Fragment,最开始使用Fragment的hide,show等方法一直失败,,如图,message是一个fragment,在里面又有两个子fragme ...

  8. C#入门经典第六章函数-2-委托

    委托:

  9. 智力大冲浪(riddle)

    智力大冲浪(riddle) 题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为这些钱还不一定都是你的?!接 ...

  10. Android Studio调试功能使用总结---转

    Android Studio调试功能使用总结[转]   这段时间一直在使用Intellij IDEA, 今天把调试区工具的使用方法记录于此. 先编译好要调试的程序. 1.设置断点 选定要设置断点的代码 ...