19

使用 utf8 作为字符集与使用 latin1 相比有哪些优点/缺点?

如果 utf 可以支持更多字符并且始终如一地使用,它不总是更好的选择吗?有什么理由选择latin1吗?

4

4 回答 4

21

UTF8 优点:

  1. 支持大多数语言,包括希伯来语等 RTL 语言。

  2. 将数据导入/导出到 UTF8 感知组件(JavaScript、Java 等)时​​无需翻译。

UTF8 的缺点:

  1. 由于编码方案更复杂,非 ASCII 字符将花费更多时间进行编码和解码。

  2. 非 ASCII 字符将占用更多空间,因为它们可能使用超过 1 个字节来存储(字符不在 ASCII 字符集中的前 127 个字符中)。一个CHAR(10)orVARCHAR(10)字段可能需要最多 30 个字节来存储一些 UTF8 字符。

  3. 其他排序规则utf8_bin会更慢,因为排序顺序不会直接映射到字符编码顺序),并且需要在某些存储过程中进行转换(因为变量默认为utf8_general_ci排序规则)。

  4. 如果您需要JOINUTF8 和非 UTF8 字段,MySQL 会造成严重的性能损失。如果加入的字段是不同的字符集/排序规则,那么亚秒级查询可能需要几分钟。

底线:

如果您不需要支持非Latin1 语言,想要获得最大性能,或者已经有表使用latin1,请选择latin1

否则,选择UTF8

于 2012-09-16T18:24:24.047 回答
19

latin1它的优点是它是单字节编码,因此它可以在相同的存储空间中存储更多的字符,因为MySql中字符串数据类型的长度取决于编码。该手册指出

要计算用于存储特定 CHAR、VARCHAR 或 TEXT 列值的字节数,您必须考虑用于该列的字符集以及该值是否包含多字节字符。特别是,在使用 utf8 Unicode 字符集时,您必须记住,并非所有字符都使用相同的字节数。utf8mb3 和 utf8mb4 字符集每个字符最多分别需要三个和四个字节。有关用于不同类别 utf8mb3 或 utf8mb4 字符的存储细分,请参阅第 10.9 节,“Unicode 支持”。

此外,许多字符串操作(例如获取子字符串和依赖于排序规则的比较)使用单字节编码更快。

无论如何,如果您完全关心国际化,latin1 就不是一个真正的竞争者。当您将存储已知的安全值(例如百分比编码的 URL)时,它可能是一个合适的选择。

于 2012-09-16T18:14:41.637 回答
6

@Ross Smith II,第 4 点很有价值,这意味着列之间的不一致可能很危险。

为了增加已经很好的答案的价值,这里是一个关于字符集之间差异的小型性能测试:

一个现代的 2013 服务器,实际使用的表有 20000 行,相关列上没有索引。

SELECT 4 FROM subscribersWHERE 1 ORDER BY time_utc_str; (4是缓存破坏者)

  • varchar(20) CHARACTER SET latin1 COLLATION latin1_bin: 15ms
  • varbinary(20): 17 毫秒
  • utf8_bin:20ms
  • utf8_general_ci:23 毫秒

对于像数字日期这样的简单字符串,当考虑性能时,我的决定是使用 utf8_bin (CHARACTER SET utf8 COLLATE utf8_bin)。这将防止与期望数据库字符集为 utf8 同时仍是二进制的其他代码的任何不利影响。

于 2014-07-22T15:20:06.907 回答
1

就 CPU 消耗而言,诸如 latin-1 之类的固定长度编码总是更有效。

如果已知某些固定长度字符集中的标记集足以满足您手头的目的,并且您的目的涉及繁重和密集的字符串处理,其中包含大量 LENGTH() 和 SUBSTR() 内容,那么这可能是一个不使用 UTF-8 等编码的充分理由。

哦,顺便说一句。不要像您似乎所做的那样混淆字符集及其编码。字符集是一些已定义的可写字形集。同一个字符集可以有多种不同的编码。unicode 标准的各个版本都构成一个字符集。它们中的每一个都可以进行UTF-8、UTF-16和“UTF-32”(不是官方名称,但它指的是对任何字符使用完整的四个字节的想法)编码,后两者可以分别采用 HOB-first 或 HOB-last 口味。

于 2012-09-16T18:13:47.527 回答