mysql 中 varchar 和 text 的区别
varchar 数据类型
如何理解 varchar(50)
varchar(50)
中的 50 在 mysql5.0 及以上默认是存储的字符数,5.0 以下,默认是字节长度。
varchar 占据的存储空间
varchar
占据的存储空间大概有以下几部分组成:
varchar
类型用来存储【实际字符有多少个】这条信息的存储空间。- 用来存储实际字符内容的存储空间,比如对于 utf-8 编码,每个字符可能占用 1 - 4 个字节,实际有 3 个字符(且每个字符占 3 个字节),那么这部分要占用的存储空间为 3 字符 x 3 字节/字符 = 9 字节。
varchar 最大支持的是 65535 个字节而不是字符
VARCHAR 能存储的最大长度会因为你在表定义中使用的字符集不同而发生变化,以 utf-8 为例:
mysql> create table varchar_test2(col_1 varchar(65535))charset=utf8 engine=innodb;
ERROR 1074 (42000): Column length too big for column 'col_1' (max = 21845); use BLOB or TEXT instead
mysql> create table varchar_test2(col_1 varchar(21845))charset=utf8 engine=innodb;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
mysql> create table varchar_test2(col_1 varchar(21844))charset=utf8 engine=innodb;
Query OK, 0 rows affected (0.02 sec)
因此在使用了 UTF-8 的字符集时,VARCHAR
的最大长度为 21844。
ps:我实际测下来只有最大仅支持 16383。
如何选择合适的 varchar 字符长度
在保留一定冗余的前提下,不要给 varchar 设置过大的字符长度
虽然使用 VARCHAR (50)
和 VARCHAR (1000)
存储‘abcd’的存储空间开销是一样的,但是当你在读取数据时,把这些数据读取到内存的过程中,MySQL 数据库需要分配相应大小的内存空间来存放数据。
所以更大的 VARCHAR
列在读取时要使用更大的内存空间,即使它实际上只存储了一丁点数据。
并且在操作这个表的过程中,如果遇到一些聚合(GROUP BY)或排序(ORDER BY)的操作,需要调用内存临时表或磁盘临时表时,性能会更加糟糕。
除此之外给 varchar
设置过大的字符长度还会带来一些其他问题:
- 导致行溢出,而行溢出的数据在读取时需要多一个 IO 操作,也会造成 InnoDB 表空间越来越大。
- InnoDB 中的大字段在做更新和删除操作时,只能进行悲观操作,这会造成并发性能下降。
- MySQL 中的最大行长度是 65535 字节,包含所有类型的列,因此不可能让一个
varchar
类型的字段把空间都占了的。
补充:另外,因为 InnoDB 的数据页默认是 16K,每个页中至少存放 2 行数据,因此建议 VARCHAR
字段的总长度不要超过 8K。
varchar 和 text 的区别
VARCHAR
:- 存储在
VARCHAR
类型字段中的数据是按照实际长度存储 - 在某些情况下,
VARCHAR
可能会占用更少的存储空间,因为它只存储实际使用的字节数。
- 存储在
TEXT
:TEXT
是用于存储大块文本数据的数据类型,可以存储最大长度为 64KB 的数据。TEXT
类型的字段占用固定的存储空间TEXT
数据在存储时会进行额外的处理和管理,因此可能会有轻微的性能开销。
总的来说,如果您需要存储较小的文本数据,VARCHAR
可能在性能方面更优,因为它占用的存储空间可能会较小。但是需要注意的是,当数据超过了 VARCHAR
定义的长度时,会进行截断处理,导致部分数据丢失。
如果您需要存储大块的文本数据,或者数据的长度不确定,使用 TEXT
类型更为合适。TEXT
类型不会对数据进行截断处理,并且为了性能更好地处理文本数据,还可以结合使用全文索引等技术。
参考
- https://www.imooc.com/read/88/article/2357