用原生SQL而不是DSL,17,494颗星背后的SQLx正在重新定义Rust数据库访问
用原生 SQL 而不是 DSL,17,494 颗星背后的 SQLx 正在重新定义 Rust 数据库访问
如果你用 Rust 写过后端服务,并且用过任何一种”主流”ORM,大概率踩过这个坑:学 DSL 的成本比直接写 SQL 还高,遇到复杂查询时 DSL 表达不了,还得绕回原生 SQL——等于同时学了两套东西。
SQLx 想解决的就是这个问题。它不是 ORM,不提供 Rust 风格的查询构建 DSL;它做的是另一件事:让你继续写原生 SQL,但把 SQL 正确性的检查从运行时搬到编译时。
这不是一个新想法,但 SQLx 是目前把这个想法做得最完整的一个。
编译时检查 SQL,不是用 Rust 语法替代 SQL
SQLx 的核心机制是 sqlx::query! 系列宏。当你写这样一段代码:
let row: (i32, String) = sqlx::query_as!(
"SELECT id, name FROM users WHERE id = $1",
user_id
)
.fetch_one(&pool)
await?;
query_as! 宏会在编译时连接你指定的开发数据库,让数据库本身验证这条 SQL 是否合法、参数类型是否匹配、返回的列能否解构成 i32 和 String。任何拼写错误、类型错误、列名错误,都会变成编译报错,而不是线上故障。
这个过程发生在编译阶段,不影响生产运行的零依赖。生产环境不需要运行数据库来做类型检查。
为什么这个区别很重要
2026 年 5 月有一篇 Rust ORMs 2026 对比 详细拆解了三家方案的取舍。SQLx 的核心论点是:ORM 在做一件费力不讨好的事——用另一种语言重新实现 SQL,而 SQL 本身已经是一个高度优化的查询语言。
Diesel 的方案是提供类型安全的 DSL,代价是学习曲线陡峭、复杂查询表达力受限。SeaORM 试图在 Active Record 模式和异步支持之间找平衡。SQLx 则直接放弃了 DSL 这一层,选择相信开发者会写 SQL,然后用编译时检查来保证安全。
这不是说 DSL 不好——DSL 有它的价值,比如防止注入、统一 API 风格。但如果你知道自己要做什么、需要什么,SQLx 让你不受约束地做。
17,494 颗星背后的技术细节
SQLx 目前最新版本为 v0.9.0(2026年5月发布),引入了 sqlx.toml 配置文件和更严格的 SQL 安全机制。这个版本的变化值得注意:它开始向”SQLx 作为工程规范工具“的方向演进,不只是库,而是一套实践。
核心数据:
- Stars: 17,494 | Forks: 1,694
- 驱动支持: PostgreSQL、MySQL、MariaDB、SQLite(MSSQL 支持在 0.7 版本前有,后因重写需求暂时移除)
- 运行时: tokio / async-std / actix,三选一
- TLS: native-tls(OpenSSL/SChannel/Secure Transport)或 rustls(纯 Rust 实现)
- Pure Rust: PostgreSQL 和 MySQL/MariaDB 驱动完全用 Rust 编写,使用
#![forbid(unsafe_code)];SQLite 因需要调用 libsqlite3 C 库,属于例外
内置功能包括连接池(sqlx::Pool)、行流式读取(异步从数据库读取、按需解码)、自动语句预处理与缓存(高频查询不用每次重新解析),以及 PostgreSQL 的 LISTEN/NOTIFY 异步通知机制。
嵌套事务和保存点支持在金融或需要部分回滚的场景下很有用。
基准测试表现
2026 年 5 月的 5 Rust 1.88 数据库驱动基准测试 覆盖了 sqlx、diesel、mongodb 等驱动。SQLx 在大多数读写场景下与 Diesel 持平,在需要高频小查询的场景中略有优势,主要来自连接池管理和语句缓存的优化。纯 HTTP 层面的基准测试意义有限,具体场景还需实测。
谁该用,谁该等
适合用 SQLx 的团队:
- 已有数据库背景、习惯写原生 SQL 的后端开发者
- 对编译时类型安全有强需求,不想把 SQL 错误留到线上
- 需要同时连接多种数据库(PostgreSQL + MySQL 或 SQLite),想用统一 API 切换
- 使用 tokio 构建异步服务,已经引入了异步生态
不适合用 SQLx 的场景:
- 团队完全不懂 SQL,期望用 Rust 语法绕过 SQL 学习曲线——这个期望本身就跑偏了
- 需要非常重的 ORM 特性(关联加载、懒加载、模型生命周期管理)——去看 SeaORM 或 Diesel
- 嵌入式/无标准库场景,SQLite 是唯一选项但希望完全摆脱 C 依赖——SQLx 的 SQLite 驱动仍依赖 libsqlite3
一个具体的下一步
如果你用 tokio,cargo run 之前只需要加一行配置就能开启编译时检查:
# Cargo.toml
sqlx = { version = "0.9", features = ["runtime-tokio", "tls-native-tls", "postgres", "macros"] }
然后设置环境变量 DATABASE_URL,运行 cargo sqlx prepare,之后任何 SQL 错误都会在编译时报出。如果你想看真实项目结构,GitHub 上 LaunchBadge 团队维护的 Ecosystem wiki 列出了基于 SQLx 构建的周边工具和 ORM 封装,可以作为参考起点。
链接汇总:
- GitHub:https://github.com/transact-rs/sqlx
- 文档:https://docs.rs/sqlx
- Crates.io:https://crates.io/crates/sqlx
- Rust ORMs 2026 对比:https://rustify.rs/articles/rust-sqlx-vs-diesel-vs-seaorm-2026
- Rust 日报 SQLx 0.9.0 发布:https://rustcc.cn/article?id=e7b83f3b-49eb-4ff4-ac8c-d9c541abc406
- 基准测试:https://www.johal.in/benchmark-rust-188-database-drivers-sqlx-vs-diesel
评论区
登录后可评论。