在 MySQL 中,如果我VARCHAR(32)
在 UTF-8 表中创建一个新字段,这是否意味着我可以在该字段中存储 32 个字节的数据或 32 个字符(多字节)?
5 回答
这个答案出现在我的谷歌搜索结果的顶部,但不正确。
混淆可能是由于正在测试不同版本的 MySQL。
- 版本 4 计数字节
- 版本 5 计数字符
这是官方 MySQL 5文档的引用:
MySQL 以字符单位解释字符列定义中的长度规范。(在 MySQL 4.1 之前,列长度以字节为单位解释。)这适用于 CHAR、VARCHAR 和 TEXT 类型。
有趣的是(我没想到)varchar 列的最大长度受 utf8 影响,如下所示:
MySQL 5.0.3 及更高版本中 VARCHAR 的有效最大长度取决于最大行大小(65,535 字节,在所有列之间共享)和使用的字符集。例如,utf8 字符每个字符最多需要三个字节,因此可以将使用 utf8 字符集的 VARCHAR 列声明为最多 21,844 个字符。
它可以让你存储 32 个多字节字符
要使用 UTF-8 节省空间,请使用 VARCHAR 而不是 CHAR。否则,MySQL 必须为 CHAR CHARACTER SET utf8 列中的每个字符保留三个字节,因为这是可能的最大长度。例如,MySQL 必须为 CHAR(10) CHARACTER SET utf8 列保留 30 个字节。
带有排序规则的32多字节数据,我刚刚使用 XAMPP 进行了测试。varchar(32)
utf8_unicode_ci
1234567890123456789012345678901234567890
截断为:
12345678901234567890123456789012
请记住,这些不是常规的 ASCII 字符。
对于高频更新的表,最好使用“char”,因为行的总数据长度将是固定的且快速的。Varchar 列使行数据大小动态化。这对 MyISAM 不利,但我不知道 InnoDB 和其他人。例如,如果您有一个非常窄的“类型”列,最好将 char(2) 与 latin1 字符集一起使用以仅占用最小空间。
如果您使用 latin1 编码(例如使用 PHP)连接到数据库以将 PHP UTF8 字符串保存在 MySQL UTF8 列中,您将获得双重 UTF8 编码。
如果 UTF8 字符串$s
的长度为 32 个字符但长度为 64 个字节并且该列是VARCHAR(32)
UTF8,则双重编码会将字符串转换$s
为 64 个字符长的 UTF8 字符串,该字符串将在数据库中被截断为对应于前 32 个字节的前 32 个字符的$s
。您最终可能会认为 MySQL 5 的行为类似于 MySQL 4,但实际上它是导致相同结果的第二个原因。