当前位置: 首页 > news >正文

乡镇政府网站建设情况/发布外链的平台有哪些

乡镇政府网站建设情况,发布外链的平台有哪些,wordpress下载页面插件,如何看网站做没做推广字符集和比较规则简介 字符集简介 我们知道在计算机中只能以二进制的方式对数据进行存储,那么他们之间是怎样对应并进行转换的?我们需要了解两个概念: 字符范围:我们可以将哪些字符转换成二进制数据,也就是规定好字…

字符集和比较规则简介

字符集简介

我们知道在计算机中只能以二进制的方式对数据进行存储,那么他们之间是怎样对应并进行转换的?我们需要了解两个概念:

  • 字符范围:我们可以将哪些字符转换成二进制数据,也就是规定好字符范围。
  • 转换过程:将一个字符转换成一个二进制数据的过程也叫做编码 ,将一个二进制数据转换成一个字符的过程叫做解码 。

我们抽象出一个字符集的概念来描述某个字符范围的编码规则。比方说我们来自定义一个名称为 margu的字符集,它包含的字符范围和编码规则如下:包含字符 ‘a’ 、 ‘b’ 、 ‘A’ 、 ‘B’ 。
编码规则如下:
采用1个字节编码一个字符的形式,字符和字节的映射关系如下:
‘a’ -> 00000001 (十六进制:0x01)
‘b’ -> 00000010 (十六进制:0x02)
‘A’ -> 00000011 (十六进制:0x03)
‘B’ -> 00000100 (十六进制:0x04)
如果我们规定使用margu这个字符集,我们就可以用二进制形式表示一些字符串了,下边是一些字符串用 margu 字符集编码后的二进制表示:
‘Ba’ -> 0000010000000001 (十六进制:0x0401)
‘bAB’ -> 000000100000001100000100 (十六进制:0x020304)
‘CD’ -> 无法表示,字符集‘margu‘不包含字符’C’和’D’

所以,如果你想表示某个字符,一定要你选用的字符集支持。

比较规则简介

在我们确定了 margu字符集表示字符的范围以及编码规则后,怎么比较两个字符的大小呢?比较简单的就是直接比较这两个字符对应的二进制编码的大小,比方说字符 ‘a’ 的编码为 0x01 ,字符 ‘b’ 的编码为 0x02 ,所以 ‘a’ 小于 ‘b’ ,这种简单的比较规则也可以被称为二进制比较规则,英文名为 binary collation 。
二进制比较规则是简单,但有时候并不符合现实需求,比如在很多场合对于英文字符我们都是不区分大小写的,也就是说 ‘a’ 和 ‘A’ 是相等的,在这种场合下二进制比较规则就不再适用了,这时候我们可以这样指定比较规则:
1 . 将两个大小写不同的字符全都转为大写或者小写。
2 . 再比较这两个字符对应的二进制数据。
这是一种稍微复杂一点的比较规则,但是实际生活中的字符不止英文字符一种,比如我们的汉字就有上万个,对于某一种字符集来说,比较两个字符大小的规则可以制定出很多种,也就是说同一种字符集可以有多种比较规则,后面会介绍目前常用的一些字符集以及它们的一些比较规则。

一些重要的字符集

目前字符集的种类有很多,它们表示的字符范围和用到的编码规则可能都不一样。下面是一些常用的字符集:

ASCII 字符集

共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共128个字符,所以可以使用1个字节(8个bit位)来进行编码,我们看一些字符的编码方式:
‘A’ -> 01000001(十六进制:0x41,十进制:65)
‘H’ -> 01001000(十六进制:0x48,十进制:72)

ISO 8859-1 字符集

共收录256个字符,是在 ASCII 字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母),也可以使用1个字节来进行编码。这个字符集也有一个别名 latin1 。

GB2312 字符集

收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字6763个,其他文字符号682个。同时这种字符集又兼容 ASCII 字符集,所以在编码方式上显得有些奇怪:

  • 如果该字符在 ASCII 字符集中,则采用1字节编码。
  • 否则采用2字节编码。

这种表示一个字符需要的字节数可能不同的编码方式称为变长编码方式 。比方说字符串 ‘爱u’ ,其中 ‘爱’ 需要用2个字节进行编码,编码后的十六进制表示为 0xCED2 , ‘u’ 需要用1个字节进行编码,编码后的十六进制表示为 0x75 ,所以拼合起来就是 0xCED275 。

注意:如何区分某个字节代表一个单独的字符还是代表某个字符的一部分呢?前面说过ASCII字符集只收录128个字符,使用0~127就可以表示全部字符,所以如果某个字节是在0~127之内的,就意味着一个字节代表一个单独的字符,否则就是两个字节代表一个单独的字符。

GBK 字符集

GBK 字符集只是在收录字符范围上对 GB2312 字符集作了扩充,编码方式上兼容 GB2312 。

utf8

