mysql中非utf8列的建议字符集

tos*_*iba 2 mysql guid utf-8

目前我使用VARCHAR/ TEXTutf8_general_ci在MySQL中的所有字符列。现在,我想改善数据库的布局/性能。

我到目前为止发现的是更好地使用

  • CHAR而不是将VARCHAR固定长度的列用作GUID或会话ID
  • CHAR用于长度为1或2的小列吗?

由于我不想像BINARY(16)处理问题那样广泛地保存我的GUID,所以我宁愿保存它们CHAR(32)来特别改进键。(从utf8切换到某些1字节字符集时,我什至会节省2/3)

  • 那么,对于此类列,最佳字符集是什么?ASCII?latin1?二进制?哪个排序规则?
  • 我不需要utf8支持但需要适当排序的其他列使用什么字符集/排序规则。二进制会失败吗?

在同一个mysql(innodb)表中混合使用不同的字符集是一种好习惯吗?还是当同一表中的所有列都具有相同的字符集时,我可以获得更好的性能吗?甚至是数据库?

Ric*_*mes 5

GUID / UUID / MD5 / SHA1均为十六进制和破折号。对于他们

CHAR(..) CHARACTER SET ascii COLLATE ascii_general_ci
Run Code Online (Sandbox Code Playgroud)

比较十六进制字符串时,这将允许A= a

对于Base64,请使用以下任一方法

CHAR(..) CHARACTER SET ascii COLLATE ascii_bin
BINARY(..)
Run Code Online (Sandbox Code Playgroud)

因为A不是语义上是一样的a

进一步说明...

  • 如果您给utf8一个无效的8位值,它会吐口水。
  • ascii向您吐出任何8位值。
  • latin1接受任何内容-因此您遇到的麻烦
  • 在具有不同字符集和/或排序规则的表中具有不同的列是完全可以的。
  • 表格上的字符集/排序规则只是一个默认值,可以在列定义中覆盖。
  • BINARY可能比任何_bin排序规则都快一点,但不足以引起注意。
  • 使用CHAR的是真正的固定长度列; 不要在其他情况下使用它来误导用户。
  • %_bin%_general_ci快,比其他归类快。同样,您将很难衡量差异。
  • 请勿使用TINYTEXTTINYBLOB
  • 为了进行正确的编码,请使用适当的字符集。
  • 对于“正确排序”,请使用适当的排序规则。请参见下面的示例。
  • 对于表示多种语言且正在使用的“正确排序”,请使用utf8mb4,如果使用utf8mb4_unicode_520_ci(或utf8mb4_900_ci使用8.0版)。520和900是指Unicode标准。将来可能会出现新的归类。

如果您完全是捷克人,请考虑这些字符集和排序规则。我按优先顺序列出了它们:

mysql> show collation like '%czech%';
+------------------+---------+-----+---------+----------+---------+
| Collation        | Charset | Id  | Default | Compiled | Sortlen |
+------------------+---------+-----+---------+----------+---------+
| utf8mb4_czech_ci | utf8mb4 | 234 |         | Yes      |       8 | -- opens up the world
| utf8_czech_ci    | utf8    | 202 |         | Yes      |       8 | -- opens up most of the world
| latin2_czech_cs  | latin2  |   2 |         | Yes      |       4 | -- kinda like latin1
Run Code Online (Sandbox Code Playgroud)

其余的都是“无用的”:

| cp1250_czech_cs  | cp1250  |  34 |         | Yes      |       2 |
| ucs2_czech_ci    | ucs2    | 138 |         | Yes      |       8 |
| utf16_czech_ci   | utf16   | 111 |         | Yes      |       8 |
| utf32_czech_ci   | utf32   | 170 |         | Yes      |       8 |
+------------------+---------+-----+---------+----------+---------+
7 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

更多

  • 使用较小数据类型(在适当的情况下)的原因是要缩小数据集,这会导致I / O减少,从而使事物更具可缓存性,从而使程序运行速度更快。这对于庞大的数据集尤其重要。对于中小型数据集而言,它的重要性降低。
  • ENUM是1个字节,却像一个字符串。因此,您获得了“两全其美”。(存在弊端,ENUM反对者TINYINT与反对者之间存在一场“宗教战争” VARCHAR。)
  • 通常,“短”列的长度始终相同。A country_code始终为2个字母,始终为ascii,始终可以受益于不区分大小写的排序规则。所以CHAR(2) CHARACTER SET ascii COLLATE ascii_general_ci是最优的。如果您的东西有时是1个字符,有时是2个字符,则掷硬币。不管你做什么都不会有太大改变。
  • VARCHAR(最多255个)附加了1个字节的长度。因此,如果您的琴弦的长度完全不同VARCHAR则至少与一样好CHAR。因此简化您的大脑处理过程:“可变长度->`VARCHAR”。
  • BIT,取决于版本,可以实现为1个字节TINYINT UNSIGNED。如果表中只有几位,那就不用担心了。
  • 我的经验法则之一说,如果您不可能获得10%的改进,请继续进行其他优化。我们在这里讨论的大部分内容都在10%以下(在这种情况下为空格)。尽管如此,在写作时还是要养成思考的习惯CREATE TABLE。我经常看到带有BIGINTDOUBLE(每个8字节)的表可以轻松使用较小的列。有时节省超过50%(空间)。
  • “空间”如何转化为“速度”。小桌子->一小部分。巨大的表格->在某些情况下为10倍。(这是10倍,而不是10%。)(UUID是在大型表上获得真正糟糕性能的一种方法。)

枚举

  • 行为和感觉像一个字符串,但仅占用一个字节。(一个字节间接地导致速度略有提高。)
  • 少于10个不同值时实用。
  • 如果经常添加一个新值ALTER TABLE,则不切实际-require ,尽管它可以是“就地”的。
  • 建议以'unknown'(或类似名称)开头列表,然后创建列NOT NULL(与之相对NULL)。
  • 枚举的字符集必须是用于连接的字符集。除非您选择的排序规则相等(例如,Avs a),否则选择关系不大。