将字符集从 utf8 更改为 ascii 是否会改善 mysql 上 CHAR 字段的消耗空间?

die*_*rre 0 mysql aws-aurora

我有下表:

CREATE TABLE `tokens` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `s_id` int(10) unsigned NOT NULL,
  `a_token` char(40) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `a_token_exp` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u_a_token` (`a_token`) USING HASH,
  KEY `f_seid` (`s_id`),
  CONSTRAINT `f_seid` FOREIGN KEY (`s_id`) REFERENCES `sessions` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)

我想更改字符集,a_token因为我们使用以下命令仅使用 ascii 字符:

ALTER TABLE tokens MODIFY a_token CHAR(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL;
Run Code Online (Sandbox Code Playgroud)

和新SHOW CREATE TABLE节目:

CREATE TABLE `tokens` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `id` int(10) unsigned NOT NULL,
  `a_token` char(40) CHARACTER SET ascii NOT NULL,
  `a_token_exp` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u_a_token` (`a_token`) USING HASH,
  KEY `f_seid` (`s_id`),
  CONSTRAINT `f_seid` FOREIGN KEY (`s_id`) REFERENCES `sessions` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)

然后我跑OPTIMIZE TABLE oauth_session_access_tokens

这个查询应该(我不确定)我的模式表的大小:

SELECT table_name AS "Table",
      ((data_length + index_length)) AS "Size"
FROM information_schema.TABLES
WHERE table_schema = "test"
ORDER BY (data_length + index_length) DESC;
Run Code Online (Sandbox Code Playgroud)

但具体的表tokens总是返回49152前后ALTER TABLE

我可以假设即使使用 CHAR 和 utf8,如果只有 ASCII 字符,那么该字段也不会为 utf8 预分配空间吗?

Bil*_*win 5

UTF-8 是一种变长字符编码。对于 ASCII 范围内的字符,每个字符只需要 1 个字节。对于需要它的字符,每个字符仅使用 2、3 或 4 个字节。

关于 UTF-8 的维基百科文章有一个很好的解释和多字节编码如何工作的说明。https://en.wikipedia.org/wiki/UTF-8

因此,即使您只有 ASCII 字符要存储,使用 UTF-8 也没有什么缺点。