mysql中VARCHAR和TEXT之间的区别

use*_*485 258 mysql varchar text

当我们在mysql中创建一个包含VARCHAR列的表时,我们必须为它设置长度.但对于TEXT类型我们不必提供长度.

VARCHAR和之间有什么区别TEXT

Abc*_*hen 481

TL; DR

TEXT

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

VARCHAR(M)

  • 变量最大M字符数
  • M 需要在1到65535之间
  • 需要1 + c字节(对于M≤255)或2 + c(对于M256≤≤65535)磁盘空间字节,其中c是存储字符串的长度
  • 可以是索引的一部分

更多细节

TEXT具有固定的最大2¹?-1 = 65535字符大小.
VARCHAR有一个可变的最大尺寸M 可达 M = 2¹?-1.
所以你不能选择大小,TEXT但你可以选择VARCHAR.

另一个区别是,您不能在TEXT列上放置索引(全文索引除外).
因此,如果您想在列上有索引,则必须使用VARCHAR.但请注意,索引的长度也是有限的,因此如果VARCHAR列太长,则必须仅使用VARCHAR索引中列的前几个字符(请参阅文档CREATE INDEX).

但是VARCHAR如果你知道可能的输入字符串的最大长度是M,例如电话号码或名称或类似的东西,你也想使用.然后你可以使用VARCHAR(30)而不是TINYTEXTTEXT如果有人试图在你的电话号码栏中保存所有三个"指环王"书籍的文本你只存储前30个字符:)

编辑:如果要存储在数据库中的文本长度超过65535个字符,则必须选择MEDIUMTEXTLONGTEXT,但要小心:MEDIUMTEXT存储最大16 MB的字符串,LONGTEXT最多4 GB.如果您LONGTEXT通过PHP 使用并获取数据(至少如果您mysqli不使用store_result),则可能会出现内存分配错误,因为PHP会尝试分配4 GB内存以确保整个字符串可以缓冲.这可能也发生在除PHP以外的其他语言中.

但是,在将数据存储到数据库之前,您应该始终检查输入(它是否太长?它是否包含奇怪的代码?).

注意:对于这两种类型,所需的磁盘空间仅取决于存储的字符串的长度,而不取决于最大长度.
例如,如果您使用charset latin1并将文本"Test"存储在VARCHAR(30),VARCHAR(100)并且TINYTEXT,它总是需要5个字节(1个字节用于存储字符串的长度,1个字节用于每个字符).如果在a VARCHAR(2000)TEXT列中存储相同的文本,它也需要相同的空间,但在这种情况下,它将是6个字节(2个字节用于存储字符串长度,1个字节用于每个字符).

有关更多信息,请查看文档.

最后,我想补充的通知,这两个,TEXT并且VARCHAR都是可变长度的数据类型,因此他们最有可能减少需要存储数据的空间.但这需要权衡性能.如果你需要更好的性能,你必须使用固定长度类型CHAR.你可以在这里阅读更多相关信息.

  • @SolomonUcko当您想要创建一个具有两个最大大小字符串列的表时,您需要使用TEXT,这意味着它们都可能需要65535个字符。您不能在一行中同时使用两个具有最大大小的 varchar,因为 MySQL 限制了最大行大小,即 65535。但是您可以在一行中使用两个 TEXT,因为 TEXT 只为行大小限制贡献 9 到 12 个字节, TEXT 的内容与行的其余部分分开存储。 (28认同)
  • `TEXT`优于`VARCHAR`的优点是什么? (11认同)
  • @AbcAeffchen我相信我明白了你的意思。基本上,“固定最大尺寸”意味着您根本无法设置尺寸-即使您不想支持这么大的尺寸,也始终为65535。这意味着TEXT是VARCHAR字段的简写形式,最大大小为2 1 -1,而忽略了索引问题。我明白吗? (3认同)
  • 请注意,如果 VARCHAR 列使用 utf-8 排序规则(每个字符 3 个字节),则最多只能包含 21844 个字符 (65535/3 = 21844)。 (3认同)
  • 不可以,固定长度的CHAR无法提供任何明显的性能提升。(这来自一个关于MyISAM表的老太太的故事;即使在那儿,它的有效性也令人怀疑。) (2认同)
  • 此外,`TEXT` 不能有默认值,而 `VARCHAR` 可以。请参阅[为什么在 MySQL 中文本列不能有默认值?- 堆栈溢出](/sf/ask/242681071/) (2认同)
  • 你什么时候会使用“TEXT”而不是“VARCHAR”......与@Solomon问题相同,这对我来说仍然不明显? (2认同)

Cod*_*der 45

上面的答案中省略了一个重要的细节。

MySQL 对每行最大大小施加了 65,535 字节的限制。VARCHAR列的大小计入最大行大小,而TEXT列被假定为通过引用存储其数据,因此它们只需要 9-12 个字节。这意味着即使您的VARCHAR字段的“理论”最大大小为 65,535 个字符,如果您的表中有一列以上,您将无法实现这一目标。

另请注意,VARCHAR字段所需的实际字节数取决于列(和内容)的编码。MySQL 将使用的最大可能字节数计入最大行大小,因此如果您使用多字节编码utf8mb4您几乎肯定应该这样做),它将使用更多的最大行大小。

更正:无论MySQL如何计算最大行大小, VARCHAR/TEXT字段数据是实际存储在行中还是通过引用存储取决于您的底层存储引擎。对于 InnoDB,行格式会影响此行为。(感谢比尔-卡文)

使用理由TEXT

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

使用理由VARCHAR

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

  • 另外,关于 utf8mb4 占用更多字节的说法也不准确。仅当您的内容实际上需要多字节字符时,这些单个字符才会占用 2、3 或 4 个字节。utf8 中更常见的字符仍然每个字符占用 1 个字节。这就是utf8的全部意义! (4认同)
  • 不,VARCHAR 和 TEXT 默认情况下都将其部分内容存储在行中。如果表的 ROW_FORMAT=DYNAMIC *并且*内容不适合该行,则 VARCHAR 或 TEXT 都将存储为指向另一页的指针。 (3认同)
  • 另外,在文档的同一页中,它还提到“可变长度列的存储包括长度字节,这些字节计入行大小。例如,VARCHAR(255) CHARACTER SET utf8mb3 列需要两个字节来存储值,因此每个值最多可以占用 767 个字节。” 我并不是说 utf8mb4 总是使用 4 个字节,只是 MySQL 将其计入最大行大小。 (2认同)
  • 我已经更新了我的答案以澄清这些细节。现在看来准确吗?@比尔卡文 (2认同)
  • 是的!+1。仅供参考,64KB 限制和 InnoDB 行大小限制之间的这种奇怪差异是由于 MySQL 的存储引擎架构造成的。当行从存储引擎传输到 SQL 层,然后形成结果集时,它们必须满足不同的规则。 (2认同)