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

编辑推荐精选

GPT Plus|Pro充值

GPT Plus|Pro充值

GPT充值

支持 ChatGPT Plus / Pro 充值服务,支付便捷,自动发货,售后可查。

GPT Image 2中文站

GPT Image 2中文站

AI 图片生成平台

GPT Image 2 是面向用户的 AI 图片生成平台,支持文生图、图生图及多模型创意工作流。

Vecbase

Vecbase

你的AI Agent团队

Vecbase 是专为 AI 团队打造的智能工作空间,将数据管理、模型协作与知识沉淀整合于一处。算法、产品与业务在同一平台无缝协同,让从数据到 AI 应用的落地更快一步。

音述AI

音述AI

全球首个AI音乐社区

音述AI是全球首个AI音乐社区,致力让每个人都能用音乐表达自我。音述AI提供零门槛AI创作工具,独创GETI法则帮助用户精准定义音乐风格,AI润色功能支持自动优化作品质感。音述AI支持交流讨论、二次创作与价值变现。针对中文用户的语言习惯与文化背景进行专门优化,支持国风融合、C-pop等本土音乐标签,让技术更好地承载人文表达。

QoderWork

QoderWork

阿里Qoder团队推出的桌面端AI智能体

QoderWork 是阿里推出的本地优先桌面 AI 智能体,适配 macOS14+/Windows10+,以自然语言交互实现文件管理、数据分析、AI 视觉生成、浏览器自动化等办公任务,自主拆解执行复杂工作流,数据本地运行零上传,技能市场可无限扩展,是高效的 Agentic 生产力办公助手。

lynote.ai

lynote.ai

一站式搞定所有学习需求

不再被海量信息淹没,开始真正理解知识。Lynote 可摘要 YouTube 视频、PDF、文章等内容。即时创建笔记,检测 AI 内容并下载资料,将您的学习效率提升 10 倍。

AniShort

AniShort

为AI短剧协作而生

专为AI短剧协作而生的AniShort正式发布,深度重构AI短剧全流程生产模式,整合创意策划、制作执行、实时协作、在线审片、资产复用等全链路功能,独创无限画布、双轨并行工业化工作流与Ani智能体助手,集成多款主流AI大模型,破解素材零散、版本混乱、沟通低效等行业痛点,助力3人团队效率提升800%,打造标准化、可追溯的AI短剧量产体系,是AI短剧团队协同创作、提升制作效率的核心工具。

seedancetwo2.0

seedancetwo2.0

能听懂你表达的视频模型

Seedance two是基于seedance2.0的中国大模型,支持图像、视频、音频、文本四种模态输入,表达方式更丰富,生成也更可控。

nano-banana纳米香蕉中文站

nano-banana纳米香蕉中文站

国内直接访问,限时3折

输入简单文字,生成想要的图片,纳米香蕉中文站基于 Google 模型的 AI 图片生成网站,支持文字生图、图生图。官网价格限时3折活动

扣子-AI办公

扣子-AI办公

职场AI,就用扣子

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

下拉加载更多