【问题标题】:MySQL VARCHAR Lengths and UTF-8MySQL VARCHAR 长度和 UTF-8
【发布时间】:2011-01-01 03:17:42
【问题描述】:

在 MySQL 中,如果我在 UTF-8 表中创建一个新的 VARCHAR(32) 字段,是否意味着我可以在该字段中存储 32 个字节的数据或 32 个字符(多字节)?

【问题讨论】:

  • @naXa:我没有。你觉得我应该?
  • 我不知道。)这是你的问题,这取决于你。我只是想说“另一个答案看起来更完整”。
  • @robsch 之前接受的答案简单而正确。但是请按照大众的要求去做,我已经接受了你想要的。

标签: mysql unicode utf-8 varchar


【解决方案1】:

它可以让你存储 32 个多字节字符

要使用 UTF-8 节省空间,请使用 VARCHAR 代替 CHAR。否则, MySQL 必须为 CHAR CHARACTER SET 中的每个字符 utf8 列,因为那是 最大可能长度。例如, MySQL 必须为 a 保留 30 个字节 CHAR(10) CHARACTER SET utf8 列。

http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html

【讨论】:

  • 我几乎从不使用CHAR,当我这样做时,它并不打算存储多字节字符,所以我很安全。 VARCHAR 呢,您确定限制是在多字节字符中定义的,而不是在单字节字符中定义的吗?
  • @jspcal:UTF-8 每个字符最多使用 4 个字节,而不是 3 个。或者 MySQL 不支持所有 4 个字节?
  • @RemyLebeau 您对 utf8 的看法是对的,但对于 MySQL 则不然。各种 utf8_xxx 字符集最大为 3 字节。 utf8mb4_xxx 占用 4 字节字符。 dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
  • 随着时间的推移,MySQL 似乎最终会使用标准的 4 字节版本(但在撰写本文时还没有):dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8.html
【解决方案2】:

varchar(32) 的 32 个 多字节 数据和排序规则 utf8_unicode_ci,我刚刚使用 XAMPP 进行了测试。

1234567890123456789012345678901234567890

截断为:

12345678901234567890123456789012

请记住,这些不是常规的 ASCII 字符。

【讨论】:

  • 在 UTF-8 标准 ASCII 字符中只会存储在一个字节中 - 要真正测试这一点,您需要在测试字符串中实际使用一些多字节(即非 ascii)字符。跨度>
  • 这是错误的,至少对于 MySQL 5+。为 varchar 或 char 指定列大小时,以字符为单位指定。我相信 VARCHAR(32) 列的实际大小是 32x3+1=97 字节。
  • @rjmackay '12345' 不是标准的 ASCII 字符。 en.wikipedia.org/wiki/…
  • 我将 40 个 unicode 字符插入 DB,并在 32 个字符处被截断。但看起来人们认为我使用了 ascii 字节并被截断为 32 个字节。难怪,我投了反对票,哈哈。
  • @ButtleButkus " 我相信 VARCHAR(32) 列的实际大小是 32x3+1=97 字节" 如果你使用 utf8 会这样,但是你会在 MySQL 中得到破坏的 Unicode 支持.您应该改用utf8mb4 编码,因为有max. 4 bytes in a utf-8 char,而不是MySQL 的utf8 变体中的3...
【解决方案3】:

这个答案出现在我的谷歌搜索结果的顶部,但不正确:

混淆可能是由于测试的mysql版本不同。

  • 版本 4 计算字节数
  • 版本 5 计算字符数

http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html

MySQL 以字符单位解释字符列定义中的长度规范。 (在 MySQL 4.1 之前,列长度以字节为单位解释。)这适用于 CHAR、VARCHAR 和 TEXT 类型。

有趣的是(我没想到)varchar 列的最大长度受 utf8 影响如下:

在 MySQL 5.0.3 及更高版本中 VARCHAR 的有效最大长度取决于最大行大小(65,535 字节,在所有列之间共享)和使用的字符集。例如,utf8 字符每个字符最多需要三个字节,因此可以将使用 utf8 字符集的 VARCHAR 列声明为最多 21,844 个字符。

【讨论】:

  • M Brown,感谢您提及这一点。一个 VARCHAR(10) 字段(使用utf8mb4)可以存储“??????????”(10 堆便便),即 10 个字符但 40 个字节。
  • 这个。这是唯一正确的答案。太多人相信版本 4 的行为是福音。
  • 接受的答案对于 MySQL 5 也是正确的——插入的数字实际上是全角字符集的一部分,并且是多字节 unicode 字符,正如他插入的海报中提到的那样“ 32 多字节数据”。很遗憾被很多人误解了。
  • 引用以下来源,我相信 utf8 字符目前最多需要 6 个字节,因此介于 1 到 6 个字节之间。这导致字符最大值为 10922 的最坏情况。我认为。 joelonsoftware.com/articles/Unicode.html
  • @usumoio 目前,MySQL 似乎使用 UTF-8 的 3 字节变体,并计划迁移到(标准)4 字节变体:dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8.html
【解决方案4】:

对于频繁更新的表,最好使用“char”,因为行的总数据长度将是固定的且快速的。 Varchar 列使行数据大小动态化。这对 MyISAM 不利,但我不知道 InnoDB 和其他人。例如,如果您有一个非常窄的“类型”列,最好将 char(2) 与 latin1 字符集一起使用以仅占用最小空间。

【讨论】:

  • 我已经读到,如果表中的任何列是 varchar,那么您将失去拥有 char 列的所有好处。基本上,您似乎必须在表中使用所有 varchar 或所有 char 以获得最大收益。不过,我不知道这是不是真的。
  • 对于 MyISAM,CHARsome 参数。对于 InnoDB,还有很多其他事情正在发生,以至于“动态/固定行大小”的争论基本上是无关紧要的。
  • 恕我直言,这里的重点是对于非常小的长度,使用CHAR 可能是有益的。
【解决方案5】:

如果您使用 latin1 编码(例如使用 PHP)连接到数据库以将 PHP UTF8 字符串保存在 MySQL UTF8 列中,您将获得双重 UTF8 编码。

如果 UTF8 字符串 $s 长度为 32 个字符但长度为 64 个字节,并且列是 VARCHAR(32) UTF8,则双重编码会将字符串 $s 转换为 64 个字符长的 UTF8 字符串,该字符串将在数据库的第 32 个字符对应于$s 的第 32 个字节。您最终可能会认为 MySQL 5 的行为类似于 MySQL 4,但实际上它是导致相同结果的第二个原因。

【讨论】:

    猜你喜欢
    • 2013-04-24
    • 2011-04-08
    • 2023-03-25
    • 2013-02-15
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    相关资源
    最近更新 更多