当我们在mysql中使用VARCHAR
列创建表时,我们必须为其设置长度。但对于TEXT
类型,我们不必提供长度。
VARCHAR
和TEXT
之间有什么区别?
答案 0 :(得分:403)
<强> TEXT
强>
c
个字节的磁盘空间,其中c
是存储字符串的长度。 <强> VARCHAR(M)
强>
M
个字符的最大变量M
需要介于1到65535之间c
字节(对于M
≤255)或2 + c
(对于256≤M
≤65535)磁盘空间的字节{{1 }}是存储字符串的长度 c
的固定最大大小为TEXT
个字符
2¹⁶-1 = 65535
的变量最大尺寸VARCHAR
最多 M
。
因此,您无法选择M = 2¹⁶-1
的大小,但可以选择TEXT
。
另一个区别是,您无法在VARCHAR
列上放置索引(全文索引除外)。
因此,如果您希望在列上有索引,则必须使用TEXT
。但请注意,索引的长度也是有限的,因此如果您的VARCHAR
列太长,则必须仅使用索引中VARCHAR
列的前几个字符(请参阅{的文档{3}})。
但是如果您知道可能的输入字符串的最大长度仅为VARCHAR
,您还希望使用VARCHAR
,例如电话号码或姓名或类似的东西。然后,您可以使用M
代替VARCHAR(30)
或TINYTEXT
,如果有人试图在您的电话号码栏中保存所有三个“指环王”书籍的文字,则只存储第一个30个字符:)
修改:如果要存储在数据库中的文本超过65535个字符,则必须选择TEXT
或MEDIUMTEXT
,但要小心:{{ 1}}存储最多16 MB的字符串,LONGTEXT
最多4 GB。如果您使用MEDIUMTEXT
并通过PHP获取数据(至少如果您使用LONGTEXT
而不是LONGTEXT
),则可能会出现内存分配错误,因为PHP会尝试分配4 GB的内存确保整个字符串可以缓冲。这可能也发生在除PHP以外的其他语言中。
但是,您应始终检查输入(是否太长?是否包含奇怪的代码?)
注意:对于这两种类型,所需的磁盘空间仅取决于存储的字符串的长度,而不取决于最大长度。
例如如果你使用charset latin1并将文本“Test”存储在mysqli
,store_result
和VARCHAR(30)
中,它总是需要5个字节(1个字节来存储)字符串的长度和每个字符的1个字节)。如果将相同的文本存储在VARCHAR(100)
或TINYTEXT
列中,它也需要相同的空间,但在这种情况下,它将是6个字节(2个字节用于存储字符串长度和每个字符1个字节。)
有关详细信息,请查看CREATE INDEX
。
最后,我想添加一个通知,VARCHAR(2000)
和TEXT
都是可变长度数据类型,因此它们最有可能最小化存储数据所需的空间。但这需要权衡性能。如果您需要更好的性能,则必须使用固定长度类型,如TEXT
。您可以阅读有关此documentation的更多信息。
答案 1 :(得分:23)
上面的答案中有一个重要的细节被省略了。
MySQL对max size of each row施加了65,535字节的限制。
VARCHAR
列的大小计入最大行大小,而假设TEXT
列通过引用存储其数据,因此它们仅需要9-12个字节。这意味着即使您的VARCHAR
字段的“理论上”最大大小为65,535个字符,如果表中有多个列,您也将无法实现。
还请注意,VARCHAR
字段所需的实际字节数取决于列(和内容)的编码。 MySQL将使用的最大可能字节计为最大行大小,因此,如果您使用像utf8mb4
(which you almost certainly should)这样的多字节编码,它将用尽最大行大小。
更正:不管MySQL如何计算最大行大小,VARCHAR
/ TEXT
字段数据是否实际存储在行中还是通过引用存储取决于您的底层存储引擎。对于InnoDB,row format影响此行为。 (感谢Bill-Karwin)
使用TEXT
的原因:
使用VARCHAR
的原因: