我知道列式数据库将列数据放在磁盘上而不是行上。我也明白在传统的 row-wise RDBMS 中,B-Tree 的叶子索引节点包含指向实际行的指针。
但是由于 columnar 不会将行存储在一起,而且它们是专门为列式操作而设计的,它们在索引技术上有何不同?
我一直在寻找,但找不到任何文字。我找到的每个文本都是针对行式 DBMS 的。
没有 BTree。(或者,如果是的话,它们不是设计的主要部分)
Infinidb 每个块存储 64K 行。该块中的每一列都被压缩并建立索引。块是一个列表,其中包含每列的最小值、最大值、平均值等,这些列可能对查询有帮助,也可能没有帮助。
首先运行 aSELECT查看每个块的摘要信息,以查看块中的任何行是否可以满足WHERE该子句。
通过过滤的块会得到更详细的观察。
没有行的副本。相反,如果您要求SELECT a,b,c,则需要解压缩 a、b、c 中每一个的 64K 行(在一个块中)的压缩信息,以进一步过滤和传递该行。因此,您应该只列出所需的列,而不是盲目地说SELECT *。
由于每列始终都是单独索引的,因此无需多说INDEX(a)。(我不知道是否INDEX(a,b)可以为柱状数据库指定。)
注意:我正在描述 Infinidb,它可以与 MariaDB 一起使用。我不知道还有其他柱状发动机。
如果您了解 1) 列式 DB 实际如何存储数据,以及 2) 索引如何工作,(它们如何存储数据)那么您可能会觉得在列式 Db 中不需要索引。
对于任何一种数据库,rowid 都是非常重要的,它就像数据存储的地址。索引不过是将 rowids 映射到按排序顺序索引的列。列式数据库就是基于这种逻辑而诞生的。他们尝试以这种方式本身存储数据,这意味着 - 他们以序列化方式将数据存储为键值对,其中实际列值是 Key 和 rowid 当数据作为其值驻留时,如果他们发现任何密钥的重复项,它们只是压缩和存储。
因此,如果您比较列式数据库如何将数据实际存储在磁盘上的格式,它几乎相同(但不完全相同,因为不同之处在于压缩,键值的表示反之亦然)面向行的数据库如何存储索引。
这就是您不再需要单独索引的原因。并且您不会发现任何试图实现索引的列式数据库。