在实际的项目中,我们还经常遇到一种数据,就是字符串数据。
MySQL中,文本字符串总体上分为 CHAR 、 VARCHAR 、 TINYTEXT 、 TEXT 、 MEDIUMTEXT 、 LONGTEXT 、 ENUM 、 SET 等类型。
图片.png

CHAR与VARCHAR类型

CHAR和VARCHAR类型都可以存储比较短的字符串。
图片.png

CHAR类型:

CHAR(M) 类型一般需要预先定义字符串长度。如果不指定(M),则表示长度默认是1个字符。如果保存时,数据的实际长度比CHAR类型声明的长度小,则会在 右侧填充 空格以达到指定的长度。当MySQL检索CHAR类型的数据时,CHAR类型的字段会去除尾部的空格。定义CHAR类型字段时,声明的字段长度即为CHAR类型字段所占的存储空间的字节数。

VARCHAR类型:

VARCHAR(M) 定义时, 必须指定 长度M,否则报错。
MySQL4.0版本以下,varchar(20):指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) ;MySQL5.0版本以上,varchar(20):指的是20字符。检索VARCHAR类型的字段数据时,会保留数据尾部的空格。VARCHAR类型的字段所占用的存储空间为字符串实际长度加1个字节。

哪些情况使用 CHAR 或 VARCHAR 更好图片.png
情况1:存储很短的信息。比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的,结果得不偿失。
情况2:固定长度的。比如使用uuid作为主键,那用char应该更合适。因为他固定长度,varchar动态根据长度的特性就消失了,而且还要占个长度信息。
情况3:十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。
情况4:具体存储引擎中的情况:
1,MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定
长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。这样使得整
个表静态化,从而使 数据检索更快 ,用空间换时间。
2,MEMORY 存储引擎和数据列:MEMORY数据表目前都使用
固定长度的数据行存储,因此无论使用CHAR或VARCHAR列
都没有关系,两者都是作为CHAR类型处理的。
3,InnoDB 存储引擎,建议使用VARCHAR类型。因为
对于InnoDB数据表,内部的行存储格式并没有区 分固定长度和可变
长度列(所有数据行都使用指向数据列值的头指针),而且
主要影响性能的因素 是数据行使用的存储总量,由于char平均占
用的空间多于varchar,所以除了简短并且固定长度的,
4,其他考虑varchar。这样节省空间,对磁盘I/O和数据存储总量比较好。

TEXT类型

在MySQL中,TEXT用来保存文本类型的字符串,总共包含4种类型,分别为TINYTEXT、TEXT、 MEDIUMTEXT 和 LONGTEXT 类型。 在向TEXT类型的字段保存和查询数据时,系统自动按照实际长度存储,不需要预先定义长度。这一点和VARCHAR类型相同。
每种TEXT类型保存的数据长度和所占用的存储空间不同,如下:
图片.png由于实际存储的长度不确定,MySQL 不允许 TEXT 类型的字段做主键。遇到这种情况,你只能采用CHAR(M),或者 VARCHAR(M)。

开发中经验:

TEXT文本类型,可以存比较大的文本段,搜索速度稍慢,因此如果不是特别大的内容,建议使用CHAR, VARCHAR来代替。还有TEXT类型不用加默认值,加了也没用。而且text和blob类型的数据删除后容易导致 “空洞”,使得文件碎片比较多,所以频繁使用的表不建议包含TEXT类型字段,建议单独分出去,单独用一个表。

ENUM类型

ENUM类型也叫作枚举类型,ENUM类型的取值范围需要在定义字段时进行指定。设置字段值时,ENUM类型只允许从成员中选取单个值,不能一次选取多个值。
其所需要的存储空间由定义ENUM类型时指定的成员个数决定。
图片.png1,当ENUM类型包含1~255个成员时,需要1个字节的存储空间;
2,当ENUM类型包含256~65535个成员时,需要2个字节的存储空间。
3,ENUM类型的成员个数的上限为65535个。

  1. CREATE TABLE test_enum(
  2. season ENUM('春','夏','秋','冬','unknow')
  3. );
  4. INSERT INTO test_enum
  5. VALUES('春'),('秋');
  6. SELECT * FROM test_enum;
  7. #Data truncated for column 'season' at row 1
  8. INSERT INTO test_enum
  9. VALUES('春,秋');
  10. #Data truncated for column 'season' at row 1
  11. INSERT INTO test_enum
  12. VALUES('人');
  13. INSERT INTO test_enum
  14. VALUES('unknow');
  15. #忽略大小写的
  16. INSERT INTO test_enum
  17. VALUES('UNKNOW');
  18. #可以使用索引进行枚举元素的调用
  19. INSERT INTO test_enum
  20. VALUES(1),('3');
  21. # 没有限制非空的情况下,可以添加null值
  22. INSERT INTO test_enum
  23. VALUES (NULL);

SET类型

SET表示一个字符串对象,可以包含0个或多个成员,但成员个数的上限为 64 。设置字段值时,可以取取值范围内的 0 个或多个值。
当SET类型包含的成员个数不同时,其所占用的存储空间也是不同的,具体如下:
图片.pngSET类型在存储数据时成员个数越多,其占用的存储空间越大。注意:SET类型在选取成员时,可以一次选择多个成员,这一点与ENUM类型不同。

CREATE TABLE test_set(
s SET ('A', 'B', 'C')
);

INSERT INTO test_set (s) VALUES ('A'), ('A,B');

#插入重复的SET类型成员时,MySQL会自动删除重复的成员
INSERT INTO test_set (s) VALUES ('A,B,C,A');

#向SET类型的字段插入SET成员中不存在的值时,MySQL会抛出错误。
INSERT INTO test_set (s) VALUES ('A,B,C,D');

SELECT *
FROM test_set;


CREATE TABLE temp_mul(
gender ENUM('男','女'),
hobby SET('吃饭','睡觉','打豆豆','写代码')
);

INSERT INTO temp_mul
VALUES('男','睡觉,打豆豆');

SELECT * 
FROM temp_mul;

#Data truncated for column 'gender' at row 1
INSERT INTO temp_mul
VALUES('男,女','睡觉,打豆豆');