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
。
还注意到......
- UTF8你吐出如果你给它一个无效的8位值。
- ascii吐出任何8位值。
- latin1接受任何东西 - 因此你的问题在路上
- 在具有不同字符集和/或排序规则的表中使用不同的列是完全可以的。
- 表格上的字符集/排序规则只是默认,适合在列定义中重写。
BINARY
可能比任何_bin
排序规则稍快,但不足以注意到。
- 使用
CHAR
表示真正固定长度的列;不要误导用户在其他情况下使用它。
%_bin
比%_general_ci
更快,这比其他排序规则更快。再一次,你会很难测量差异。
- 千万不要使用
TINYTEXT
或TINYBLOB
。
- 为了正确编码,请使用适当的字符集。
- 对于“正确排序”,请使用适当的排序规则。见下面的例子。
- 对于表示多种语言且正在使用
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
其余的是 “无用”:
| 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
与TINYINT
与VARCHAR
之间的倡导者之间存在“宗教战争”。)
- 通常,“short”列总是长度相同。 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
。如果你的桌子上只有几个点,那就不值得担心了。
- 我的Rules of Thumb之一表示,如果您不太可能获得10%的改进,请继续进行其他优化。我们在这里讨论的大部分内容都低于10%(本例中为空间)。不过,在编写
CREATE TABLE
时应养成考虑它的习惯。我经常看到带有BIGINT
和DOUBLE
(每个8字节)的表格,可以很容易地使用较小的列。有时节省50%以上(空间)。
- “空间”如何转化为“速度”?微小的表格 - >很小的百分比。巨大的表 - >在某些情况下10倍。 (这是10倍,而不是10%。)(UUID的是获得巨大的表非常糟糕表现的一种方式。)
ENUM
- 行为,感觉就像一个字符串,但需要只有一个字节。(一个字节间接转化为轻微的速度提升。)
- 实际应用的时候少于10个不同的值。
- 如果经常添加一个新的值不切实际 - 需要
ALTER TABLE
,尽管它可以是“inplace”。
- 建议从
'unknown'
(或类似的东西)开始列表,并使列NOT NULL
(与NULL
相比)。
- 枚举的字符集需要是其他方式用于连接的。除非您有整理等于(例如,
A
与a
)的选项,否则选择并不重要。
如果字符超出ASCII范围,UTF-8仅使用多个字节。字符串化的UUID(如果这就是您使用的GUID)始终落在该范围内。 – robertklep
@robertklep我听说,这是有道理的,但我认为这不适用于指数(空间消耗)!?例如,在将utf8列转换为latin1时,'EXPLAIN SELECT'显示2/3更小的'key_len'值。 – toshniba
啊,我没有考虑(我对MySQL/InnoDB索引如何实现不了解太多)。 – robertklep