mysql5.7官网直译数据类型--字符串类型2

11.4.4 The ENUM Type 枚举类型
一个枚举类型是一个字符串对象,其值来自于表在创建时设定的列的值的集合中选择,其优点:
》在合适的情况下,存储数据在一列中使用有限的可能值。你输入的字符串值自动转变为数字。具体请看11.8的数据类型类型存储要求中对枚举类型存储的要求。
》在查询和输出过程中,数字被转变为正确的字符串返回。
当然有些潜在的问题,需要考虑:
》如果你使得枚举值看起来像数字,它很容易和真实存储在内部的值混淆,作为枚举的限制会解释。
》使用枚举列作为排序条件,最终是以枚举存储值来排序。
》创建和使用枚举列
》对于枚举值的索引
》没价值的处理
》空或NULL枚举值
》枚举存储
》枚举限制
Creating and Using ENUM Columns 创建和使用枚举列。
一个枚举值必须是一个可以引证的字符串值。例如,你能在表中创建一个枚举列像这样:
CREATE TABLE shirts (
    name VARCHAR(40),
    size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),
  ('polo shirt','small');
SELECT name, size FROM shirts WHERE size = 'medium';
+---------+--------+
| name    | size   |
+---------+--------+
| t-shirt | medium |
+---------+--------+
UPDATE shirts SET size = 'small' WHERE size = 'large';
COMMIT;
插入1million行数据在这张表中假设值为“medium"则需要1million bytes来存储。而你要是存储字符串”medium"在一个字符串列,则需要6million bytes。
Index Values for Enumeration Literals 对枚举值的索引
每一个没价值都有索引:
在列中被列出的元素索引,以1开始。
对于一个空字符串或者是错误值的索引是0.这意味着你可以通过如下的查询找出非法的值:
mysql> SELECT * FROM tbl_name WHERE enum_col=0;
NULL值的索引也是NULL。
在这里索引的目的,其实是枚举值在list集合中的位置。并不是表中的索引。
例如,一个列设计为 ENUM('Mercury', 'Venus', 'Earth') 可以展示的值. 则每一个值的索引也是:
Value         Index
NULL           NULL
''              0
'Mercury'       1
'Venus'         2
'Earth'         3
一个枚举列最多可以有65535个不同的值。(实际的限制是小于3000个)一张表可以有不超过255个唯一元素集合定义通过它的枚举和集合列被考虑作为一个分组。更多信息请看C.10.5关于.frm文件结构的限制。
如果你检索一个枚举值在一个数字上下文,列值的索引会被返回。例如,你能够检索数字值像这样:
mysql> SELECT enum_col+0 FROM tbl_name;
函数例如SUM()或者AVG()想将一个数字参数映射为一个数字如果可能的话。对于枚举孩子,索引数字被用于计算。
Handling of Enumeration Literals 处理枚举值
当一个表被创建时,枚举成员值尾部的空格会被自动删除掉。
当查找时,存储在枚举列中的值被展示,通过使用表定义时的字符。注意,枚举列可以是一个字符集和collation.对于二进制或者大小眼敏感的collations,在设计值的时候,应该考虑字母。
如果你存储一个数字在一个枚举列,数字被作为可能的索引值来对待,并且被存储的值是对应索引的枚举成员。(然而,对LOAD DATA不起作用,其对所有的输入都当作是字符串)如果数字值是引用,它依然被解释为一个索引如果没有匹配的字符串列在枚举值集合中。
因为这样的原因, 定义一个枚举列,其中的枚举值却看起来像数字并不太合适,因为它很容易变的混淆。例如,如下字符串枚举值'0', '1', and '2',但是数字索引值却是 1, 2, and 3:
numbers ENUM('0','1','2')
如果你存储2,它被解释作为一个索引值,并且变为‘1’。如果你存储‘2’,因为其和‘2’匹配,所以被存储为‘2’。如果你存储‘3’,因为不匹配任何值,所以作为索引来对待,变为‘2’。


mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1       |
| 2       |
| 2       |
+---------+
可以使用 SHOW COLUMNS FROM tbl_name LIKE 'enum_col' 来查看枚举可能的所有值。
在C API,枚举值被作为字符串返回。关于使用集合元数据来区分字符串彼此的不同的更多信息,请看27.8.5,”C API数据结构“


