MySQL 中的字符串类型
字符类型包括: CHAR 与 VARCHARCHAR(m) m 取值范围 0~255。列宽固定,存储时字符串右边会补空格,取出时自动去掉空格,除非开启了 PAD_CHAR_TO_FULL_LENGTH。 对于值未超出的情况,VARCHAR 在存储及查询时皆会完整保留末尾的空格字符。 VARCHAR(m) m 取值范围 0~65535,不定长度,根据存储的值而定,但上限为 m。存储时,会在值的前面预留一到两位用来存储字符串长度。0~255时预留一位,超过的情况使用两位来标识所存储的字符串的长度 在非严格模式下,超过的非空格值会自动截断来存储,同时生成警告信息。建议开启严格模式以避免这种不完整数据的产生。 对于超出的空格值,VARCHAR 会在插入钱截断并产生警告信息,而对于 CHAR 则没有警告信息,直接静默截断存储。 以下表格以 m为4的情况展示了 非严格模式下 CHAR,VARCHAR 在存储不同长度字符串时的表现。
以下代码展示了两者在查询时对于末尾空格的处理情况。 mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4)); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO vc VALUES ('ab ', 'ab '); Query OK, 1 row affected (0.00 sec) mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc; +---------------------+---------------------+ | CONCAT('(', v, ')') | CONCAT('(', c, ')') | +---------------------+---------------------+ | (ab ) | (ab) | +---------------------+---------------------+ 1 row in set (0.06 sec) 在进行排序和字符串比较时,具体表现和使用的字符集(character set collation )有关。 Pad 属性Pad 即字符串长度不够时的补齐操作,一般是添加空格。大部分字符集都有一个 可通过查询 补齐属性直接影响非二进制字符串(CHAR, VARCHAR, and TEXT)进行比较时的末尾的空白会如何处理。 对于 mysql> CREATE TABLE names (myname CHAR(10)); Query OK, 0 rows affected (0.03 sec) mysql> INSERT INTO names VALUES ('Monty'); Query OK, 1 row affected (0.00 sec) mysql> SELECT myname = 'Monty', myname = 'Monty ' FROM names; +------------------+--------------------+ | myname = 'Monty' | myname = 'Monty ' | +------------------+--------------------+ | 1 | 1 | +------------------+--------------------+ 1 row in set (0.00 sec) mysql> SELECT myname LIKE 'Monty', myname LIKE 'Monty ' FROM names; +---------------------+-----------------------+ | myname LIKE 'Monty' | myname LIKE 'Monty ' | +---------------------+-----------------------+ | 1 | 0 | +---------------------+-----------------------+ 1 row in set (0.00 sec) 对于要求列值要求在记录中唯一( BINARY 与 VARBINARY基本与 CHAR 和 VARCHAR 类似,不同点在于存储的是二进制字符值。存储长度的取值范围也一样,只是单位是字节而不是字符。 写入时对于超出限制的值,会自动截断,除非开启 MySQL 的严格模式,此时会报错而非截断后成功写入。 对于 以下代码展示了自动补零在存取时的表现, mysql> CREATE TABLE t (c BINARY(3)); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t SET c = 'a'; Query OK, 1 row affected (0.01 sec) mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t; +--------+---------+-------------+ | HEX(c) | c = 'a' | c = 'a\0\0' | +--------+---------+-------------+ | 610000 | 0 | 1 | +--------+---------+-------------+ 1 row in set (0.09 sec) 所以如果你期望查询时得到与存储时一致的值,最好使用 BLOB 与 TEXT 类型BLOB (binary large object) 即大型二进制形式的对象,用于数据量大的情况。BLOB 大类中具体包含:TINYBLOB, BLOB, MEDIUMBLOB 以及 LONGBLOB 四种数据类型,他们只存在存储上限的区别。 文本类型 BLOB 类型内部处理时以二进制字符串的形式处理,在进行比较操作或排序时,按其表示的二进制数字来进行。而 TEXT 类型表示非二进制字符,在进行比较或排序时与字符集有关。 非严格模式下写入一个超出长度的值时,会自动截断后存入,同时生成警告信息,这一行为可通过开启严格模式来避免。 其中对于 TEXT 类型,截取末尾的空格字符时始终生成警告信息,与 MySQL 当前设置的模式无关。 一般来说你可把 BLOB 看作是 VARBLOB,存储任意大的数据。TEXT 同理,可看成 VARCHAR。但还是有一些区别的:
因为 BLOB 和 TEXT 所存的值有可能很大,实际使用时会遇到些限制,比如
mysql> SET max_sort_length = 2000; mysql> SELECT id, comment FROM t -> ORDER BY comment;
ENUM 类型枚举值类型通过在创建表时指定该类型可接受的合法值列表,相比一般的字符类型有以下优势:
枚举的创建与使用枚举中的项通过单引号指定,以下是一个创建和使用枚举类型的示例: 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; 不支持在创建时使用表达式,比如下面这样是不行的: # 🚨 CREATE TABLE sizes ( size ENUM('small', CONCAT('med','ium'), 'large') ); # 🚨 SET @mysize = 'medium'; CREATE TABLE sizes ( size ENUM('small', @mysize, 'large') ); 枚举项的数字值枚举列表中每项都对应一个数字值,是一个从 1 开始的索引值。枚举类型最多可包含 65,535 个候选项。 对于写入的非法值会存储成 0,所以可通过查询为 0 的列找出所有这些非法的记录。 mysql> SELECT * FROM tbl_name WHERE enum_col=0; NULL 的索引值是 NULL。 以
在需要数字的上下文中,枚举类型返回时会自动处理成数字,譬如: mysql> SELECT enum_col+0 FROM tbl_name; 插入时,数字类型的值会自动与枚举中的索引对应,如果插入的数字带引号,即尝试以字符串形式存入,MySQL 会先从枚举列表中找,如果找不到相应的匹配项,会将这个插入值当索引处理。所以尽量不要设置数字类型的枚举,这导致存取时一些不可预测的情况发生。比如: numbers ENUM('0','1','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’ 可在结果中的 mysql> SHOW COLUMNS FROM enum_test LIKE 'n'; +-------+-------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------------+------+-----+---------+-------+ | n | enum('0','1','2') | YES | | NULL | | +-------+-------------------+------+-----+---------+-------+ 1 row in set (0.00 sec) 排序规则排序时根据其在枚举列表中的索引来定。比如 空字符串会排在非空值前面,NULL 值在所有值前面。 SET 类型SET 类型是一组字符串值,它的值类似于枚举,必需是定义表时指定的候选值中所列出的值,不同点在于它可同时支持设置多个候选值,用逗号分隔(同时意味着候选值自身不能包含逗号)。 比如类型为定义为 '' 'one' 'two' 'one,two'
内部存储时其实存的是一个字节表。每个候选值都对应一个二进制值中的一位。比如定义如下的表: CREATE TABLE set_test( rowid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, myset SET('Travel','Sports','Dancing','Fine Dining') ); 每个值对应一个二进制位数值,所以每个候选值也对应一个计算后的数字。
这样在设置时,如果设置的是数字,会解析成对应的二进制形式,比如 9=8+1,对应 同时 9 的二进制表示是 在设置时不关心候选值的顺序及次数,多次指定同一个候选值最终只会出现一次。 mysql> CREATE TABLE myset (col SET('a', 'b', 'c', '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 mysql> SELECT col FROM myset; +------+ | col | +------+ | a,d | | a,d | | a,d | | a,d | | a,d | +------+ 5 rows in set (0.04 sec) 通过 mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0; mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%'; 以下用法也是可行的: mysql> SELECT * FROM tbl_name WHERE set_col & 1; mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2'; 相关资源 |
原文地址:https://www.cnblogs.com/Wayou/p/mysql_data_type_string.html
相关推荐
-
更改用户host留下的坑 服务器
2020-7-5
-
Centos安装supervisor,守护Redis进程 服务器
2019-8-16
-
Linux基本命令 服务器
2019-8-16
-
sudo 与输出重定向 服务器
2019-5-11
-
QEMU/KVM磁盘在线备份 服务器
2020-7-16
-
Linux 中改变主机名的 4 种方法 服务器
2019-5-6
-
Galera Cluster原理 服务器
2019-3-18
-
利用PowerShell监控Win-Server性能 服务器
2019-8-19
-
Go range实现理及性能优化剖析 服务器
2020-6-22
-
12 个有趣的 Linux 终端命令 服务器
2020-5-25