列式数据库中的多列选择

abi*_*abi 0 sql database indexing

我只是了解基于行和基于列的数据库之间的区别。我知道它们的好处,但我有几个问题。假设我有一个包含 3 列的表 - col1、col2 和 col3。我想获取所有 col2、col3 对,其中 col3 与特定值匹配。假设列值存储在磁盘中,如下所示。

块 1 = col1
块 2,块 3 = col2
块 4 = col3

  1. 我的理解是列值和行 ID 信息将存储在一个块中。例如:(Block4 -> 苹果:row_2,香蕉:row_1)。我对么?
  2. 块中的值是否按列值排序?例如:(Block4 -> apple:row_2, Banana:row_1 而不是 Block4 -> Banana:row_1, apple:row_2)。如果不是,过滤或搜索如何在不影响性能的情况下工作?
  3. 假设块中的值根据列值排序,那么如何根据从 Block4 获取的行 id 过滤相应的 col2 值?那么需要线性搜索吗?

Gor*_*off 5

列式数据库的目的是通过将 IO 限制为查询中使用的列来提高读取查询的性能。它通过将列分成单独的存储空间来实现这一点。

列式数据库的简单形式将使用主键存储一个或一组列,然后用于将JOIN表中的所有列组合在一起。未引用的列将不包括在内。

然而,为列式数据库提供本机支持的数据库比简单的示例具有更复杂的功能。每个列式数据库都以自己的方式存储数据。因此,您的答案取决于您未指定的特定数据库。

它们可能存储列的值“块”,这些块代表(以某种方式)一系列行。因此,如果您从 10 亿行表中选择 1 行,则只需读取包含这些行的块。

单独存储列可以增强列级别的功能:

  1. 压缩。具有相同数据类型的值比包含不同值的行更容易压缩。
  2. 区块统计。可以对块进行统计汇总(例如最小值和最大值),这可以促进过滤。
  3. 二级数据结构。例如,索引可以在块内使用(实际上,这些可能类似于“排序”值)。

所有这一切的代价是插入不再简单,因此列方向的 ACID 属性更加棘手。由于此类数据库通常用于决策支持查询,因此这可能不是一个重要的限制。

“行”本质上是由行 ID 确定的。然而,行 id 实际上可能由多个部分组成,例如块 id 和块内行。这允许存储为每个组件使用 4 个字节,但不限于 40 亿行。

对于任何此类数据库来说,在不同列之间重建行显然是一个关键功能。在“简单”示例中,这是通过JOIN算法处理的。然而,专门的数据结构显然会有更具体的方法。基本上按“行顺序”存储数据将是一个典型的解决方案。