字符集收录地球上能想到的所有字符,而且还在不断扩充。这种字符集兼容 ASCII 字符集,采用变长编码方式,编码一个字符需要使用1~4个字节,比如:
‘A’ -> 01000001(十六进制:0x41)
‘啊’ -> 111001011001010110001010(十六进制:0xE5958A)
注意:其实准确的说,utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个字符,utf32使用4个字节编码一个字符。
MySQL中并不区分字符集和编码方案的概念,所以后边唠叨的时候把utf8、utf16、utf32都当作
一种字符集对待。

对于同一个字符,不同字符集也可能有不同的编码方式。比如对于汉字 ‘我’ 来说, ASCII 字符集中没有收录这个字符, utf8 和 gb2312 字符集对汉字 我 的编码方式如下:
utf8编码:111001101000100010010001 (3个字节,十六进制表示是:0xE68891)
gb2312编码:1100111011010010 (2个字节,十六进制表示是:0xCED2)

MySQL中支持的字符集和排序规则

MySQL中的utf8和utf8mb4

上边说过utf8 字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而在Mysql中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以Mysql衍生出utf8的两个子字符集概念:
utf8mb3 :精简版的utf8 字符集,只使用1~3个字节表示字符。
utf8mb4 :标准版的utf8 字符集,使用1~4个字节表示字符。
重点注意:在 MySQL 中 utf8 是 utf8mb3 的别名,所以之后在 MySQL 中提到 utf8 就意味着使用1~3个字节来表示一个字符,如果要想使用4字节编码一个字符的情况,比如存储一些emoji表情,那么需要完整指定使用utf8mb4 字符集。

字符集的查看

MySQL 支持好多好多种字符集,查看当前 MySQL 中支持的字符集可以用下边这个语句:
SHOW (CHARACTER SET|CHARSET) [LIKE 匹配的模式];
其中 CHARACTER SET 和 CHARSET 是同义词,用任意一个都可以。

mysql> show character set;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese        | big5_chinese_ci     |      2 |
| dec8     | DEC West European               | dec8_swedish_ci     |      1 |
| cp850    | DOS West European               | cp850_general_ci    |      1 |
| hp8      | HP West European                | hp8_english_ci      |      1 |
| koi8r    | KOI8-R Relcom Russian           | koi8r_general_ci    |      1 |
| latin1   | cp1252 West European            | latin1_swedish_ci   |      1 |
......
41 rows in set (0.00 sec)

从返回的结果中可以看到,目前使用的mysql(5.7版本)一共支持41种字符集,其中的 Default collation 列表示这种字符集中一种默认的比较规则,ci结尾的表示都是忽略大小写 。最后一列的Maxlen ,它代表该种字符集表示一个字符最多需要几个字节。大家需要对常用的有印象,如下:

字符集名称描述默认比较规则最长字节数
asciiUS ASCIIascii_general_ci1
latin1cp1252 West Europeanlatin1_swedish_ci1
gb2312GB2312 Simplified Chinesegb2312_chinese_ci2
gbkGBK Simplified Chinesegbk_chinese_ci2
utf8UTF-8 Unicodeutf8_general_ci3
utf8mb4UTF-8 Unicodeutf8mb4_general_ci4

比较规则查看

查看 MySQL 中支持的比较规则的命令如下:
SHOW COLLATION [LIKE 匹配的模式];
一种字符集可能对应有多种比较规则, MySQL 支持的字符集就已经非常多了,所以支持的比较规则更多,我们先只查看一下 utf8 字符集下的比较规则:

mysql> show collation like 'utf8\_%';
+--------------------------+---------+-----+---------+----------+---------+
| Collation                | Charset | Id  | Default | Compiled | Sortlen |
+--------------------------+---------+-----+---------+----------+---------+
| utf8_general_ci          | utf8    |  33 | Yes     | Yes      |       1 |
| utf8_bin                 | utf8    |  83 |         | Yes      |       1 |
| utf8_unicode_ci          | utf8    | 192 |         | Yes      |       8 |
......
| utf8_general_mysql500_ci | utf8    | 223 |         | Yes      |       1 |
+--------------------------+---------+-----+---------+----------+---------+
27 rows in set (0.00 sec)

从返回的结果可以看到关于utf8的比较规则都有27种,这些比较规则的命名有一定的规律,具体规律如下:

  • 比较规则名称以与其关联的字符集的名称开头。如上图的查询结果的比较规则名称都是以 utf8 开头的。
  • 后边紧跟着该比较规则主要作用于哪种语言,比如 utf8_spanish_ci 表示以西班牙语的规则比较,utf8_roman_ci 是以罗马语的规则比较, utf8_general_ci 是一种通用的比较规则。
    名称后缀意味着该比较规则是否区分语言中的重音、大小等,具体可以用的值如下:
    • _ai:accent insensitive ,不区分重音(insentive:不敏感的)
    • _as:accent sensitive ,区分重音
    • _ci:case insensitive ,不区分大小写
    • _cs:case sensitive,区分大小写
    • _bin:binary ,以二进制方式进行比较
      比如 utf8_general_ci 这个比较规则是以 ci 结尾的,说明不区分大小写。
      每种字符集对应若干种比较规则,每种字符集都有一种默认的比较规则, SHOW COLLATION 的返回结果中的Default 列的值为 YES 的就是该字符集的默认比较规则,比方说 utf8 字符集默认的比较规则就是utf8_general_ci 。

