深入了解Turso,这个“用Rust重写的SQLite”

我喜欢 Rust,也喜欢 SQLite,所以你可以想象,当我得知"SQLite 正在用 Rust 重写"时,我有多么兴奋: Turso

SQLite 可能是世界上部署最广泛的数据库,你的任何设备上都有数十个数据库,它也可能是最可靠的软件之一,其测试数量是代码数量的 590 倍(我知道测试也是代码,这只是为了简化):约 92,053,100 行测试代码 vs 约 155,800 行代码

此外,几乎所有编程语言都有 SQLite 绑定,所以为什么有人会想用 Rust 重写它呢?

SQLite到底是什么?

提到 SQLite,大多数人首先想到的是 C 库、它的可靠性、传奇般的测试覆盖率以及易于嵌入的特性。

但是,SQLite 也可以被视为一种单文件数据库格式的规范,而这正是有趣之处。SQLite 数据库本质上是一个高度优化的 B+ 树集合,存储在磁盘(或内存)上,并包含模式和一些元数据。

如果我们有其他能够理解这种文件格式的数据库引擎呢?Turso 正是如此:它是一款全新的数据库引擎,(大部分情况下,除了 MVCC 模式等极少数例外)与 SQLite 数据库文件格式兼容,但在架构层面上却完全不同。

用户体验也相同,至少在 Rust 中是这样,以下是一个 Hello World 示例:

复制代码
use turso::{Builder, EncryptionOpts};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
    let db = Builder::new_local("test.db").build().await?;
    let conn = db.connect()?;

    let rows = conn.query("SELECT * FROM users", ()).await?;

    return Ok(());
}

SQLite 很棒,但存在很多问题

诚然,SQLite 堪称一件艺术品,但它也存在许多问题,会给毫无防备的开发者带来麻烦。

首先,SQLite 测试套件不是开源的,因此想要修改它的人无法像原开发者那样安心地进行修改。

其次,SQLite 的开发者并不真正接受外部贡献。你可以报告 bug(他们会尽快修复)和提出功能请求,但这可能不足以满足你的需求。

最后,SQLite 是用 C 语言编写的,这使得它容易出现一些很容易避免的错误,这一点可以从变更日志中看出。此外,由于 C 语言糟糕的类型系统和不安全的内存管理,也使得维护和添加新功能变得非常困难。

除此之外,SQLite 还不支持(官方的)并发写入,SQLite 的列默认是弱类型的,这与数据库的预期不符,而且模式更改可能会很麻烦,因为某些操作需要您自己复制整个表。

其中大部分问题都可以通过用 Rust 重写来解决。

《为什么 SQLite 是用 C 语言编写的》一文中,SQLite 的作者暗示 Rust 是重写 SQLite 的最佳选择,但 Rust 目前还不能满足所有要求,因为 SQLite 部署在非常特殊的地方,而 Rust 代码目前还无法部署到这些地方。

我从创新者的困境角度来看待这种情况:现有企业不愿意牺牲一部分市场份额进行变革,所以我们需要新的竞争者来创新。

Turso 不断创新:甚至在达到 v1.0 版本之前,他们就已经解决了开发者在使用 SQLite 时遇到的绝大多数长期痛点,这些痛点已在《优化 SQLite 以适应服务器》一文中有所介绍:

这还没提到 Rust 提供的所有其他好处,例如借用检查器、内存安全以及具有清晰抽象的高级代码,这些都使得无所畏惧的重构成为可能。

一个可扩展到多台机器的进程内数据库

Turso 最容易被误解的特性之一是,它被设计成既可以用作进程内数据库,也可以像 PostgreSQL 一样用作网络数据库,因此其背后的公司可以销售云托管解决方案。

作为一名开发者和创业者,这正是我梦寐以求的数据库:我的十个项目中,有九个只需要一台虚拟机,因此 SQLite/Turso 的进程内模型非常适合它们。但是,对于那些获得用户增长并需要扩展的项目(正如我之前提到的),SQLite 就不太合适了,因为它不支持并发写入。而且,在项目扩展过程中,将应用程序从 SQLite 移植到 Postgres 会浪费你宝贵的时间。

