MySQL 字符串列同时具有逻辑字符限制和物理字节表示。将这两个概念分开,可以避免多语言文本和索引中的许多意外。
CHAR 和 VARCHAR
#
CHAR(n) 是定长字符串。MySQL 会按照声明的长度填充值以满足存储语义,因此它最适合国家/地区代码等真正定宽的值。VARCHAR(n) 是变长字符串,通常更适合作为名称、标签和其他长度变化文本的默认类型。
在这两种类型中,n 都是最大字符数,而不是字节数。因此,当字符集支持时,
VARCHAR(10) 列可以容纳十个 emoji 或十个中文字符,即使这些字符在磁盘上使用的字节数超过十个。
CREATE TABLE profile (
country_code CHAR(2) NOT NULL,
display_name VARCHAR(100) NOT NULL
) CHARACTER SET utf8mb4;TEXT 类型
#
对于较大的变长文本,使用 TINYTEXT、TEXT、MEDIUMTEXT 或 LONGTEXT。它们的限制以字节为单位,因此实际字符容量取决于列字符集。TEXT 列可以建立索引,但较大或较旧的 MySQL 配置可能需要索引前缀;围绕长文本设计索引前,应检查存储引擎和 MySQL 版本。
字符集和排序规则 #
字符集定义字符如何编码为字节。对于新的 MySQL 应用,utf8mb4 通常是安全选择,因为它支持完整的 Unicode 范围。MySQL 历史上的 utf8 名称可能指代三字节实现,不能表示每个 Unicode 字符。
排序规则定义字符集的比较和排序规则。它决定比较是否区分大小写或重音,以及字符串如何排序。可以在服务器、数据库、表或列级别设置字符集和排序规则;明确的表级或列级设置可以使应用的预期更清晰。
CREATE TABLE article (
title VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci NOT NULL
);根据应用所需的比较方式选择排序规则。对于标识符,二进制或区分大小写的比较可能合适;对于面向用户的搜索,不区分重音和大小写的排序规则可能更合适。
二进制字符串类型 #
BINARY 和 VARBINARY 存储的是字节,而不是文本。它们使用 binary 字符集和排序规则,因此 MySQL 不会进行转码或应用语言学比较规则。BINARY(n) 会用 0x00 填充存储值;VARBINARY(n) 不会。对于较大的字节序列,使用 BLOB 类型。不要将加密数据、摘要或协议字节存储在字符列中,因为连接转换和排序规则可能改变它们的解释。
CREATE TABLE artifact (
sha256 BINARY(32) NOT NULL,
payload LONGBLOB NOT NULL,
PRIMARY KEY (sha256)
);默认值、连接设置和索引 #
字符集和排序规则默认值会从服务器、数据库、表和列设置中解析。字符串字面量也具有字符集和排序规则。连接声明 character_set_client、character_set_connection 和
character_set_results;对于没有配置这些设置的客户端,使用驱动程序的 utf8mb4
配置或执行 SET NAMES utf8mb4。
应检查实际生效的设置,而不是假设软件包默认值:
SHOW CREATE TABLE article;
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';索引限制以字节为单位。使用 utf8mb4 的 VARCHAR(255) 在字符数据上最多可能需要
1,020 字节,还不包括索引元数据。当前 MySQL 版本中的 InnoDB 支持较大的索引键,但设计仍必须考虑选定的行格式、页面大小和 MySQL 版本。应优先使用有界搜索键的索引;只有当前缀仍具有选择性时,才使用前缀索引。
评论
在 GitHub 上阅读或评论(发表评论需要登录)