跟我一起学习MySQL技术内幕(第五版):(第三章学习日记2上)
3.1.2字符串值 3.1.2.1字符串类型与字符集支持 3.1.2.2字符集相关的系统变量 3.1.2.1字符串类型与字符集支持 字符串值一般可以分为两类,二进制串和非二进制串 二进制串:一组字节序列,没有特殊的比较或者排序属性. 比较操作是基于各字节的数值逐个字节实现的.
3.1.2字符串值
3.1.2.1字符串类型与字符集支持
3.1.2.2字符集相关的系统变量
3.1.2.1字符串类型与字符集支持
字符串值一般可以分为两类,二进制串和非二进制串
二进制串:一组字节序列,没有特殊的比较或者排序属性.
比较操作是基于各字节的数值逐个字节实现的.
所有字节都有意义,**甚至包括结尾的空格**.
非二进制串:一个字符序列,每个二进制串都与字符集相关.
字符集决定了:MySQL如何解释字符串内容,哪些字符可以用.
每个字符集都有一种或者多种排序规则.
**尾部空格不会参与比较(TEXT类型除外-具有唯一性索引)**
字符串所使用的排序规则决定了字符在字符集里的先后顺序,这会对比较操作产生影响.
默认的字符集和排序规则分别为latin1和latin_swedish_ci.
查看服务器上提供的字符集以及排序规则:
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 |
.......
.......
show collation;
--------------------------+----------+-----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+--------------------------+----------+-----+---------+----------+---------+
| big5_chinese_ci | big5 | 1 | Yes | Yes | 1 |
| big5_bin | big5 | 84 | | Yes | 1 |
| dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 |
| dec8_bin | dec8 | 69 | | Yes | 1 |
| cp850_general_ci | cp850 | 4 | Yes | Yes | 1 |
| cp850_bin | cp850 | 80 | | Yes | 1 |
........
........
每种排序规则都捆绑在某个特定的字符集上,而每个给定的字符集可以有多种排序规则.
格式: 字符集名语言名附加后缀
后缀规则如下:
_ci表示排序规则不区分大小写
_cs表示排序规则要区分大小写
_bin表示这是一种二进制排序规则.(比较操作基于数字字符编码值进行,与语言无关)
如:utf8_bin
二进制串和非二进制串的排序特性:
二: 逐字节进行比较,结果只取决于每个字节的数值大小,区分大小写(大小写不同,对应
字节数值不同,二进制串其实并没有大小写的概念区分大小写实际上是排序规则的一项功能)
非二:按字符进行比较,每一个字符的相对值取决于当前所用字符集的排序规则.大小写设定为同一排序值,所以不区分大小写(不适用于区分大小写的非二进制排序)
确定某个字符串的字符集和排序规则:
(默认情况下,MySQL会把十六进制常量当作二进制串对待)
select charset(x'0123'),collation(x'0123');
+------------------+--------------------+
| charset(x'0123') | collation(x'0123') |
+------------------+--------------------+
| binary | binary |
+------------------+--------------------+
有两种记法约定可以用于将某个字符串强制解释为某种指定的字符集.
1._charset str
_latin2 'abc'
_latin2 x'616263'
_latin2 0x616263
_utf8 'def'
_utf8 X'646566'
_utf8 0x646566
对于引号里的字符串:
字符集引导符与字符串之间空白可选
十六进制不能留有任何空白
2.N’str’(等价于_utf8’str’)
N的后面必须紧跟一个引号形式的字符串,不能有任何空白
(3.对于字符串表达式或列值的引导符记法)
convert (str using charset);
引导符和convert是不一样的,引导符只会改变对字符串的解释,不会改变值,而convert是一个函数,进入的是输入参数,生成一个新的字符串返回.
set @s1 = _ucs2 'ABCD';
set @s2 = convert ('ABCD' using ucs2);
select char_length(@s1), length(@s1), char_length(@s2), length(@s2);
+------------------+-------------+------------------+-------------+
| char_length(@s1) | length(@s1) | char_length(@s2) | length(@s2) |
+------------------+-------------+------------------+-------------+
| 2 | 4 | 4 | 8 |
+------------------+-------------+------------------+-------------+
第一条语句:把ABCD每一对字符解释为一个双字节ucs2字符
第二条语句:把每个字符转化为相应的ucs2字符.
这一节最后介绍了二进制串与使用二进制串排序规则的非二进制串的区别.
1.二进制串没有字符集的概念.它会被解释为字节,并且比较的是单字节的数字代码
2.使用了二进制排序规则的非二进制串,会被解释为字符,并且比较的是它们的数字字符值,这种值通常是基于每个字符多个字节算出的.
set @s1 = binary 'abcd';
set @s2 = _latin1'abcd' collate latin1_bin;
select upper(@s1),upper(@s2);
+------------+------------+
| upper(@s1) | upper(@s2) |
+------------+------------+
| abcd | ABCD |
+------------+------------+
二进制串根本没有字符集的概念,所以无从得知哪些字节值对应着大写或者小写字符.如果非要这么做,可以选择先 convert再使用upper lower函数.
3.1.2.2字符集相关的系统变量
这一小节pass 暂时并没有什么用 一切使用默认就好了