TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT的最大存储大小

935
根据MySQL文档,有四种TEXT类型:
  1. TINYTEXT
  2. TEXT
  3. MEDIUMTEXT
  4. LONGTEXT
假设字符编码为UTF-8,每种数据类型的列可以存储的最大长度是多少?

39
以TEXT类型为例,它可以包含65535字节的数据。UTF-8包含多字节字符。因此,如果您仅使用丹麦字符“Ø”填写字段,则只能获得32767个字符,因为该UTF-8字符由两个字节组成。如果您使用“a”填充,则会获得65535个字符。 - Andrew Plank
3
也考虑阅读 使用TEXT还是VARCHAR数据类型更好? - Somnath Muluk
4个回答

1751

来自MySQL 8的文档

      数据类型 | 最大长度
-----------+-------------------------------------
  TINYTEXT |           255 (2 8−1) 字节
      TEXT |        65,535 (216−1) 字节 = 64 KiB
MEDIUMTEXT |    16,777,215 (224−1) 字节 = 16 MiB
  LONGTEXT | 4,294,967,295 (232−1) 字节 =  4 GiB

请注意,您列中可以存储的字符数取决于字符集编码方式


3
@Bridge 不确定我是否理解正确,但这意味着TINYTEXT最多可以容纳255个字符,我是对的吗? - ltdev
10
是的,这取决于字符。根据文档:TEXT列最大长度为255(28-1)个字符。如果值包含多字节字符,则有效最大长度会减少。请参考Ankan的答案了解更多细节。 - Bridge
5
@aurel.g 这才是你真正回答问题的方式。我同意Christophe的观点,这就是mySQL应该呈现其参数的方式,即使只是作为其...深奥文本视图的补充简写。 - cbmtrx
2
@GaborSch 那么您是在说文档有误吗?恐怕我刚刚编写了一个测试,将65535个字符插入TEXT列中,没有出现任何问题。 - Bridge
126
为什么在文档中找到这个比在 Stack Overflow 上难得多? - Boris D. Teoharov
显示剩余6条评论

289

同样答案的拓展

  1. 这个SO帖子详细介绍了开销和存储机制。
  2. 如点(1)所述,应始终使用VARCHAR而不是TINYTEXT。但是,在使用VARCHAR时,最大行大小不应超过65535个字节。
  3. 在此处http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html中概述了utf-8最多3个字节。

这是一个快速决策的粗略估计表格!

  1. 因此,最坏情况假设(每个utf-8字符3个字节)到最好情况(每个utf-8字符1个字节)
  2. 假设英语平均每个词有4.5个字母
  3. x是分配的字节数

x-x

      Type | A= worst case (x/3) | B = best case (x) | words estimate (A/4.5) - (B/4.5)
-----------+---------------------------------------------------------------------------
  TINYTEXT |              85     | 255               | 18 - 56
      TEXT |          21,845     | 65,535            | 4,854.44 - 14,563.33  
MEDIUMTEXT |       5,592,415     | 16,777,215        | 1,242,758.8 - 3,728,270
  LONGTEXT |   1,431,655,765     | 4,294,967,295     | 318,145,725.5 - 954,437,176.6

请参考 Chris V 的回答:https://dev59.com/kWYr5IYBdhLWcg3wIG1u#35785869


4
为什么要使用“VARCHAR”而不是“TINYTEXT”?使用更小的“TINYTEXT”是否更好(因为更节省存储空间)? - vlasits
27
请参考包括在内的SO帖子以获取更多详细信息。 (1) 所有文本类型,包括tinytext,都作为行外对象存储,这是一种开销。(2) 然后,这些对象由8或16字节的地址引用。因此,无论您的tinytext有多小,您都会增加不必要的开销,对于最大255字节的大小也是如此。显然应该使用varchar,它不会有上述任何开销。 - Ankan-Zerob
4
考虑到TINYTEXT明显不应该用于代替VARCHAR,为什么还保留它作为一个选项?是否存在某些晦涩的使用情况需要使用它? - nextgentech
5
请查看https://dev.mysql.com/doc/refman/5.0/en/column-count-limit.html。记录大小限制为64 KiB,表限制为4k列。TINYTEXT在记录大小中计为1个字节+8个字节,而VARCHAR(255)在记录大小中计算从1个字节+255个字节到2个字节+1020个字节(4个字节的UTF-8字符)。 - Shi
2
我喜欢用单词来表示字段大小,但是...英语通常被认为每个单词有大约5个字符,并且还有一个空格字符需要存储;然而,英语始终接近每个UTF-8字符1字节,因此我会除以6,得到不同大小的大约40/10,000/2,700,000/710,000,000个单词。像波兰语这样有很多重音的语言会有稍微少一些的单词数;希腊语、希伯来语、阿拉伯语等(主要是2字节序列)大约一半;CJK汉字是3或4字节序列,但我不知道单词有多长。 - ChrisV
显示剩余5条评论

56

响应 @Ankan-Zerob 的挑战,这是我对每种文本类型可以存储的最大长度的估计,以单词为单位测量

      Type |         Bytes | English words | Multi-byte words
-----------+---------------+---------------+-----------------
  TINYTEXT |           255 |           ±44 |              ±23
      TEXT |        65,535 |       ±11,000 |           ±5,900
MEDIUMTEXT |    16,777,215 |    ±2,800,000 |       ±1,500,000
  LONGTEXT | 4,294,967,295 |  ±740,000,000 |     ±380,000,000

在编程领域,一个单词大约包含4.8个字母是一个不错的平均值(例如norvig.com/mayzner.html)。然而,不同领域的词汇长度也因此有所不同(例如口语和学术论文),因此没有必要过于精确。英语中,大部分字符都是单字节的ASCII字符,偶尔出现多字节字符,因此每个字母接近一个字节。需要额外计算单词之间的空格,因此我将其舍入为每个单词5.8字节。拥有许多重音符号的语言,如波兰语,存储的单词会稍微少一些,如同较长单词的德语。

需要使用多字节字符的语言,如希腊语、阿拉伯语、希伯来语、印地语、泰语等,通常需要UTF-8中的两个字节才能表示一个字符。猜测一个单词大约包含5个字母,因此我将其舍入为每个单词11个字节。

CJK文字(汉字,日本汉字,平假名,片假名等)我一无所知;我相信字符在UTF-8中大多需要3个字节,并且(极为简化地说),它们可能被认为每个单词使用约2个字符,因此它们会介于另外两者之间。(根据情况,CJK文本使用UTF-16可能需要更少的存储空间。)
当然,这忽略了存储开销等方面。

CJK字符可能使用3或4字节序列:http://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8.html - Raptor

13

这很好,但并没有回答问题:

"在所有情况下都应该使用VARCHAR而不是TINYTEXT"。如果您有宽列,则Tinytext非常有用,因为数据存储在记录之外。虽然存在性能开销,但确实有用途。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接