使用 utf8 作为字符集与使用 latin1 相比有哪些优点/缺点?
如果 utf 可以支持更多字符并且始终如一地使用,它不总是更好的选择吗?有什么理由选择latin1吗?
UTF8 优点:
支持大多数语言,包括希伯来语等 RTL 语言。
将数据导入/导出到 UTF8 感知组件(JavaScript、Java 等)时无需翻译。
UTF8 的缺点:
由于编码方案更复杂,非 ASCII 字符将花费更多时间进行编码和解码。
非 ASCII 字符将占用更多空间,因为它们可能使用超过 1 个字节来存储(字符不在 ASCII 字符集中的前 127 个字符中)。一个CHAR(10)
orVARCHAR(10)
字段可能需要最多 30 个字节来存储一些 UTF8 字符。
其他排序规则utf8_bin
会更慢,因为排序顺序不会直接映射到字符编码顺序),并且需要在某些存储过程中进行转换(因为变量默认为utf8_general_ci
排序规则)。
如果您需要JOIN
UTF8 和非 UTF8 字段,MySQL 会造成严重的性能损失。如果加入的字段是不同的字符集/排序规则,那么亚秒级查询可能需要几分钟。
底线:
如果您不需要支持非Latin1 语言,想要获得最大性能,或者已经有表使用latin1
,请选择latin1
。
否则,选择UTF8
。
latin1
它的优点是它是单字节编码,因此它可以在相同的存储空间中存储更多的字符,因为MySql中字符串数据类型的长度取决于编码。该手册指出
要计算用于存储特定 CHAR、VARCHAR 或 TEXT 列值的字节数,您必须考虑用于该列的字符集以及该值是否包含多字节字符。特别是,在使用 utf8 Unicode 字符集时,您必须记住,并非所有字符都使用相同的字节数。utf8mb3 和 utf8mb4 字符集每个字符最多分别需要三个和四个字节。有关用于不同类别 utf8mb3 或 utf8mb4 字符的存储细分,请参阅第 10.9 节,“Unicode 支持”。
此外,许多字符串操作(例如获取子字符串和依赖于排序规则的比较)使用单字节编码更快。
无论如何,如果您完全关心国际化,latin1 就不是一个真正的竞争者。当您将存储已知的安全值(例如百分比编码的 URL)时,它可能是一个合适的选择。
@Ross Smith II,第 4 点很有价值,这意味着列之间的不一致可能很危险。
为了增加已经很好的答案的价值,这里是一个关于字符集之间差异的小型性能测试:
一个现代的 2013 服务器,实际使用的表有 20000 行,相关列上没有索引。
SELECT 4 FROM subscribers
WHERE 1 ORDER BY time_utc_str
; (4是缓存破坏者)
对于像数字日期这样的简单字符串,当考虑性能时,我的决定是使用 utf8_bin (CHARACTER SET utf8 COLLATE utf8_bin)。这将防止与期望数据库字符集为 utf8 同时仍是二进制的其他代码的任何不利影响。
就 CPU 消耗而言,诸如 latin-1 之类的固定长度编码总是更有效。
如果已知某些固定长度字符集中的标记集足以满足您手头的目的,并且您的目的涉及繁重和密集的字符串处理,其中包含大量 LENGTH() 和 SUBSTR() 内容,那么这可能是一个不使用 UTF-8 等编码的充分理由。
哦,顺便说一句。不要像您似乎所做的那样混淆字符集及其编码。字符集是一些已定义的可写字形集。同一个字符集可以有多种不同的编码。unicode 标准的各个版本都构成一个字符集。它们中的每一个都可以进行UTF-8、UTF-16和“UTF-32”(不是官方名称,但它指的是对任何字符使用完整的四个字节的想法)编码,后两者可以分别采用 HOB-first 或 HOB-last 口味。