MySQL中VARCHAR和TEXT的区别
MySQL中VARCHAR和TEXT的区别
这个问题已经在此处有答案:
当我们在MySQL中创建一个表时,如果有一个VARCHAR
列,我们必须为其设置长度。但是对于TEXT
类型,我们不需要提供长度。
VARCHAR
和TEXT
有什么区别?
在以上答案中漏掉了一个重要细节。
MySQL对于每行的最大大小有一个限制,即65,535字节。 VARCHAR列的大小计入最大行大小,而TEXT
列被认为是通过引用存储它们的数据,因此只需要9-12个字节。这意味着即使您的VARCHAR
字段的“理论”最大大小为65,535个字符,如果您的表中有多个列,您也无法实现该大小。
另请注意,VARCHAR
字段所需的实际字节数取决于列的编码(以及内容)。MySQL将用于最大行大小的最大可能字节数进行计数,因此,如果您使用像utf8mb4
这样的多字节编码(您几乎可以肯定需要这样做),它将使用您最大行大小的更多字节数。
更正:无论MySQL如何计算最大行大小,VARCHAR
/TEXT
字段数据实际上是否存储在行中或由引用存储取决于您的底层存储引擎。对于InnoDB,行格式会影响此行为。 (感谢Bill-Karwin)
使用TEXT
的原因:
- 如果您想存储一段或多段文本
- 如果您不需要对该列进行索引
- 如果您已达到表的行大小限制
使用VARCHAR
的原因:
- 如果您想存储几个单词或一个句子
- 如果您要对(整个)列进行索引
- 如果您要在外键约束中使用该列
TL;DR
TEXT
- 最大长度为65535个字符(无法限制最大长度)
- 占用2+
c
个字节的磁盘空间,其中c
是存储字符串的长度。 - 不能成为完整的索引的一部分。需要指定前缀长度。
VARCHAR(M)
- 最大长度为
M
个字符(可变长度) M
的值必须在1到65535之间- 占用1+
c
个字节(对于M
≤255)或2+c
个字节(对于256≤M
≤65535)的磁盘空间,其中c
是存储字符串的长度 - 可以成为索引的一部分
更多细节
TEXT
类型的最大长度为固定的2¹⁶-1 = 65535
个字符。
VARCHAR
类型的最大长度M
可变,最大为M = 2¹⁶-1
。
因此,你不能选择TEXT
类型的长度,但你可以选择VARCHAR
类型的长度。
另一个不同之处在于,TEXT
列上无法放置索引(除了全文索引)。
因此,如果你想在列上创建索引,必须使用VARCHAR
类型。但请注意,索引的长度也受到限制,因此,如果你的VARCHAR
列太长,你必须在索引中只使用前几个字符(请参阅CREATE INDEX
的文档)。
但是如果你知道可能输入的字符串的最大长度仅为M
,例如电话号码或姓名之类,那么可以使用VARCHAR(30)
代替TINYTEXT
或TEXT
,如果有人试图在你的电话号码列中将三部《指环王》的所有文本保存下来,你只会保存前30个字符:)
编辑:如果你要存储的文本长度超过65535个字符,则必须选择MEDIUMTEXT
或LONGTEXT
,但请注意:MEDIUMTEXT
可存储最长为16 MB的字符串,LONGTEXT
最长可存储4 GB。如果你使用LONGTEXT
并通过PHP获取数据(至少如果使用mysqli
而没有使用store_result
),你可能会遇到内存分配错误,因为PHP尝试分配4 GB的内存以确保可以缓冲整个字符串。这也可能发生在PHP之外的其他语言中。
尽管如此,在将其存储在数据库中之前,你应该始终检查输入(是否过长?是否包含奇怪的代码?)。
请注意:对于这两种类型,所需的磁盘空间仅取决于存储字符串的长度,而不是最大长度。
例如,如果你使用的字符集是latin1并在VARCHAR(30)
、VARCHAR(100)
和TINYTEXT
中存储文本“Test”,它始终需要5个字节(1个字节用于存储字符串的长度,每个字符需要1个字节)。如果你将相同的文本存储在VARCHAR(2000)
或TEXT
列中,它也将需要相同的空间,但在这种情况下,它将需要6个字节(2个字节用于存储字符串的长度,每个字符需要1个字节)。
想要了解更多信息,请查看文档。
最后我想指出一个注意事项,即TEXT
和VARCHAR
都是可变长度的数据类型,所以它们很可能会最小化您存储数据所需的空间。但这会导致性能上的折衷。如果您需要更好的性能,则必须使用固定长度类型,如CHAR
。您可以在此处阅读更多相关信息。