Empty or NULL Enumeration Values 空或者NULL枚举值
一个枚举值在如下情况下可以是一个空字符串‘’或者是NULL:
如果你插入一个非法值在一个枚举(也就是,一个字符串没有在允许出现的值列表中),则会用空串来代替错误值。这个字符串能够区别于正常的空串通过实际上字符串的数字值是0.看枚举值的索引值部分了解更多.
>如果严格SQL模式可用,试着插入一个错误的值会报错。
>如果枚举列声明为可以存储NULL,对于列来说NULL是一个合法值,默认值是NULL。如果一个枚举列被声明为NOT NULL,它的默认值是列表允许的第一个值。
Enumeration Sorting 枚举的排序
枚举值的排序是基于他们的索引数字,也就是他们在允许列表中出现的位置。例如,‘b'会排序在’a'之前。对于ENUM('b','a').而空串会排序在非空串之前,而且NULL会排序在所有值之前。
为了阻止未预期的结果,当使用一个枚举值来排序,使用下面这些技术之一:
>根据字符顺序来存储枚举值。
>确保列被存储根据语义而不是索引数字通过coding ORDER BY CAST(col AS CHAR) or ORDER BY CONCAT(col).
Enumeration Limitations 枚举的限制。
一个枚举值不能是一个表达式,即使表达式是一个字符串值。
例如,这个建表语句不起作用,因为CONCAT函数不能用于枚举常量值:
CREATE TABLE sizes (
    size ENUM('small', CONCAT('med','ium'), 'large')
);
你也不能使用一个用户变量作为一个枚举值。这对语句不会有作用:


SET @mysize = 'medium';


CREATE TABLE sizes (
    size ENUM('small', @mysize, 'large')
);
我们强烈推荐你不要使用数字作为枚举值。因为它不会存储超过合适的TINYINT或者SMALLINT类型,并且容易和字符串混合你引用的真实值。如果你使用一个数字作为一个枚举值,总是遇到它被引用的标记。如果引用标记被省略,数字被认为一个索引,关于引用的处理,请看 how even a quoted number could be mistakenly used as a numeric index value.
在定义时给出重复值,会引起一个警告,或是错误,如果是严格SQL模式的话。
---------------------------------------------------
11.4.5 The SET Type
一个集合是一个字符串对象,其中可以有0或者多个值,每个值必须从已经允许的值集合中得到。SET列中的值由逗号分隔的多个集合元素组成。一个序列关于这个是集合元素,但是不包含逗号。
例如,一个列被定义为SET('one', 'two') NOT NULL 可能的值为:
''
'one'
'two'
'one,two'
一个SET 列能由最大64个不同的成员。一个表不能多于255个不同元素列表定义通过他们枚举和SET列考虑为一个分组。更多信息关于这个限制,请看 “Limits Imposed by .frm File Structure”.
重复的值可能是一个警告,或者是错误如果用的是严格SQL模式的话。
当表在创建时关于SET元素尾部的空格会被自动删除。
当查询时,被存储于SET列的值被展示使用列定义的时候使用到的字母。注意SET列能够被设置为 a character set and collation. 对于二进制或者大小写敏感的字符集,自设计列值时,字母的大小写应该考考。
MySQL存储数字的设置值,使用第一个集合成员对应的存储值的低阶位。如果你查询一个集合值在一个数字上下文环境,检索到的值具有与组成列值的集合成员相对应的位元。例如你可以检索数字值如下:
mysql> SELECT set_col+0 FROM tbl_name;
如果一个数字被存储在一个SET列,位值被设置在二进制表示数字定义集合成员在列值中。对于列定义为SET('a','b','c','d'), 成员有如下的二进制和十进制值。
SET Member  Decimal Value Binary Value
'a'            1            0001
'b'            2            0010
'c'            4            0100
'd'            8            1000
如果你设置一个值为9在这个列中,也就是二进制的1001,所以第一和第4集合成员值’a'和‘b'被选中,结果是'a,d'.
对于一个包含多个SET元素的值,它不会匹配列表中你给出的元素的顺序。它也不会匹多次给出的元素。当一个值被查询,在值中的每个元素只出现一次,根据你创建表时列出单的元素的顺序。例如,假设列的定义为SET('a','b','c','d'):
mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
如果你插入的值是 'a,d', 'd,a', 'a,d,d', 'a,d,a', and 'd,a,d':
mysql> INSERT INTO myset (col) VALUES
-> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0
当所有这些值出现作为 'a,d' 当查询时:
mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)
如果你插入的是不支持的值,值被忽略并且产生一个警告:


mysql> INSERT INTO myset (col) VALUES ('a,d,d,s');
Query OK, 1 row affected, 1 warning (0.03 sec)


mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)


mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
6 rows in set (0.01 sec)
如果是严格的SQL模式,则插入非法值会报错。
SET值的排序根据数字。NULL值会排序到所有非NULL值之前。
函数例如SUM()或者AVG(),如果想将一个数字参数转变为一个数字。对于SET值,转变操作可以使用。
正常情况下,你查询SET值使用FIND_IN_SET() 函数或者模糊匹配操作:


mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
第一个语句查找行,其中set_col包含了set成员的值。第二个类似,但是不是完全相同:它找到任何包含值在任何地方,即使是一个子串.
下面的语句是允许的:


mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
第一个查询查找值包含第一个SET元素。第二个查找是精确匹配。小心使用第二种类型。对比'val1,val2' 和'val2,val1'返回不同的值. 你应该使用相同顺序才可以。
使用SHOW COLUMNS FROM tbl_name LIKE set_col 来查看列中可能的所有值.
在C API,SET值被作为字符串返回。更多信息请看Section 27.8.5, “C API Data Structures”.
------------------------------------------------

猜你喜欢

转载自blog.csdn.net/wu1226419614/article/details/79119390
今日推荐