mysql中非utf8列的建议字符集

时间:2017-09-20 08:12:14

标签: mysql utf-8 guid

目前,我正在使用VARCHAR / TEXTutf8_general_ci来处理mysql中的所有字符列。现在我想改进数据库布局/性能。

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

    固定长度列的
  • CHAR代替VARCHAR作为GUID或会话ID
  • 还对长度为1或可能为2?
  • 的小列使用CHAR

由于处理问题,我不想将我的GUID保存为BINARY(16),因此我宁愿将它们保存为CHAR(32)以特别改进密钥。 (当从utf8切换到某个1字节字符集时,我甚至会保存2/3)

  • 那么这些列的最佳字符集是什么? ASCII? LATIN1? BINARY?哪种整理?
  • 用于其他列的字符集/排序规则,我不需要utf8支持但需要正确排序。二进制会失败吗?

在同一个mysql(innodb)表中混合使用不同的字符集是不错的做法?或者当所有列在同一个表中具有相同的字符集时,我能获得更好的性能吗?甚至数据库?

1 个答案:

答案 0 :(得分:3)

GUID / UUID / MD5 / SHA1都是十六进制和短划线。对他们来说

CHAR(..) CHARACTER SET ascii COLLATE ascii_general_ci

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

对于Base64内容,请使用

CHAR(..) CHARACTER SET ascii COLLATE ascii_bin
BINARY(..)

因为A 在语义上与a相同。

进一步说明......

    如果你给它一个无效的8位值,
  • utf8会向你吐口水。
  • ascii向您吐出任何8位值。
  • latin1接受任何东西 - 从而使你的问题在路上
  • 在具有不同字符集和/或排序规则的表中使用不同的列是完全可以的。
  • 表格上的字符集/整理只是一个默认,适合覆盖列定义。
  • BINARY可能比任何_bin整理快一点,但还不足以引起注意。
  • CHAR用于真正固定长度的列;在其他情况下使用它不会误导用户。
  • %_bin%_general_ci更快,这比其他排序规则更快。再一次,你很难衡量差异。
  • 切勿使用TINYTEXTTINYBLOB
  • 要进行正确的编码,请使用适当的字符集。
  • 对于"正确排序",使用适当的排序规则。见下面的例子。
  • 对于"正确排序"在表示多种语言且您使用utf8mb4的情况下,请使用utf8mb4_unicode_520_ci(如果使用版本8.0,则使用utf8mb4_900_ci)。 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

其余的是"无用":

| 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)

更多

  • 使用较小数据类型(适当时)的原因是缩小数据集,从而减少I / O,从而使事物更易于缓存,从而使程序运行得更快。这对于庞大的数据集尤为重要;对于小型或中型数据集来说,这一点并不重要。
  • ENUM是1个字节,但就像一个字符串。所以你得到了两个世界中最好的"。 (有弊端,ENUM vs TINYINT vs VARCHAR的倡导者之间存在宗教战争。)
  • 通常是"短"长度总是一样的。 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。如果您的表中只有几位,则不值得担心。
  • 我的一个Rules of Thumb表示,如果您不可能获得10%的改善,请继续进行其他优化。我们在这里讨论的大部分内容都不到10%(在这种情况下是空间)。尽管如此,在写CREATE TABLE时养成思考它的习惯。我经常看到包含BIGINTDOUBLE(每个8字节)的表,可以轻松使用较小的列。有时节省超过50%(空间)。
  • "空间"转化为"速度"。小桌子 - >很小的比例。巨大的桌子 - >在某些情况下10x。 (那是10倍,而不是10%。)(UUID是在巨大的桌子上获得非常糟糕表现的一种方式。)

<强> ENUM

  • 行为和感觉就像一个字符串,但只需要一个字节。 (一个字节间接转换为轻微的速度提升。)
  • 比少于10个不同的值时实用。
  • 如果经常添加新值,则不切实际 - 需要ALTER TABLE,但 可以&#34; inplace&#34;。
  • 建议使用'unknown'(或类似内容)开始列表并制作列NOT NULL(与NULL对比)。
  • 枚举的字符集必须是用于连接的其他内容。除非您有整理相等的选项(例如,Aa),否则选择无关紧要。