stanchion

stanchion

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

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

StanchionSQLite列式存储数据压缩虚拟表Github开源项目

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<sup>*</sup>

<sub>* 不支持字符计数</sub>

没有 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

编辑推荐精选

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
博思AIPPT

博思AIPPT

AI一键生成PPT,就用博思AIPPT!

博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。

AI办公办公工具AI工具博思AIPPTAI生成PPT智能排版海量精品模板AI创作热门
潮际好麦

潮际好麦

AI赋能电商视觉革命,一站式智能商拍平台

潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。

iTerms

iTerms

企业专属的AI法律顾问

iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。

SimilarWeb流量提升

SimilarWeb流量提升

稳定高效的流量提升解决方案,助力品牌曝光

稳定高效的流量提升解决方案,助力品牌曝光

Sora2视频免费生成

Sora2视频免费生成

最新版Sora2模型免费使用,一键生成无水印视频

最新版Sora2模型免费使用,一键生成无水印视频

Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
商汤小浣熊

商汤小浣熊

最强AI数据分析助手

小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。

imini AI

imini AI

像人一样思考的AI智能体

imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。

下拉加载更多