MySQL varchar索引存储

时间:2016-03-24 09:06:08

标签: mysql sql indexing enums

我有一个使用Laravel框架构建的应用程序。它的一个特性是能够在表之间创建多态关系。它通过存储相关表的ID和相关表模型的完全限定类名来实现。可以想象,根据模型的名称空间和类名,某些条目可能会很长。

在我的场景中,我有4张桌子。基表A是多态的。表格BCD不是。

非多态表模型的类名如下:

LongNamespace\SubNamespace\Something\B
LongNamespace\SubNamespace\Something\C
LongNamespace\SubNamespace\Something\D 

A的结果如下:

id | relation_id | relation_type
--------------------------------
1  | 1           | LongNamespace\SubNamespace\Something\B
2  | 2           | LongNamespace\SubNamespace\Something\C
3  | 5           | LongNamespace\SubNamespace\Something\D
4  | 12          | LongNamespace\SubNamespace\Something\D
5  | 3           | LongNamespace\SubNamespace\Something\B
6  | 6           | LongNamespace\SubNamespace\Something\C

... etc (around 50,000 rows) ...

每个记录添加了38个字节,其中大部分是重复数据,我的问题是,会在relation_type列存储器中为每个单独的relation_type记录添加一个索引(我假设是索引会发生什么,或者它会像ENUM一样对它们进行分组,因此总存储量将是relation_type中的3个唯一条目,然后通过某种哈希表在内部关联,节省n * 38个字节的值太空了。

1 个答案:

答案 0 :(得分:0)

索引包含所有索引列的所有文本,以及(在InnoDB的情况下)所有PRIMARY KEY列的所有文本。因此,38 * n字节被浪费了'。

如果您宣布relation_type

ENUM(`LongNamespace\SubNamespace\Something\B`,
     `LongNamespace\SubNamespace\Something\C`,
     `LongNamespace\SubNamespace\Something\D`,
     ...)

那么它只需要1或2个字节,但就像那些39字节的字符串一样。

当您添加另一个表等时,当然会出现维护问题。

另一方面,38 * 50K = ~2MB"小",并没有什么大不了的。

不,索引不会保存在RAM中。然而,它是"缓存"在RAM中,逐块。因此,如果索引(或表)非常大,那么由于没有停留在缓存(RAM)中,会有额外的I / O.但它仍然会工作#34;虽然很慢。