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)
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
将选择第一个可以表示附加值集合的类型,优先顺序如下(i64
,u64
,f64
)。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