这就是为什么大多数项目一开始就直接使用 PostgreSQL,"以防万一",但这会增加开发和运维过程中的摩擦,尤其是在需要管理扩展、升级数据库版本或管理备份时。

我们迫切需要一个能够从进程内扩展到网络化的数据库,但很少有人知道他们需要的是汽车/火车而不是更快的马。

在智能体时代,智能体在自己的沙箱中工作,你不希望因为每次会话都需要启动一个新数据库而增加额外的开销,这一点尤其如此。此外,对于那些既需要用于本地/嵌入式应用程序的嵌入式数据库,又需要用于后端的数据库的项目来说,这一点也同样适用。

扩展

SQLite 最棒的特性之一就是构建和加载自定义扩展非常容易。与 PostgreSQL 等网络数据库不同,后者通常由云服务提供商管理,用户只能使用有限的扩展,而 SQLite 扩展只是动态库,可以直接添加到容器中。您可以阅读我之前的文章《用 Rust 构建 SQLite 扩展》 ,了解如何用 Rust 构建快速安全的 SQLite 扩展。

Turso 已经支持扩展,并提供了一个 SDK 来用 Rust 编写扩展

以下是来自https://github.com/tursodatabase/turso/blob/main/extensions/crypto/src/lib.rs的一小段代码,向您展示为 Turso 构建扩展是多么容易。

复制代码
#[scalar(name = "crypto_sha256", alias = "crypto_sha256")]
fn crypto_sha256(args: &[Value]) -> Value {
    if args.len() != 1 {
        return Value::error(ResultCode::Error);
    }

    let Ok(hash) = sha256(&args[0]) else {
        return Value::error(ResultCode::Error);
    };

    Value::from_blob(hash)
}

结语

Turso 正是我期待已久的数据库!虽然我不认识他们,但团队看起来很强大,所以我祝他们好运,并(不)耐心地等待 v1.0 版本。

使用DuckDB处理分析数据和时间序列数据,使用 Turso 处理交易数据,我觉得我们终于回归了理智,此前多年来,分布式系统热潮导致所有数据(不足 100GB)都需要集群处理。

对他们来说,时机非常好,因为嵌入式数据库非常适合人工智能代理,所以我希望他们能够及时取得成功,并靠自身盈利,这样他们就不需要出售公司和/或将项目商业化,这对于风险投资支持的公司来说通常是一个风险。

https://kerkour.com/turso-sqlite

https://mp.weixin.qq.com/s/DW_zHKVjtPX7dCSV2Y6BsA

相关推荐
星越华夏2 分钟前
python中四种获取文件后缀名的方法
开发语言·python
lunzi_08263 分钟前
【学习笔记】《Python编程 从入门到实践》第9章:类、继承、组合与面向对象编程
笔记·python·学习
思陌Ai算法定制4 分钟前
【心血管影像AI预测预后】心肌梗死后心脏MRI如何更早识别高风险患者?
人工智能·影像组学·心血管影像·心脏mri·心肌梗死·stemi·微循环阻塞
大蚂蚁2号4 分钟前
本地批量音视频转文本免费工具
python·音视频·开源软件
云烟成雨TD5 分钟前
Agent Scope Java 2.x 系列【6】消息层
java·人工智能·agent
云烟成雨TD6 分钟前
Spring AI Alibaba 1.x 系列【74】Agentic RAG 与混合 RAG
java·人工智能·spring
Tiansan66666 分钟前
郑州AI问答推广:2家优质服务商剖析
人工智能·郑州ai问答推广2家
“码”力全开9 分钟前
解耦异构算力:基于 Docker 与边缘计算的 GB28181/RTSP 企业级 AI 视频管理平台架构设计(含源码交付)
人工智能·docker·边缘计算
云烟成雨TD9 分钟前
Spring AI Alibaba 1.x 系列【79】图执行生命周期的可观测性基础设施
java·人工智能·spring
kishu_iOS&AI9 分钟前
LLM —— Milvmus向量数据库
数据库·人工智能·milvus