Project Icon

stanchion

SQLite列式存储扩展 提升大规模数据分析性能

Stanchion是一个为SQLite引入列式存储能力的扩展。通过仅扫描查询所需列数据和采用压缩技术,该扩展显著提升了分析查询和宽表的性能。Stanchion适用于处理指标、日志、事件和时间序列等数据,以及执行大规模分析查询。它能在现有SQLite部署中实现列式存储和数据仓库的优势,无需改变现有技术架构。

Stanchion

SQLite 中的面向列的表

为什么选择 Stanchion?

Stanchion 是一个 SQLite 3 扩展,它为 SQLite 这个使用最广泛的数据库带来了面向列存储的强大功能。SQLite 仅支持面向行的表,这意味着它并不适用于所有工作负载。使用 Stanchion 插件可以将面向列存储和数据仓库的所有优势带到 SQLite 已经部署的任何地方,包括您现有的技术栈。

在许多情况下,面向列的存储性能优于面向行的存储:

  • 存储和处理指标、日志和事件数据
  • 时间序列数据存储和分析
  • 对多行少列进行分析查询(例如计算数月每小时天气数据的平均温度)
  • 变更跟踪、历史/时态表
  • 锚点建模 / 类 Datomic 数据模型

Stanchion 非常适合分析查询和宽表,因为它只扫描给定查询引用的列的数据。它使用运行长度和位压缩编码等压缩技术,大大减少了存储数据的大小,极大地降低了大型数据集的成本。这使其成为存储大型、不断扩展的数据集的理想解决方案。

示例

从 Release 下载适用于您平台的预构建动态库或从源代码构建

.load /path/to/libstanchion

CREATE VIRTUAL TABLE dnd_monsters
USING stanchion (
    id INTEGER NOT NULL,
    name TEXT NOT NULL,
    type TEXT NOT NULL,
    size INTEGER NOT NULL,
    challenge_rating FLOAT NOT NULL,
    SORT KEY (id)
);

INSERT INTO dnd_monsters (id, name, type, size, challenge_rating)
VALUES
    (1, 'Beholder', 'ABERRATION', 4, 13),
    (2, 'Gelatinous Cube', 'OOZE', 4, 2),
    (3, 'Mimic', 'MONSTROSITY', 3, 2),
    (4, 'Lich', 'UNDEAD', 3, 21);

-- 因为 `dnd_monsters` 表是面向列的,所以以下查询
-- 只读取 `name`、`type` 和 `challenge_rating` 列的数据。
-- `id` 和 `size` 列中的数据根本不会被访问或扫描!
SELECT name
FROM dnd_monsters
WHERE type = 'UNDEAD' AND challenge_rating >= 18;

状态

Stanchion 处于 alpha 阶段。某些功能可能尚未完全实现。存储格式可能会以不向后兼容的方式发生变化。暂时不要在生产环境中使用

构建

安装 Zig (master 版本)并克隆 stanchion 仓库。然后运行:

zig build ext -Doptimize=ReleaseFast

SQLite 扩展是 zig-out 目录中名为 libstanchion 的动态库。

运行测试

默认情况下,测试使用系统 SQLite 库。但是,stanchion 的构建可以选择下载并编译特定版本的 SQLite,并在运行测试时使用该版本。通过 -Dsqlite-test-version=$SQLITE_VERSION 参数来构建单元测试和集成测试。例如:

zig build test -Dsqlite-test-version=3.38.5

还可以为任何版本的 SQLite 启动 SQLite shell(这是一个用于调试的便利功能):

zig build sqlite-shell -Dsqlite-test-version=3.43.2

使用方法

加载 Stanchion

Stanchion 是一个使用 SQLite 虚拟表系统的运行时可加载扩展。要从 SQLite CLI 加载扩展,请使用 .load 命令。查看您正在使用的 SQLite 绑定的文档,了解如何在应用程序中加载扩展。以下是不同语言绑定的一些示例:Python 的 sqlite3Rust 的 rusqliteRuby 的 sqlite3Go 的 go-sqlite3

