mysql中VARCHAR和TEXT之间的区别

时间:2014-08-14 05:45:30

标签: mysql text varchar

当我们在mysql中使用VARCHAR列创建表时,我们必须为其设置长度。但对于TEXT类型,我们不必提供长度。

VARCHARTEXT之间有什么区别?

2 个答案:

答案 0 :(得分:403)

TL; DR

<强> TEXT

  • 固定最大尺寸为65535个字符(不能限制最大尺寸)
  • 占用2 + c个字节的磁盘空间,其中c是存储字符串的长度。
  • 不能成为索引的一部分

<强> VARCHAR(M)

  • M个字符的最大变量
  • M需要介于1到65535之间
  • 需要1 + 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个字符,则必须选择TEXTMEDIUMTEXT,但要小心:{{ 1}}存储最多16 MB的字符串,LONGTEXT最多4 GB。如果您使用MEDIUMTEXT并通过PHP获取数据(至少如果您使用LONGTEXT而不是LONGTEXT),则可能会出现内存分配错误,因为PHP会尝试分配4 GB的内存确保整个字符串可以缓冲。这可能也发生在除PHP以外的其他语言中。

但是,您应始终检查输入(是否太长?是否包含奇怪的代码?)

注意:对于这两种类型,所需的磁盘空间仅取决于存储的字符串的长度,而不取决于最大长度。
例如如果你使用charset latin1并将文本“Test”存储在mysqlistore_resultVARCHAR(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将使用的最大可能字节计为最大行大小,因此,如果您使用像utf8mb4which you almost certainly should)这样的多字节编码,它将用尽最大行大小。

更正:不管MySQL如何计算最大行大小,VARCHAR / TEXT字段数据是否实际存储在行中还是通过引用存储取决于您的底层存储引擎。对于InnoDB,row format影响此行为。 (感谢Bill-Karwin)

使用TEXT的原因:

  • 如果您要存储一段或更多的文字
  • 如果您不需要为该列编制索引
  • 如果您已达到表格的行大小限制

使用VARCHAR的原因:

  • 如果要存储一些单词或句子
  • 如果要索引(整个)列
  • 如果要使用具有外键约束的列