字符集和比较规则的应用

各级别的字符集和比较规则

MySQL 有4个级别的字符集和比较规则,分别是:

  • 服务器级别
  • 数据库级别
  • 表级别
  • 列级别
    接下来看看怎么查看和设置这几个级别的字符集和比较规则。

服务器级别

MySQL 提供了两个系统变量来表示服务器级别的字符集和比较规则:

系统变量说明
character_set_server服务器级别的字符集
collation_server服务器级别的比较规则

我们看一下这两个系统变量的值,记不住全称的可以用%进行匹配。

mysql> show variables like '%_server';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| character_set_server | utf8            |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+
2 rows in set (0.01 sec)

可以看到在我的计算机中服务器级别默认的字符集是 utf8 ,默认的比较规则是utf8_general_ci 。
我们可以在启动服务器程序时通过启动选项或者在服务器程序运行过程中使用 SET 语句修改这两个变量的值。比如我们可以在配置文件中这样配置:
[server]
character_set_server=gbk
collation_server=gbk_chinese_ci
当服务器启动的时候读取这个配置文件后这两个系统变量的值便修改了。

数据库级别

我们在创建和修改数据库的时候可以指定该数据库的字符集和比较规则,具体语法如下:
CREATE DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];

ALTER DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
其中的 DEFAULT 可以省略,并不影响语句的语义。比方说我们新创建一个名叫 charset_demo_db 的数据库,在创
建的时候指定它使用的字符集为 gb2312 ,比较规则为 gb2312_chinese_ci :

mysql> create  database charset_demo_db character set gb2312 collate gb2312_chinese_ci;
Query OK, 1 row affected (0.00 sec)mysql>

如果想查看当前数据库使用的字符集和比较规则,可以查看下面两个系统变量的值(前提是使用 USE 语句选择要查看的数据库,如果没有指定要查看的数据库,则变量与相应的服务器级系统变量具有相同的值):

#未指定数据库,值与服务器级别的系统变量一致
mysql> show variables like '%_database';
+------------------------+-----------------+
| Variable_name          | Value           |
+------------------------+-----------------+
| character_set_database | utf8            |
| collation_database     | utf8_general_ci |
| skip_show_database     | OFF             |
+------------------------+-----------------+
3 rows in set (0.00 sec)
mysql> use charset_demo_db;
Database changed
mysql> show variables like '%_database';
+------------------------+-------------------+
| Variable_name          | Value             |
+------------------------+-------------------+
| character_set_database | gb2312            |
| collation_database     | gb2312_chinese_ci |
| skip_show_database     | OFF               |
+------------------------+-------------------+
3 rows in set (0.01 sec)

可以看到这个 charset_demo_db 数据库的字符集和比较规则就是我们在创建语句中指定的。需要注意的是:数据库中存在的两个变量(character_set_database、collation_database)都是只读的,没法通过修改这两个变量的值来修改数据的字符集和比较规则,想要修改数据库的字符集和比较规则,需要在创建或者修改数据库的时手动指定character set和collation变量的值,如果不指定的话,则默认使用服务器级别的字符集和比较规则。

表级别

我们也可以在创建和修改表的时候指定表的字符集和比较规则,语法如下:
CREATE TABLE 表名 (列的信息)
[[DEFAULT] CHARACTER SET 字符集名称]
[COLLATE 比较规则名称]]

ALTER TABLE 表名
[[DEFAULT] CHARACTER SET 字符集名称]
[COLLATE 比较规则名称]
比方说我们在刚刚创建的 charset_demo_db 数据库中创建一个名为 test 的表,并指定这个表的字符集和比较规则:

mysql> create table test(name varchar(10) ) CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 0 rows affected (0.08 sec)mysql> 

如果创建和修改表的语句中没有指明字符集和比较规则,将使用该表所在数据库的字符集和比较规则作为该表的字符集和比较规则。假设我们的创建表 test 的语句是这么写的:
CREATE TABLE test(name varchar(10) ) ;
因为表test的建表语句中并没有明确指定字符集和比较规则,则表test 的字符集和比较规则将继承所在数据库charset_demo_db 的字符集和比较规则,也就是 gb2312 和gb2312_chinese_ci 。

列级别

需要注意的是,对于存储字符串的列,同一个表中的不同的列也可以有不同的字符集和比较规则。我们在创建和修改列定义的时候可以指定该列的字符集和比较规则,语法如下:
CREATE TABLE 表名(
列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称],
其他列…
);
ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称];