在加载 stanchion(或任何扩展)之前,您可能需要先启用扩展加载。以下是不同语言绑定的一些示例:Python 的 sqlite3Rust 的 rusqliteRuby 的 sqlite3。某些绑定默认启用扩展加载(例如 Go 的 go-sqlite3)。有关更多信息,请参阅 SQLite C API 文档

Stanchion 既是持久性扩展,也是自动扩展。它只需要在一个进程中的一个连接中加载一次,然后它将自动被同一进程中的所有连接加载。从其他连接再次加载它也无害。连接到同一 SQLite 数据库的其他进程中的连接仍然需要加载 stanchion。

创建表

创建 stanchion 表的方式与在 SQLite 中创建任何表非常相似:

CREATE VIRTUAL TABLE sensor_log USING stanchion (
    sensor_id TEXT NOT NULL,
    timestamp INTEGER NOT NULL,
    value FLOAT NULL,
    variance FLOAT NULL,
    severity INTEGER NOT NULL,
    SORT KEY (sensor_id, timestamp)
)

USING stanchion 短语告诉 SQLite 将 sensor_log 创建为由 stanchion 实现的虚拟表。

所有 stanchion 表都需要 SORT KEY。它定义了聚集索引,即表中记录的顺序。SORT KEY 不强制唯一性。目前,SORT KEY 只能包含列而不能包含表达式。

Stanchion 表不支持外键、主键、检查或唯一约束。在面向列的表更有用的场景中,这些约束通常不太有用,而且在面向列的数据库中并不广泛支持。但是,将来可能会将部分或全部这些约束作为选项引入 stanchion。

数据类型

下表显示了所有 stanchion 数据类型。布尔值在通过 SQLite 时会转换为整数。这允许它们在查询和 SQLite API 中使用,因为 SQLite API 不支持专用的布尔类型。有关 BOOLEAN 类型的更多信息,请参阅与 SQLite 的区别: BOOLEAN 类型

Stanchion 类型SQLite 类型别名
BOOLEANINTEGERBOOL
INTEGERINTEGERINT
FLOATREALREAL, DOUBLE
BLOBBLOB
TEXTTEXTVARCHAR*

* 不支持字符计数

没有 ANY 类型,所有插入的值必须与声明的列类型匹配。在 stanchion 表中不可能进行动态类型。Stanchion 表大致相当于声明为 STRICT 的 SQLite 表(不包含任何类型)。

支持少量常用类型名称的别名。使用别名声明列与使用规范类型名称声明没有区别。

添加和查询数据

插入和查询数据的方式与 SQLite 中的任何其他表相同。Stanchion 表甚至可以使用 .import 命令等功能来向表中添加记录。

INSERT INTO sensor_log (sensor_id, timestamp, value, variance, severity)
VALUES
    (2064, 12433702443, 74.37, 1.06, 1),
    (2064, 12433703443, 73.12, 0.96, 1)

插入 Stanchion 表的值必须是列声明的类型。这相当于使用 STRICT 表选项声明 SQLite 表。

目前不支持更新和删除记录。未来将添加对更新和删除的支持。

Stanchion 表可以在 SQLite 中使用原生表的所有地方使用。在编写查询时,将 SORT KEY 视为复合索引以提高查询性能。在以下查询中,使用排序键来减少扫描的数据量。当然,只读取 sensor_idtimestampvalue 列。

SELECT AVG(value)
FROM sensor_log
WHERE sensor_id = 2064 AND timestamp > 12433700000

与 SQLite 的区别

BOOLEAN 类型

Stanchion 有一个专用的 BOOLEAN 类型。布尔值在 stanchion 内部用作每个可空段的一部分,并公开以便也可以直接使用。

SQLite 使用 INTEGER 表示布尔值。Stanchion 在通过 SQLite 传递时将 BOOLEAN 值转换为 INTEGER 值。查询 BOOLEAN stanchion 列会返回 INTEGER SQLite 值。

SORT KEY 定义的聚集索引

