我知道如果长度> 255,则需要 2 个字节来存储长度前缀。我只需要验证我的假设。请告诉我字符集(latin1,ucs2,utf8mb4)的长度前缀和字符串('abcd')的长度。对于 varchar(20) 列。文件说:
[...]对于字符串“abcd”,L 为 4,存储要求为 5 个字节。如果同一列改为使用 ucs2 双字节字符集,则存储要求为10 个字节:'abcd' 的长度为 8 个字节,该列需要两个字节来存储长度,因为最大长度大于 255 (最多 510 个字节)。[...]
参考: 11.7 数据类型存储要求(Oracle | Docs)
我只是不明白为什么对于带有字符集'ucs2'的'abcd',即使它小于255,它也需要2字节长度的前缀。
abcd
全是英文,所以: ucs2 9 个字节;utf8 为 5 个字节。但...UCS2 每个字符使用 2 个字节(至少对于“西方”字母)。我认为大多数亚洲字符需要 4 个字节。
utf8(或 utf8mb4)是一种可变长度编码。英文字母每个占 1 个字节;大多数欧洲文本每个字符占用 1 或 2 个字节。亚洲语言每个字符占用 3 个字节,有时是 4 个字节。
latin1 只有 1 字节字符,因此仅限于英语,外加一些带重音的欧洲字母。
但是,但是……
VARCHAR(40)
以任何正在使用的编码存储最多 40 个字符(不是字节)。磁盘空间为 1 个字节的长度加上最多 4*40 个字节的文本。一个很长的例子是 40 个 Emoji,占用 161 个字节。<opinion>
几乎没有理由使用CHARACTER SET
ucs2(或 ucs4)。特别是,任何涉及 unicode 或 utf8 的东西都应该使用utf8mb4
.</opinion>
但是但是但是...
重新评论关于 10 个字节的评论——InnoDB 有时会使用 1 个字节作为长度,有时会使用 2 个字节。但决定是基于表中的所有列。您的“40”不会强制使用 2 字节长度,但其他一些列可能会。
文档说“例如,一
VARCHAR(255)
列......(最多 510 个字节)”。所以它需要 2 个字节,因为最大字节长度 > 255。您的示例是“VARCHAR(40)”,即“最多 80 个字节”(<=255)。