MySQL数据类型 - 字符串数据类型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL数据类型 - 字符串数据类型相关的知识,希望对你有一定的参考价值。
1.ENUM类型
ENUM是一个字符串对象,其值从允许值列表中选择,创建表时,这些允许的值在列定义中明确列出。
ENUM类型具有以下优点:
●在列具有有限可能值的情况下压缩数据存储。指定为输入值的字符串将自动编码为数字。
●查询和输出可读性强。在查询结果中这些数字被转换回相应的字符串。
需要考虑的潜在问题:
创建和使用ENUM列
枚举值必须是带引号的字符串文本。例如,可以创建一个具有ENUM列的表:
将100万行值为‘medium‘的记录插入此表将需要100万字节的存储空间,而如果将实际字符串‘medium‘存储在VARCHAR列中,则需要600万字节的存储空间。
枚举文本的索引值
每个枚举值都有一个索引:
●列定义中的枚举元素被分配了索引号,从1开始。
●空字符串(‘‘)错误值的索引值为0。这意味着您可以使用以下SELECT语句查找分配了无效ENUM值的行:
●NULL值的索引为NULL。
●这里的术语"index"是指枚举值列表中的一个位置。它与表索引无关。
例如,定义为ENUM(‘Mercury‘, ‘Venus‘, ‘Earth‘)的列可以具有此处显示的任何值。还显示了每个值的索引。
值 | 索引 |
---|---|
NULL | NULL |
‘‘ | 0 |
‘Mercury‘ | 1 |
‘Venus‘ | 2 |
‘Earth‘ | 3 |
ENUM列最多可以有65535个不同元素。
如果在数值上下文中检索ENUM值,则返回列值的索引。例如,可以从ENUM列中检索数值,如下所示:
类似SUM()或AVG()这样的函数需要数值参数,在必要时会将参数转换为数字。对于ENUM值,将在计算中使用索引号。
枚举字面量的处理
创建表时,将自动从表定义中的ENUM成员值中删除尾随空格。
检索时,存储在ENUM列中的值将使用列定义中使用的字母大小写显示。请注意,可以为ENUM列分配字符集和排序规则。对于二进制或区分大小写的排序规则,将值分配给列时将考虑字母大小写。
如果将数字存储到ENUM列中,则该数字将被视为可能的索引值,并且存储的值是具有该索引的枚举成员。(但是,这对于LOAD DATA语句不起作用,因为此语句将所有输入都视为字符串。)如果数值被引号引起来,则如果枚举值列表中没有匹配的字符串,则仍将其解释为索引。由于这些原因,不建议使用看起来像数字的ENUM值定义枚举列,因为这很容易使人混淆。例如,以下列具有枚举成员"0"、"1"和"2",但数字索引值为1、2和3:
如果存储2,它将被解释为一个索引值,并变为"1"(索引值是2)。如果存储‘2‘,则它与枚举值匹配,因此存储为‘2‘。如果存储‘3‘,则它与任何枚举值都不匹配,因此它被视为索引并变为‘2‘(索引值是3)。
要确定ENUM列的所有可能值,请使用SHOW COLUMNS FROM tbl_name LIKE ‘enum_col‘并在查询结果的Type列中解析ENUM定义。
空或NULL枚举值
枚举值在某些情况下也可以是空字符串(‘‘)或NULL值:
●如果将无效值插入ENUM(即,允许值列表中不存在的字符串),则会将空字符串作为特殊错误值插入。此字符串与"普通"空字符串的区别在于此字符串的数值为0。
如果启用了严格SQL模式,则尝试插入无效的ENUM值将导致错误。
●如果ENUM列声明为允许NULL,则NULL值是该列的有效值,默认值为NULL。如果ENUM列声明为NOT NULL,则其默认值是允许值列表的第一个元素。
枚举排序
ENUM值根据其索引号进行排序,索引号取决于列定义中列出枚举成员的顺序。例如,对于 ENUM(‘b‘, ‘a‘),‘b‘排序在‘a‘之前。空字符串排序在非空字符串之前,NULL值排序在所有其他枚举值之前。
为了防止在ENUM列上使用ORDER BY子句时出现意外结果,可以使用以下技术之一:
●按字母顺序指定枚举列表。
●通过ORDER BY CAST(col AS CHAR) 或者 ORDER BY CONCAT(col)语句确保列是按词汇顺序排序的,而不是按索引号排序。
枚举限制
枚举值不能是表达式,甚至不能是计算结果为字符串值的表达式。
例如,下面的CREATE TABLE语句不起作用,因为CONCAT函数不能用于构造枚举值:
也不能将用户变量用作枚举值。下面的语句不起作用:
强烈建议您不要使用数字作为枚举值,因为它不能保存在适当的TINYINT或SMALLINT类型中,而且如果不正确地引用枚举值,很容易混淆字符串和隐含的数字值(可能不同)。如果使用数字作为枚举值,请始终将其括在引号中。如果省略引号,则该数字视为索引。
定义中的重复值会导致警告,如果启用了严格SQL模式,则会导致错误。
2.SET类型
SET是一个字符串对象,可以有零个或多个值,每个值都必须从创建表时指定的允许值列表中选择。SET列值由多个集合成员组成,它们由逗号(,)分隔。其结果是,成员值本身不应包含逗号。
例如,列指定为SET(‘one‘, ‘two‘) NOT NULL可以具有以下任何值:
一个集合列最多可以有64个不同的成员。
定义中的重复值会引起警告,如果启用了严格SQL模式,则会导致错误。
创建表时,将自动从表定义中的集合成员值中删除尾随空格。
有关SET类型的存储要求,请参见字符串类型存储要求。
检索时,存储在集合列中的值将使用列定义中使用的字母大小写显示。请注意,可以为集合列分配字符集和排序规则。对于二进制或区分大小写的排序规则,将值分配给列时将考虑字母大小写。
mysql以数字方式存储SET值,存储值的最低位对应于第一个集合成员。如果在数字上下文中检索一个集合值,则检索到的值具有与构成列值的集合成员相对应的位集。例如,可以从如下所示的集合列中检索数值:
如果一个数字存储在SET列中,则在该数字的二进制表示形式中设置的位决定了列值中的集合成员。对于指定为SET(‘a‘,‘b‘,‘c‘,‘d‘)的列,成员具有以下十进制和二进制值。
SET 成员 | 十进制值 | 二进制值 |
---|---|---|
‘a‘ | 1 | 0001 |
‘b‘ | 2 | 0010 |
‘c‘ | 4 | 0100 |
‘d‘ | 8 | 1000 |
如果将值9赋给此列,即二进制的1001,则选择第一个和第四个SET值成员‘a‘和‘d‘,结果值为‘a,d‘。
对于包含多个集合元素的值,插入该值时元素的列出顺序并不重要。给定元素在值中列出的次数也无关紧要。稍后检索该值时,该值中的每个元素都会出现一次,其中的元素将根据在表创建时指定它们的顺序列出。假设列被指定为SET(‘a‘,‘b‘,‘c‘,‘d‘):
如果分别插入值‘a,d‘,‘d,a‘,‘a,d,d‘,‘a,d,a‘和‘d,a,d‘:
当检索时所有值都显示为‘a,d‘:
如果将SET列设置为不支持的值,则忽略该值并发出警告:
如果启用了严格SQL模式,则尝试插入无效的SET值将导致错误。
SET值按数字排序。NULL值的排序在非NULL集合值之前。
类似SUM()或AVG()等需要数值参数的函数,在必要时将参数转换为数字。对于SET值,将转换成数值使用。
通常,使用FIND_IN_SET()函数或LIKE运算符搜索SET值:
第一条语句查找set_col包含集合成员‘value‘的行。第二个类似,但不完全一样:它查找set_col在任何部分包含‘value‘的行,甚至是另一个集合成员的子字符串。
还允许以下语句:
这些语句中的第一个语句查找包含第一个集合成员的值。第二个要查找一个精确匹配值。要当心第二种类型的比较。将集合值与‘val1,val2‘进行比较所返回的结果与将值与‘val2,val1‘进行比较所返回的结果不同。应该按照列定义中列出的顺序指定值。
若要确定集合列的所有可能值,请使用SHOW COLUMNS FROM tbl_name LIKE set_col 语句并分析输出的Type列中的集合定义。
英文版地址:
https://dev.mysql.com/doc/refman/8.0/en/enum.html
以上是关于MySQL数据类型 - 字符串数据类型的主要内容,如果未能解决你的问题,请参考以下文章