具有两个不同字符集的两个表

use*_*087 5 mysql encoding

我有一张表存储来自用户的输入,因此为了允许国家字符,我将 charset 设置为utf8mb4

然后我有第二个表,它可以变得非常大(100+ 数百万行),并且我 100% 确定该表将仅存储 ASCII 字符,因此我已将此表的字符集设置为latin1以节省磁盘空间。

在一个数据库中的表之间使用不同的字符集有什么缺点吗?这被认为是不好的做法吗?

或者有没有其他方法可以解决这个问题?(保持磁盘占用最小并允许使用国家字符)

编辑:

其输出show create table接受用户输入(并具有 utf8mb4)

 CREATE TABLE `sensor` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `label` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `description` varchar(3000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created` datetime(6) NOT NULL,
  `state` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `region` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `model_reference` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `label` (`label`),
  KEY `id` (`id`),
  KEY `sensor_ibfk_1` (`model_reference`),
 FULLTEXT KEY `fulltext_index`(`label`,`description`,`state`,`region`), 
 CONSTRAINT `sensor_ibfk_1` FOREIGN KEY (`model_reference`) REFERENCES      `model` (`id`) ON DELETE SET NULL ON UPDATE NO ACTION
 ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4      COLLATE=utf8mb4_unicode_ci
Run Code Online (Sandbox Code Playgroud)

其输出show create table是自动生成的(并具有 latin1)

CREATE TABLE `sensor_history` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `sensor_reference` int(20) DEFAULT NULL,
 `temperature` varchar(16) DEFAULT NULL,
 `pressure` varchar(16) DEFAULT NULL,
 `at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
 PRIMARY KEY (`id`),
 KEY `sensor_history_ibfk_1` (`sensor_reference`),
 CONSTRAINT `sensor_history_ibfk_1` FOREIGN KEY (`sensor_reference`)     REFERENCES `sensor` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)

Ric*_*mes 5

每个数据库的每个表的每一列都可以有不同的CHARACTER SETCOLLATION除非JOIN在具有不同字符集和/或排序规则的列上,否则没有缺点。

Ascii(7 位的东西)是 latin1 和 utf8mb4 的子集。因此,编码是相同的,因此对于纯 ascii 文本不会看到空间差异。

但是,当您声明不必要的大字符串时,会遇到一些问题,尤其是对于更宽的字符集。 可能你不会打嗝。请提供SHOW CREATE TABLE对可能案例的审查。

客户端必须声明它正在使用的字符集,所以UTF-8你在那里需要什么。在这种情况下,任何非 utf8mb4 列都会在客户端和服务器之间进行自动转换。

更多的

当存入 时VARCHAR(...) CHARACTER SET utf8mb4,有 1 字节或 2 字节长度的开销,加上

  • "abc" (ascii) 将占用 3 个字节 - 每个 ascii 字符占用 1 个字节,
  • "ÛØÎ" 将占用 6 个字节 - 大多数欧洲字符占用 1 或 2 个字节,
  • “José”将占用 5 个字节 - “é”占用 2 个字节,
  • "" (Emoji) 将占用 12 个字节;每个表情符号是 3 或 4 个字节。中国人同上。
  • “$€”(货币符号)将占用 4 个字节——“$”为 1,欧元为 3。

CHARACTER SET latin1

  • "abc", "ÛØÎ", "José", "$€" 可以正确存储在 latin1 中,分别使用 3、3、4、2 个字节。
  • 表情符号、所有亚洲语言、希腊语、西里尔语和其他语言都不能用 latin1 表示。垃圾随之而来。具体垃圾取决于各种设置;此问答列出了常见的乱码。

航行畅通:

  • 必须使用CHARACTER SET可以容纳字符的a 声明(显式或隐式)列。(英语适用于任何字符集,但表情符号仅适用于 utf8mb4。)
  • 连接参数(或SET NAMES)必须正确说明客户端中使用的编码。
  • 两个字符集之间必须有映射。(英语总是映射。(西欧可以在 latin1、utf8、utf8mb4 之间映射,但其他的不多。)