4个版本 (2个重大更新)

0.3.0 2024年4月18日
0.2.1 2024年1月16日
0.2.0 2023年10月14日
0.1.0 2023年9月8日

#33 in 数据库实现


3 个crate中使用 (通过 izihawa-tantivy)

MIT 许可证

755KB
18K SLoC

列格式

本crate描述了tantivy中使用的列格式。

目标

此格式具有以下特殊之处。

  • 需要紧凑
  • 访问特定列不需要加载整个列存储。可以在2到3次随机访问中完成。
  • 具有不同类型的列可以关联到相同的列名。
  • 需要支持具有不同类型 (str, u64, i64, f64) 和不同基数 (必需, 可选, 多值) 的列。
  • 一旦加载,列提供便宜的成本随机访问。
  • 它被设计为允许范围查询。

强制规则

用户可以通过向ColumnarWriter插入行来创建列式存储,并将其序列化为Write对象。用户无法阻止将不同类型的值记录到相同的column_name中。

在这种情况下,tantivy-columnar的行为如下

  • Json值被分为3种类型(字符串、数字、布尔)。对应不同组的值映射到不同的列。例如,字符串值独立于数字或布尔值处理。tantivy-columnar将简单地发出与给定column_name相关联的多个列。
  • 对于给定的json值类型,只发出一个列。如果记录了不同数字类型的数字值(例如,u64、i64、f64),tantivy-columnar将选择第一个可以表示附加值集合的类型,优先顺序如下(i64u64f64)。i64被优先选择,因为它可能产生更少的类型变化。大多数严格要求u64的用例显示出对50%的值(例如,64位哈希)的限制。另一方面,许多用例可能会显示出罕见的负值。

列格式

这种列式格式可能具有多个列(不同类型)与同一column_name相关联(参见上面的强制规则)。然而,(column_name, columne_type)对唯一标识一个列。这对是序列化为列column_key。该键的格式为:[column_name][ZERO_BYTE][column_type_header: u8]

COLUMNAR:=
    [COLUMNAR_DATA]
    [COLUMNAR_KEY_TO_DATA_INDEX]
    [COLUMNAR_FOOTER];


# Columns are sorted by their column key.
COLUMNAR_DATA:=
    [COLUMN_DATA]+;

COLUMNAR_FOOTER := [RANGE_SSTABLE_BYTES_LEN: 8 bytes little endian]

列式文件以实际列数据开始,按列键排序连接在一起。

一个sstable将`(column name, column_cardinality, column_type)`与字节数的范围相关联。

列名不能包含零字节\0

列出与column_name关联的所有列,可以通过列出以[column_name][ZERO_BYTE]前缀的所有键来完成。

相关的字节数范围指的是字节数范围

此crate暴露了tantivy的列式格式。此格式在README.md中描述

此crate引入了以下概念。

Columnar是数据框的等价物。它将column_key映射到Column

Column<T>将一个RowId(u32)关联到任意数量的值。

这是通过包装一个ColumnIndex和一个ColumnValue对象来实现的。该ColumnValue<T>代表一个映射,将每个RowId映射到恰好一个值。

然后,ColumnIndex将每个RowId映射到ColumnValue中的RowId集合。

为了优化和压缩目的,ColumnIndex有三种可能的表示形式,每种形式适用于不同的基数。

  • 完整

所有RowId都恰好有一个值。ColumnIndex是平凡的映射。

  • 可选

所有 RowIds 都只能有一个值。ColumnIndex 是一个简单的映射 ColumnRowId -> Option<ColumnValueRowId>

  • 多值

所有 RowIds 可以有任意数量的值。列索引是将值映射到范围。

所有这些对象都在它们自己的模块中独立实现和测试。

  • 列式
  • 列索引
  • 列值

依赖关系

~8MB
~128K SLoC