在 Stanchion 中,表中记录的顺序(即聚集索引)由 SORT KEY 控制。目前,stanchion 中的每个表都必须有一个由 1 个或多个列组成的显式 SORT KEY(目前不支持表达式)。它在创建表时声明,不能更改。与 PRIMARY KEY 不同,它不强制唯一性。

这与 SQLite 不同,SQLite 中的表默认按 ROWID 排序,或者如果表是 WITHOUT ROWID 表,则按 PRIMARY KEY 排序。

无唯一性(UNIQUEPRIMARY KEY)或外键约束

这可能在未来发生变化。实现这些功能可能需要外部索引。当/如果引入"主键"时,可能会合理地遵循Clickhouse的"MergeTree"引擎的做法,要求"主键"必须是"排序键"的前缀。

无外部索引

目前没有外部索引机制。用于优化查询的唯一索引是使用"SORT KEY"声明的聚集索引。

强制执行列类型

插入Stanchion表的值必须符合列的声明类型。这相当于使用"STRICT"表选项声明SQLite表。

暂不支持更新或删除

未来将在Stanchion中添加对"UPDATE"和"DELETE"的支持。

表结构无法更改

这是Stanchion希望支持的功能,但可能会很困难,因为SQLite没有记录支持虚拟表架构更改的方法。目前仍在调查中。

待办事项

即将推出的功能的高层次路线图(仅粗略排序):

  • 重命名表
  • 优化表
  • 并发安全性和测试
  • 更多编码:RLE、字典、Chimp等
  • 字节级无损压缩(如zstd)
  • 将SQLite原生表转换为Stanchion表的函数
  • 发布与SQLite、DuckDB和chDB的基准测试
  • "DELETE"和"UPDATE"
  • 配置参数和调优
  • 在iOS和Android应用中使用Stanchion的指南
  • 架构更改(SQLite虚拟表本身不支持)
  • 列表数据类型

数据存储内部结构

行组、段和条带

每个表中的记录分组为行组。每个行组最多包含固定数量的记录。行组是逻辑(非物理)分组,并按行组内的最小排序键值进行索引。目前,行组是不可变的,当新插入的记录数量超过阈值时,它们由一批新插入的记录(可能还包括现有行组的值)构建而成。

一个行组由多个段组成。一个段包含单个列的数据。可以将每个行组视为表中的一个数据跨度,而每个段则是列中的一个数据跨度。一个段由单个SQLite"BLOB"值支持。目前,段是不可变的。

每个段由1个或多个条带组成。条带是同一类型的数据块,由段的"BLOB"值的一部分(片段)支持。一个段可以包含以下条带:存在、主要和长度。当段包含空值时,主要条带用于指示每个记录中的值是否不为"NULL"。对于"BOOLEAN"、"INTEGER"和"FLOAT"列,值存储在主要条带中。对于"TEXT"和"BLOB"列,值的字节存储在主要条带中,每个值的长度存储在长度条带中。

待处理插入

当记录添加到Stanchion表时,它们被插入到一个标准的持久化B+树(即原生的、面向行的SQLite表)中,称为待处理插入表。由于它是一个原生的SQLite表,记录以面向行的方式存储。它们按排序键排序,以便能够高效地合并到行组中。

首先将记录存储在待处理插入表中的原因是,创建段需要拥有将进入该段的所有数据。创建段时,使用的编码取决于要存储在段中的值,并非所有编码都支持高效追加。此外,当数据表现出可被编码利用的模式,且每个段有更多数据时,可以实现更高的压缩率。待处理插入表充当缓冲区,在其中存储记录,直到有足够的记录以创建段为止。

当查询按排序键列进行筛选时,Stanchion将该筛选器直接应用于待处理插入,以限制访问哪些待处理插入。按排序键筛选是Stanchion目前唯一支持的索引机制。

行组索引

行组索引是一个原生的、面向行的SQLite表,它按每个行组的起始(最小)排序键对行组进行索引。当查询按排序键列进行筛选时,Stanchion将该筛选器应用于主索引,以限制访问哪些行组。按排序键筛选是Stanchion目前唯一支持的索引机制。

贡献

请参阅CONTRIBUTING.md

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号