比如我们修改一下表 test 中列 name的字符集和比较规则可以这么写:

mysql> alter  table test modify name varchar(10) charset gbk collate gbk_chinese_ci;
Query OK, 0 rows affected (0.21 sec)
Records: 0  Duplicates: 0  Warnings: 0

对于某个列来说,如果在创建和修改的语句中没有指明字符集和比较规则,将使用该列所在表的字符集和比较规则作为该列的字符集和比较规则。比方说表 test的字符集是 utf8 ,比较规则是 utf8_general_ci ,修改列 name的
语句是这么写的:
ALTER TABLE test MODIFY name VARCHAR(10);
那列name的字符集和编码将使用表test的字符集和比较规则,也就是utf8和utf8_general_ci 。
注意:在转换列的字符集时需要注意,如果转换前列中存储的数据不能用转换后的字符集进行表示会发生错误。比方说原先列使用的字符集是utf8,列中存储了一些汉字,而现在把列的字符集转换为ascii的话就会出错,因为ascii字符集并不能表示汉字字符。

仅修改字符集或仅修改比较规则

由于字符集和比较规则是互相有联系的,如果我们只修改了字符集,比较规则也会跟着变化,如果只修改了比较规则,字符集也会跟着变化,具体规则如下:

  • 只修改字符集,则比较规则将变为修改后的字符集默认的比较规则。
  • 只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。

不论哪个级别的字符集和比较规则,这两条规则都适用,下面以服务器级别的字符集和比较规则为例测试一下:

  • 只修改字符集,则比较规则将变为修改后的字符集默认的比较规则。
mysql> set  character_set_server = gb2312;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%_server';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| character_set_server | gb2312            |
| collation_server     | gb2312_chinese_ci |
+----------------------+-------------------+
2 rows in set (0.00 sec)
  • 只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。
mysql> set  collation_server = utf8_general_ci;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like '%_server';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| character_set_server | utf8            |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+
2 rows in set (0.00 sec)

各级别字符集和比较规则小结

下面总结以上4个级别字符集和比较规则之间的联系:

  • 如果创建或修改列时没有显式的指定字符集和比较规则,则该列默认用表的字符集和比较规则
  • 如果创建或修改表时没有显式的指定字符集和比较规则,则该表默认用数据库的字符集和比较规则
  • 如果创建或修改数据库时没有显式的指定字符集和比较规则,则该数据库默认用服务器的字符集和比较规则

知道了这些规则之后,对于给定的表,我们应该知道它的各个列的字符集和比较规则是什么,从而根据这个列的类型来确定存储数据时每个列的实际数据占用的存储空间大小了。具体使用的字符集类型可以通过show create table test;进行查看,注意表名需要修改成自己要查询的表。

客户端和服务器通信中的字符集

编码和解码使用的字符集不一致的后果

说到底,字符串在计算机上的体现就是一个字节串,如果你使用不同字符集去解码这个字节串,最后得到的结果可能千奇百怪。
我们知道字符 ‘我’ 在 utf8 字符集编码下的字节串长这样: 0xE68891 ,如果一个程序把这个字节串发送到另一个程序里,另一个程序用不同的字符集去解码这个字节串,假设使用的是 gbk 字符集来解释这串字节,解码过程就是这样的:

  1. 首先看第一个字节 0xE6 ,它的值大于 0x7F (十进制:127),说明是两字节编码,继续读一字节后是 0xE688 ,然后从 gbk 编码表中查找字节为 0xE688 对应的字符,发现是字符 ‘鎴’
  2. 继续读一个字节 0x91 ,它的值也大于 0x7F ,再往后读一个字节发现木有了,所以这是半个字符。
  3. 所以 0xE68891 被 gbk 字符集解释成一个字符 ‘鎴’ 和半个字符。

假设用 latin1 字符集去解释这串字节,解码过程如下:

  1. 先读第一个字节 0xE6 ,它对应的 latin1 字符为 æ 。
  2. 再读第二个字节 0x88 ,它对应的 latin1 字符为 ˆ 。
  3. 再读第二个字节 0x91 ,它对应的 latin1 字符为 ‘ 。
  4. 所以整串字节 0xE68891 被 latin1 字符集解释后的字符串就是 ‘我’
    可见,如果对于同一个字符串编码和解码使用的字符集不一样,会产生意想不到的结果,作为使用者的我们看上去就像是产生了乱码一样。

字符集转换的概念

如果接收 0xE68891 这个字节串的程序按照 utf8 字符集进行解码,然后又把它按照 gbk 字符集进行编码,最后编码后的字节串就是 0xCED2 ,我们把这个过程称为 字符集的转换 ,也就是字符串 ‘我’ 从 utf8 字符集转换为gbk 字符集。

Mysql中字符集的转换

