ChatGPT解决这个技术问题 Extra ChatGPT

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

根据 the MySQL docs,有四种 TEXT 类型:

小文本 文本 中文本 长文本

假设字符编码为 UTF-8,我可以在每种数据类型的列中存储的最大长度是多少?

以 TEXT 类型为例。它可以包含 65535 字节的数据。 UTF-8 包含多字节字符。因此,如果您仅使用丹麦字符“Ø”填写该字段,您将只能获得 32767 个字符,因为该 UTF-8 字符由两个字节组成。如果你用“a”填充它,你会得到 65535 个字符。

D
Déjà vu

documentation (MySQL 8)

Type | Maximum length
-----------+-------------------------------------
  TINYTEXT |           255 (2 8−1) bytes
      TEXT |        65,535 (216−1) bytes = 64 KiB
MEDIUMTEXT |    16,777,215 (224−1) bytes = 16 MiB
  LONGTEXT | 4,294,967,295 (232−1) bytes =  4 GiB

请注意,可以存储在列中的字符数取决于字符编码。


@Bridge 不确定我是否理解,但这意味着 TINYTEXT 最多可以包含 255 个字符,对吗?
@Lykos 是的,好吧 - 取决于角色。来自文档:A TEXT column with a maximum length of 255 (28 – 1) characters. The effective maximum length is less if the value contains multi-byte characters.有关更多详细信息,请参阅 Ankan 的答案。
@aurel.g 这就是你真正回答问题的方式。我同意 Christophe 的观点,这就是 mySQL 应该如何呈现其参数的方式——即使只是作为他们......神秘文本视图的补充速记。
@GaborSch所以您是说文档有误?恐怕我刚刚编写了一个测试,将 65535 个字符插入到 TEXT 列中没有问题。
为什么在文档中比在 stackoverflow 中更难找到它
o
oldboy

相同答案的扩展

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

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

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

xx

      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://stackoverflow.com/a/35785869/1881812


这个“应始终使用 VARCHAR 而不是 TINYTEXT”的理由是什么?有时使用较小的 TINYTEXT 不是更好(因为存储效率更高)吗?
@vlasits 阅读包含的 SO 帖子以获取详细信息。 (1) 所有文本类型,包括 tinytext 都存储为行外的对象,这是一个开销 (2) 这些对象然后由 8 或 16 个字节的地址引用。因此,无论您的 tinytext 多么小,您都在增加不必要的开销,最大大小为 255 字节。很明显应该使用 varchar,它不会有任何上述开销。
@Ankan-Zerob 鉴于很明显 TINYTEXT 永远不应该在 VARCHAR 上使用,那么将其作为一个选项的理由是什么?是否有一些晦涩的用例是必要的?
@nextgentech 看看 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 字符)。
我喜欢用单词来表示字段大小,但是…… 英语通常认为每个单词大约有 5 个字符,并且还有一个空格字符要存储;但是,每个 UTF-8 字符的英语总是接近 1 个字节,因此我将除以 6,给出不同大小的大约 40 / 10,000 / 2,700,000 / 710,000,000 个字。带有大量口音的语言(例如波兰语)的单词会稍微少一些;希腊语、希伯来语、阿拉伯语等(主要是 2 字节序列)大约一半; CJK 表意文字是 3 或 4 字节的序列,但我不知道单词有多长。
C
ChrisV

面对@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 个字符,因此它们将介于其他两个字符之间。 (使用 UTF-16 的 CJK 脚本可能需要更少的存储空间,具体取决于)。

这当然忽略了存储开销等。


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

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

“应始终使用 VARCHAR 而不是 TINYTEXT。”如果您有很宽的行,Tinytext 很有用 - 因为数据存储在记录之外。有性能开销,但它确实有用。