我们知道从客户端发往服务器的请求本质上就是一个字符串,服务器向客户端返回的结果本质上也是一个字符串,而字符串其实是使用某种字符集编码的二进制数据。这个字符串可不是使用一种字符集的编码方式一条道走到黑的,从发送请求到返回结果这个过程中伴随着多次字符集的转换,在这个过程中会用到3个系统变量,我们先把它们写出来看一下:

系统变量描述
character_set_client服务器解码请求时使用的字符集
character_set_connection服务器处理请求时会把请求字符串从 character_set_client 转为 character_set_connection
character_set_results服务器向客户端返回数据时使用的字符集

这几个系统变量在我的计算机上的默认值如下(不同操作系统的默认值可能不同),注意只关注上面给的几个变量,其他的在测试过程中应该手动改过。

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

可以看到这三个系统变量的值都是 utf8 ,为了体现出字符集在请求处理过程中的变化,我们这里特意修改 一个系统变量的值:
mysql> set character_set_connection = gbk;
Query OK, 0 rows affected (0.00 sec)
所以现在系统变量 character_set_client 和 character_set_results 的值还是 utf8 ,而 character_set_connection 的值为 gbk 。现在假设我们客户端发送的请求是下边这个字符串:
SELECT * FROM t WHERE s = ‘我’;
为了方便大家理解这个过程,我们只分析字符 ‘我’ 在这个过程中字符集的转换。 现在看一下在请求从发送到结果返回过程中字符集的变化:

  1. 客户端发送请求所使用的字符集
    一般情况下客户端所使用的字符集和当前操作系统一致,不同操作系统使用的字符集可能不一样,如下:
  • Linux系统使用的是 utf8
  • Windows 使用的是 gbk
    我在windows服务器上使用的xshell客户端,并设置了编码格式为utf8。所以字符 ‘我’ 在发送给服务器的请求中的字节形式就是: 0xE68891
    注意:如果使用的是可视化工具,比如securecrt/xshell之类的,这些工具可以使用自定义的字符集来编码发送到服务器的字符串,而不采用操作系统默认的字符集。
  1. 服务器接收到客户端发送来的请求其实是一串二进制的字节,它会认为这串字节采用的字符集是 character_set_client ,然后把这串字节转换为 character_set_connection 字符集编码的字符。
    由于我的计算机上 character_set_client 的值是 utf8 ,首先会按照 utf8 字符集对字节串 0xE68891 进行解码,得到的字符串就是 ‘我’ ,然后按照 character_set_connection 代表的字符集,也就是 gbk 进行编码,得到的结果就是字节串 0xCED2 。
  2. 因为表 test 的列 name 采用的是 gbk 字符集,与 character_set_connection 一致,所以直接到列中找字节值为 0xCED2 的记录,最后找到了一条记录。
    注意:如果某个列使用的字符集和character_set_connection代表的字符集不一致的话,还需要进行一次字符集转换。
  3. 上一步骤找到的记录中的 name 列其实是一个字节串 0xCED2 ,name列是采用 gbk 进行编码的,所以首先会将这个字节串使用 gbk 进行解码,得到字符串 ‘我’ ,然后再把这个字符串使用 character_set_results 代表 的字符集,也就是 utf8 进行编码,得到了新的字节串: 0xE68891 ,然后发送给客户端。
  4. 由于客户端是用的字符集是 utf8 ,所以可以顺利的将 0xE68891 解释成字符‘我’ ,从而显示到我们的显示器上,所以我们使用者也正确读懂了返回的结果。
    总的可以参照下面这个图来总结以上的这几个步骤:
    在这里插入图片描述
    上面这个图中我们需要注意以下几个地方:
  • 服务器认为客户端发送过来的请求是用 character_set_client 编码的。假设你的客户端采用的字符集和 character_set_client 不一样的话(也就是编码和解码的规则不一样),这就会出现意想不到的情况。比如我的客户端使用的是 utf8 字符集,如果把系统变量 character_set_client 的值设置为 ascii 的话,服务器可能无法理解我们发送的请求,更别谈处理这个请求了。
  • 服务器将把得到的结果集使用 character_set_results 编码后发送给客户端。
    假设你的客户端采用的字符集和 character_set_results 不一样的话,这就可能会出现客户端无法解码结果 集的情况,结果就是在你的屏幕上出现乱码。比如我的客户端使用的是 utf8 字符集,如果把系统变量character_set_results 的值设置为 ascii 的话,可能会产生乱码。
  • character_set_connection 只是服务器在将请求的字节串从 character_set_client 转换为 character_set_connection 时使用,它是什么其实没多重要,但是一定要注意,该字符集包含的字符范围一定要涵盖请求中的字符,要不然会导致有的字符无法使用character_set_connection 代表的字符集进行编码。比如你把 character_set_client 设置为 utf8 ,把 character_set_connection 设置成 ascii ,那么此时你如果从客户端发送一个汉字到服务器,那么服务器无法使用 ascii 字符集来编码这个汉字,就会向用户发出一个警告。

了解了在 MySQL 中从发送请求到返回结果过程里发生的各种字符集转换,但是为啥要这样转来转去的呢?不觉得很繁琐么?
答:是的很繁琐,所以我们通常都把 character_set_client 、character_set_connection、 character_set_results 这三个系统变量设置成和客户端使用的字符集一致的情况,这样减少了很多无谓的字符集转换。为了方便我们设置, MySQL 提供了一条非常简便的语句:
SET NAMES 字符集名;
这一条语句产生的效果和我们执行这3条的效果是一样的:
SET character_set_client = 字符集名;
SET character_set_connection = 字符集名;
SET character_set_results = 字符集名;
比方说我的客户端使用的是 utf8 字符集,所以需要把这几个系统变量的值都设置为 utf8 :

mysql> SET names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'character_set_%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | utf8                             |
| character_set_connection | utf8                             |
| character_set_database   | gb2312                           |
| character_set_filesystem | binary                           |
| character_set_results    | utf8                             |
| character_set_server     | utf8                             |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.01 sec)

注意: 如果使用的是Windows系统作为客户端,也就是没有用其他的终端软件,如xshell,那应该设置成gbk。
另外,如果你想在启动客户端的时候就把 character_set_client 、 character_set_connection 、 character_set_results 这三个系统变量的值设置成一样的,那我们可以在启动客户端的时候指定一个叫 default-character-set 的启动选项,比如在配置文件里可以这么写:
[client]
default-character-set=utf8
它起到的效果和执行一遍 SET NAMES utf8 是一样一样的,都会将那三个系统变量的值设置成 utf8 。

比较规则的应用

比较规则的作用通常体现比较字符串大小的表达式以及对某个字符串列进行排序,所以有时候也称为排序规则 。比方说表 test 的列 name 使用的字符集是 gbk ,使用的比较规则是 gbk_chinese_ci ,我们向里边插入几条记录:

mysql> INSERT INTO test(name) VALUES('a'), ('b'), ('A'), ('B');
Query OK, 4 rows affected (0.04 sec)
Records: 4  Duplicates: 0  Warnings: 0
mysql> select * from test order by name;
+------+
| name |
+------+
| a    |
| A    |
| b    |
| B    |
||
+------+
5 rows in set (0.00 sec)
mysql> 

可以看到在默认的比较规则 gbk_chinese_ci 中是不区分大小写的,我们现在把列 name 的比较规则修改为 gbk_bin :

mysql> ALTER TABLE test  MODIFY name VARCHAR(10) COLLATE gbk_bin;
Query OK, 5 rows affected (0.17 sec)
Records: 5  Duplicates: 0  Warnings: 0

由于 gbk_bin 是直接比较字符的编码,所以是区分大小写的,我们再看一下排序后的查询结果:

mysql> select * from test order by name;
+------+
| name |
+------+
| A    |
| B    |
| a    |
| b    |
||
+------+
5 rows in set (0.01 sec)

所以如果以后大家在对字符串做比较或者对某个字符串列做排序操作时没有得到想象中的结果,需要思考一下是不是字符规则的问题。

总结:总的来说,在选用字符集时要选择能支持表示字符的字符集,并尽量精简。其次,使用时,尽量保证客户端服务端(包括服务器级别,数据库级别,表级别,列级别)字符集及比较规则一致,避免进行多次转化及转换出错。

更多关于mysql的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出

相关文章:

【Mysql】Mysql的字符集和比较规则(三)

字符集和比较规则简介 字符集简介 我们知道在计算机中只能以二进制的方式对数据进行存储,那么他们之间是怎样对应并进行转换的?我们需要了解两个概念: 字符范围:我们可以将哪些字符转换成二进制数据,也就是规定好字…...

【SpringCloud-11】SCA-sentinel

sentinel是一个流量控制、熔断降级的组件,可以替换第一代中的hystrix。 hystrix用起来没有那么方便: 1、要在调用方引入hystrix,没有ui界面进行配置,需要在代码中进行配置,侵入了业务代码。 2、还要自己搭建监控平台…...

设计模式:简单工厂模式(C#、JAVA、JavaScript、C++、Python、Go、PHP):

简介: 简单工厂模式,它提供了一个用于创建对象的接口,但具体创建的对象类型可以在运行时决定。这种模式通常用于创建具有共同接口的对象,并且可以根据客户端代码中的参数或配置来选择要创建的具体对象类型。 在简单工厂模式中&am…...

浅谈智能照明控制系统在智慧建筑中的应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要:新时期,建筑行业发展迅速,在信息化背景下,建筑功能逐渐拓展,呈现了智能化的发展态势。智能建筑更加安全、节能、环保,也符合绿色建筑理念。在建筑智…...

lower_bound()以及upper_bound()

lower_bound(): lower_bound()的返回值是第一个大于等于 target 的值的地址,用这个地址减去first,得到的就是第一个大于等于target的值的下标。 在数组中: int poslower_bound(a,an,target)-a;\\n为数组…...

unity(WebGL) 截图拼接并保存本地,下载PDF

截图参考:Unity3D 局部截图、全屏截图、带UI截图三种方法_unity 截图_野区捕龙为宠的博客-CSDN博客 文档下载: Unity WebGL 生成doc保存到本地电脑_unity webgl 保存文件_野区捕龙为宠的博客-CSDN博客 中文输入:Unity WebGL中文输入 支持输…...

加速企业云计算部署:应对新时代的挑战

随着科技的飞速发展,企业面临着诸多挑战。在这个高度互联的世界中,企业的成功与否常常取决于其能否快速、有效地响应市场的变化。云计算作为一种新兴的技术趋势,为企业提供了实现这一目标的可能。通过加速企业云计算部署,企业可以…...

ubuntu 18.04 LTS交叉编译opencv 3.4.16并编译工程[全记录]

一、下载并解压opencv 3.4.16源码 https://opencv.org/releases/ 放到home路径下的Exe文件夹(专门放用户安装的软件)中,其中build是后期自建的 为了版本控制,保留了3.4.16,并增加了-gcc-arm 二、安装cmake和cmake-g…...

禁用和开启笔记本电脑的键盘功能,最快的方式

笔记本键盘通常较小,按键很不方便,当我们外接了键盘时就不需要再使用自带的键盘了,而且午睡的时候,总是担心碰到笔记本的键盘,可能会删掉我们的代码什么的,所以就想着怎么禁用掉,下面是操作步骤…...

【单片机基础】使用51单片机制作函数信号发生器(DAC0832使用仿真)

文章目录 (1)DA转换(2)DAC0832简介(3)电路设计(4)参考例程(5)参考文献 (1)DA转换 单片机作为一个数字电路系统,当需要采集…...

springcloud组件

https://www.bilibili.com/video/BV1QX4y1t7v5?p32&vd_source297c866c71fa77b161812ad631ea2c25 eureka : 主要是收集服务的注册信息。 如果有了eureka启动了。内部之前的调用其实就可以用服务名了, 本来是要是用ip端口来访问的,只要eureka启来了…...

手机爬虫用Appium详细教程:利用Python控制移动App进行自动化抓取数据

Appium是一个强大的跨平台工具,它可以让你使用Python来控制移动App进行自动化操作,从而实现数据的抓取和处理。今天,我将与大家分享一份关于使用Appium进行手机爬虫的详细教程,让我们一起来探索Appium的功能和操作,为手…...

deb包构建详解

deb包构建详解 一、deb包构建流程二、deb包构建描述文件详解2.1 control文件2.2 postinst 文件 (post-installation script)2.3 postrm 文件 (post-removal script)2.4 prerm 文件 (pre-removal script)2.5 preinst 文件 (pre-installation script)2.6 rules 文件2.7 changelog…...

【Spring Cloud】网关Gateway的请求过滤工厂RequestRateLimiterGatewayFilterFactory

概念 关于微服务网关Gateway中有几十种过滤工厂,这一篇博文记录的是关于请求限流过滤工厂,也就是标题中的RequestRateLimiterGatewayFilterFactory。这个路由过滤工厂是用来判断当前请求是否应该被处理,如果不会被处理就会返回HTTP状态码为42…...

自己写spring boot starter问题总结

1. Unable to find main class 创建spring boot项目写自己的starterxi写完之后使用install出现Unable to find main class&#xff0c;这是因为spring boot打包需要一个启动类&#xff0c;按照以下写法就没事 <plugins><plugin><groupId>org.springframewo…...

vue3如何打开页面即向后端发送请求

目录 背景&#xff1a; 实现&#xff1a; 1、使用 2、案例 补充&#xff1a; 1、如何定义一个集合来接受后端返回的list 2、加入请求头 背景&#xff1a; 如果想在页面刚加载时向后端发送请求&#xff0c;可以使用Vue 3的生命周期钩子函数onMounted来实现 实现&#xff…...

【软考】9.2 串/数组/矩阵/广义表/树

《字符串》 一种特殊的线性表&#xff0c;数据元素都为字符模式匹配&#xff1a;寻找子串第一次在主串出现的位置 模式匹配算法 1. 暴力破解法&#xff08;布鲁特-福斯算法&#xff09; 主串与子串一个个匹配效率低 2. KMP算法 主串后缀和子串前缀能否找到一样的元素&#xf…...

大数据 DataX 数据同步数据分析入门

目录 一、DataX 概览 1.1 DataX 是什么 1.2 DataX 3.0 概览 设计理念 当前使用现状 二、DataX 详解 2.1 DataX 3.0 框架设计 2.2 DataX 3.0 插件体系 2.3 DataX 3.0 核心架构 2.3.1 核心模块介绍 2.3.2 DataX 调度流程 2.4 DataX 3.0 的六大核心优势 2.4.1 可靠的…...

【京东开源项目】微前端框架MicroApp 1.0正式发布

介绍 MicroApp是由京东前端团队推出的一款微前端框架&#xff0c;它从组件化的思维&#xff0c;基于类WebComponent进行微前端的渲染&#xff0c;旨在降低上手难度、提升工作效率。MicroApp无关技术栈&#xff0c;也不和业务绑定&#xff0c;可以用于任何前端框架。 源码地址…...

多个子div在父中垂直居中

在一个div下&#xff0c;有多个子div&#xff0c;且子div都是水平垂直居中 <template><div><div class"far"><!-- 注意需要多包裹一层 --><div><div class"son1">1</div><div class"son2">222…...

[C国演义] 第十五章

第十五章 最长湍流子数组环绕字符串中唯⼀的⼦字符串 最长湍流子数组 力扣链接 子数组 ⇒ dp[i]的含义: 以arr[i] 结尾的所有子数组中的最长湍流子数组的长度 子数组 ⇒ 状态转移方程根据 最后一个位置来划分&#x1f447;&#x1f447;&#x1f447; 初始化: 都初始化为…...

Docker Compose和Consul

目录 Docker-compose Docker-compose 简介 YAML 文件格式及编写注意事项 Docker Compose配置常用字段 Docker Compose 常用命令 Docker Compose 文件结构 compose 部署 Docker Compose 环境安装 准备依赖文件 编写配置文件docker-compose.yml Consul consul 部署 c…...

Wireshark新手小白基础使用方法

一、针对IP抓取 1、过滤格式&#xff1a; &#xff08;1&#xff09;、ip.src eq x.x.x.x &#xff08;2&#xff09;、ip.dst eq x.x.x.x &#xff08;3&#xff09;ip.src eq x.x.x.x or ip.dst eq x.x.x.x 二、针对端口过滤 1、过滤格式&#xff1a; &#xff08;1&a…...

互动设计:深入了解用户体验的关键

交互是人与计算机系统之间的互动过程。在计算机领域中&#xff0c;交互是人机交互技术的核心内容之一。交互设计是一种基于人类行为科学、心理学、人体工程学等领域的专业设计&#xff0c;目的是创造用户友好的、易于使用的计算机软件、网络、移动应用等。交互的本质在于用户的…...

maven的坐标元素

maven的坐标&#xff1a;使用三个向量在Maven仓库中唯一的定位到一个jar包 * groupId&#xff1a;公司或组织的ID * artifactId&#xff1a;一个项目或者是项目中的一个模块的ID * version&#xff1a;版本号 <groupId>com.gz.maven</groupId> <artifactId&…...

蓝桥杯 题库 简单 每日十题 day13

01 乘积尾零 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将 所填结果输出即可。如下的10行数据&#xff0c;每行有10个整数&#xff0c;请你求出它们的乘积的末尾有多少个零&#xff1f; 5650 4542 3554 473 946 4114 3871 9073 90 …...

联想G50笔记本直接使用F键功能(F1~F12)需要在BIOS设置关闭热键功能可以这样操作!

如果开启启用热键模式按F1就会出现FnF1的效果&#xff0c;不喜欢此方式按键的用户可以进入BIOS设置界面停用热键模式即可。 停用热键模式方法如下&#xff1a; 1、重新启动笔记本电脑&#xff0c;当笔记本电脑屏幕出现Lenovo标识的时候&#xff0c;立即按FnF2进入BIOS设置界面…...

C++入门(头文件,命名空间,作用域,输入输出流,引用,缺省参数,函数重载)

目录 一&#xff0c;头文件 二,命名空间 三&#xff0c;作用域 四&#xff0c;输入输出流 五&#xff1a;引用 六&#xff0c;缺省参数 七&#xff0c;函数重载 一&#xff0c;头文件 C的头文件与C是有差距的&#xff0c;C的头文件是#include<stdio.h>,而C是#inc…...

“Linux免除系统交互操作方法、expect自动化交互工具” 及 “SSH批量修改主机密码脚本”

一、Linux系统免除交互操作方法 1、EOF多文本输入 案例&#xff1a;为机器磁盘进行分区并实现挂载&#xff0c;免交互式操作&#xff0c;如何实现&#xff1f; #!/bin/bash fdisk /dev/sdb <<EOF n p 1 wq EOFmkfs.xfs /dev/sdb1 && mkdir -p /data &&am…...

三相异步电机动态数学模型及矢量控制仿真

三相异步电机动态数学模型及矢量控制仿真 本文带你一步步推倒三相异步电机动态数学模型&#xff0c;按基于转子磁链定向的矢量控制进行 matlab 仿真&#xff0c;实现较好的控制效果。 1、异步电机三相方程 2、坐标变换 3、磁链3/2变换推导 4、两相静止坐标系下的方程 5、…...