SurrealDB 2.0 Rust SDK 实战指南:从嵌入式引擎到远程客户端
【免费下载链接】surrealdbA scalable, distributed, collaborative, document-graph database, for the realtime web项目地址: https://gitcode.com/GitHub_Trending/su/surrealdb
本指南以surrealdbcrate 的官方发布说明(surrealdb/CARGO.md)为主体骨架,系统讲解 SurrealDB 的定位、安装部署、SurrealQL 核心用法以及 Rust SDK 的接入方式。读者读完将掌握:如何在 macOS / Linux / Windows / Docker 上快速启动 SurrealDB 服务器,如何用 SurrealQL 完成建模、建表、索引、事件、图查询、权限等操作,以及如何通过surrealdbcrate 在 Rust 中同时接入嵌入式与远程数据库。
SurrealDB 是一个端到端的云原生数据库,为现代应用(Web、移动端、Serverless、Jamstack、后端与传统应用)而设计,在 surrealdb/src/lib.rs 中被定义为 "a scalable, distributed, collaborative, document-graph database for the realtime web"。它同时充当数据库与实时协作式 API 后端,支持 SQL(客户端直连查询)、GraphQL、ACID 事务、WebSocket 连接、结构化与非结构化数据、图查询、全文索引、地理空间查询,以及基于行级权限的细粒度访问控制。
SurrealDB 是什么:数据库与 API 后端合二为一
从官方说明可以看到,SurrealDB 的核心价值在于简化数据库与 API 基础设施:
- 减少开发时间:省去大多数服务端组件,让开发者更快、更省成本地构建安全、高性能的应用。
- 实时协作式 API 后端服务:同时扮演数据库与 API 后端,天然支持实时协作场景。
- 多种查询语言支持:客户端直连 SQL、GraphQL、ACID 事务、WebSocket、结构化与非结构化数据、图查询、全文索引、地理空间查询。
- 细粒度访问控制:提供基于行级权限的访问控制,精确管理数据访问。
仓库的 Feature 清单完整展示了它的能力边界:
- 可作为数据库服务器运行,也可作为嵌入式库使用;
- 多行、多表 ACID 事务;
- 单节点或高可扩展分布式模式;
- 记录链接(record links)与有向类型化图连接;
- 同时存储结构化与非结构化数据;
- 增量计算视图(incrementally computed views),用于预计算的进阶分析;
- 内置实时 API 层与安全权限;
- 以表、文档、图三种方式任意建模;
- 为前后端开发提供简单 schema 定义;
- 支持从浏览器与客户端设备直连查询;
- 支持嵌入 JavaScript 函数实现自定义高级功能。
快速安装:从三平台命令行到 Docker
官方文档强调 SurrealDB"一条命令即可安装运行"。仓库 docker/Dockerfile 与 docker/DOCKER.md 证实了 Docker 是官方主推的部署方式之一。
macOS
最快的方式是使用 Homebrew,它会同时安装命令行工具与 SurrealDB 服务器(单一可执行文件):
brew install surrealdb/tap/surreal如果不使用 Homebrew,可参照下方 Linux 的安装方式。
Linux
在 Unix 系操作系统上,推荐通过官方安装脚本安装命令行工具:
curl -sSf https://install.surrealdb.com | shWindows
同样推荐使用命令行工具方式:
iwr https://install.surrealdb.com -useb | iexDocker
Docker 容器内包含完整的命令行工具——既可以导入导出数据,也可以直接启动服务器,无需在宿主机安装任何工具:
docker run --rm -p 8000:8000 surrealdb/surrealdb:latest start更新镜像到最新版本:
docker pull surrealdb/surrealdb:latest除 Docker 外,还可以使用 Docker Compose、Docker Swarm、Rancher 或 Kubernetes 等容器编排工具部署,仓库提供了可参考的 dev/docker/compose.yaml。
快速上手:客户端与服务端接入
官方文档给出的入门路径是:启动 SurrealDB 服务器 → 选择平台 → 将 SDK 集成进代码。文档列出的官方 SDK 支持情况如下:
- 客户端应用:JavaScript、WebAssembly、Ember.js(已支持);React.js、Angular.js、Vue.js、Apollo GraphQL(规划中)。
- 服务端代码:JavaScript、Node.js、Golang、Rust、Deno(已支持);Python、C、Java、Ruby、PHP、Swift、R(规划中)。
其中 Rust 版本的官方 SDK 正是surrealdbcrate 本身,在 surrealdb/README.md 中被称为 "The official SurrealDB SDK for Rust",接入只需:
cargo add surrealdbQuick Look:SurrealQL 核心实战
官方文档用一组精炼示例演示了 SurrealQL 的主要能力,这些示例同时也是仓库language-tests中大量.surql测试用例(如 language-tests/tests/language/statements 下的 549 个用例)所覆盖的行为。
强类型数据建模
凭借强类型数据类型,可以在数据库层面完整建模:
UPDATE person SET waist = <int> "34.59", height = <float> 201, score = <decimal> 0.3 + 0.3 + 0.3 + 0.1 ;Schemafull 表、字段约束与事件
既支持无结构数据(schemaless),也支持全结构数据(schemafull):
-- Create a schemafull table DEFINE TABLE user SCHEMAFULL; -- Specify fields on the user table DEFINE FIELD name ON TABLE user TYPE object; DEFINE FIELD name.first ON TABLE user TYPE string; DEFINE FIELD name.last ON TABLE user TYPE string; DEFINE FIELD email ON TABLE user TYPE string ASSERT string::is_email($value); -- Add a unique index on the email field preventing duplicate values DEFINE INDEX email ON TABLE user COLUMNS email UNIQUE; -- Create a new event whenever a user changes their email address DEFINE EVENT email ON TABLE user WHEN $before.email != $after.email THEN ( CREATE event SET user = $this, time = time::now(), value = $after.email, action = 'email_changed' );其中ASSERT string::is_email($value)这类字段级断言,在源码 surrealdb/core/src/doc 的字段校验逻辑中有完整实现;DEFINE EVENT与$before/$after语义则由 surrealdb/core/src/exec 中的事件执行器支撑。
图连接:RELATE 与有向边
用完全有向的图边连接记录:
-- Add a graph edge between user:tobie and article:surreal RELATE user:tobie->write->article:surreal SET time.written = time::now() ; -- Add a graph edge between specific users and developers LET $from = (SELECT users FROM company:surrealdb); LET $devs = (SELECT * FROM user WHERE tags CONTAINS 'developer'); RELATE $from->like->$devs UNIQUE SET time.connected = time::now() ;灵活查询:数组过滤与多级图遍历
-- Select a nested array, and filter based on an attribute SELECT emails[WHERE active = true] FROM person; -- Select all 1st, 2nd, and 3rd level people who this specific person record knows, or likes, as separate outputs SELECT ->knows->(? AS f1)->knows->(? AS f2)->(knows, likes AS e3 WHERE influencer = true)->(? AS f3) FROM person:tobie; -- Select all person records (and their recipients), who have sent more than 5 emails SELECT *, ->sent->email->to->person FROM person WHERE count(->sent->email) > 5; -- Select other products purchased by people who purchased this laptop SELECT <-purchased<-person->purchased->product FROM product:laptop; -- Select products purchased by people in the last 3 weeks who have purchased the same products that we purchased SELECT ->purchased->product<-purchased<-person->(purchased WHERE created_at > time::now() - 3w)->product FROM person:tobie;这些图遍历语法在仓库测试中有大量对照,例如 language-tests/tests/language/graph 目录下的 37 个用例。
地理空间数据
支持 GeoJSON 地理数据类型,包括点、线与多边形:
UPDATE city:london SET centre = (-0.118092, 51.509865), boundary = { type: "Polygon", coordinates: [[ [-0.38314819, 51.37692386], [0.1785278, 51.37692386], [0.1785278, 51.61460570], [-0.38314819, 51.61460570], [-0.38314819, 51.37692386] ]] } ;嵌入 JavaScript 函数
支持用 JS 函数编写自定义嵌入逻辑:
CREATE film SET ratings = [ { rating: 6, user: user:bt8e39uh1ouhfm8ko8s0 }, { rating: 8, user: user:bsilfhu88j04rgs0ga70 }, ], featured = function() { return this.ratings.filter(r => { return r.rating >= 7; }).map(r => { return { ...r, rating: r.rating * 10 }; }); } ;行级权限控制
为客户端与应用访问指定细粒度权限:
-- Specify access permissions for the 'post' table DEFINE TABLE post SCHEMALESS PERMISSIONS FOR select -- Published posts can be selected WHERE published = true -- A user can select all their own posts OR user = $auth.id FOR create, update -- A user can create or update their own posts WHERE user = $auth.id FOR delete -- A user can delete their own posts WHERE user = $auth.id -- Or an admin can delete any posts OR $auth.admin = true ;Rust SDK:嵌入式、远程与运行时引擎选择
CARGO.md面向 crates.io 的读者,而仓库内的 surrealdb/README.md 与 surrealdb/src/engine/any/mod.rs 则进一步揭示了 Rust SDK 的完整形态。
统一 API 与引擎抽象
从 surrealdb/src/engine/mod.rs 的源码结构看,引擎分为三大类:
- local(嵌入式):内嵌在应用进程中,包括内存存储(
kv-mem)、SurrealKV(kv-surrealkv)、RocksDB(kv-rocksdb)、IndxDB(kv-indxdb,浏览器/Wasm 场景)与 TiKV(kv-tikv,分布式); - remote(远程):连接外部服务器,包括 WebSocket(
protocol-ws)与 HTTP(protocol-http); - any(运行时选择):在运行时根据 endpoint 字符串动态选择任意已编译启用的引擎。
SDK 的Surreal<C>泛型客户端通过类型参数C: Connection在编译期锁定引擎,从而保证"所有引擎使用完全一致的 API,只是 endpoint 不同"。SDK 特性在 surrealdb/Cargo.toml 中定义:
default = ["protocol-ws", "rustls"]:默认走 WebSocket 且使用 rustls 做 TLS;- 存储引擎:
kv-mem、kv-indxdb、kv-rocksdb、kv-tikv、kv-surrealkv; - 协议与 TLS:
protocol-http、protocol-ws、native-tls、rustls; - 扩展能力:
scripting(JS 脚本)、http(HTTP 函数)、ml(机器学习,Wasm 下不支持)、jwks等。
嵌入式入门示例
SDK 也支持直接嵌入内存或磁盘数据库,无需启动服务器。以内存引擎为例(来自 surrealdb/src/engine/any/mod.rs 的模块文档):
use surrealdb::engine::any; use surrealdb::engine::any::Any; use surrealdb::opt::Resource; use surrealdb::Surreal; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { // 使用环境变量指定的 endpoint,开发时默认回退到内存引擎 let endpoint = std::env::var("SURREALDB_ENDPOINT").unwrap_or_else(|_| "memory".to_owned()); let db = any::connect(endpoint).await?; db.use_ns("namespace").use_db("database").await?; // 像操作远程数据库一样使用 Ok(()) }配合 Cargo.toml 最小配置:
surrealdb = { version = "1", # 关闭默认特性(protocol-ws 与 rustls),可缩短编译时间 default-features = false, # 无条件启用内存存储 features = ["kv-mem"], }生产环境若改用 RocksDB 持久化,只需换一种构建方式与环境变量,无需改代码:
cargo build --features surrealdb/kv-rocksdb --release export SURREALDB_ENDPOINT="rocksdb:/path/to/database/folder"这样既能避免在 Windows 开发机上编译 RocksDB(需要 C/C++ 依赖、编译耗时较长),又能让开发环境(内存引擎)与生产环境(RocksDB / WebSocket 远程引擎)完全解耦。
远程连接示例
README 中的完整示例 演示了 WebSocket 远程连接、根用户认证、命名空间/数据库选择、增删改查与参数化查询:
use serde::{Deserialize, Serialize}; use serde_json::json; use surrealdb::sql::Thing; use surrealdb::Surreal; use surrealdb::engine::remote::ws::Ws; use surrealdb::opt::auth::Root; use surrealdb::Error; #[derive(Serialize, Deserialize)] struct Person { #[serde(skip_serializing)] id: Option<Thing>, title: String, name: Name, marketing: bool, } #[tokio::main] async fn main() -> Result<(), Error> { let db = Surreal::new::<Ws>("localhost:8000").await?; // 以 root 用户登录 db.signin(Root { username: "root", password: "root" }).await?; // 选择命名空间与数据库 db.use_ns("namespace").use_db("database").await?; // 创建记录 let tobie: Option<Person> = db.create("person").content(Person { /* ... */ }).await?; // 按 ID 更新记录 let jaime = db.update(("person", "jaime")).merge(json!({ "marketing": true })).await?; // 查询全部记录 let people: Vec<Person> = db.select("person").await?; // 参数化自定义查询 let query = "SELECT marketing, count() FROM type::table($table) GROUP BY marketing"; let groups = db.query(query).bind(("table", "person")).await?; // 范围删除(删到 jaime 之前) let people: Vec<Person> = db.delete("person").range(.."jaime").await?; Ok(()) }客户端行为的源码级细节
从 surrealdb/src/lib.rs 的实现可以看到几个值得注意的设计:
- 版本协商:远程连接建立时会调用
check_server_version,要求服务器版本满足SUPPORTED_VERSIONS(常量">=3.0.0-alpha.1, <4.0.0"),不匹配则拒绝连接;单元测试test_supported_versions验证了 3.0.x 各阶段版本通过、2.x 与 4.x 被拒绝。 - 连接可克隆:
Surreal<C>实现了Clone,克隆时生成新的session_id并复用同一个内部Router,因此无需连接池即可在多处共享客户端;所有克隆共享同一底层连接,且具备自动重连能力。 - 连接容量控制:
Connect::with_capacity(n)可设置内部通道与 WebSocket 响应路由 HashMap 的上限,默认0表示无界通道,适用于高 QPS 场景防止客户端内存失控。 - 相同解析器:SDK 声明"无效的 SQL 查询绝不会发送到服务器,客户端与服务端使用同一套解析器",保证客户端侧即可拦截语法错误。
认证与能力配置
SDK 内置了完整的认证凭据类型,位于 surrealdb/src/opt/auth.rs:Root(root 用户)、Namespace(命名空间用户)、Database(数据库用户)、Record(记录级用户,通过 access method 登录)分别对应Signin/Signup两种动作。
对于嵌入式引擎,还可以通过 surrealdb/src/opt/capabilities.rs 中的Capabilities配置运行时能力边界:
Capabilities::all():允许所有函数与全部网络访问;Capabilities::none():禁用全部;Capabilities::new()(默认):启用 live query 通知与所有非脚本函数,但禁止网络目标(Targets::None);- 构建器方法(如
with_function_denied("http::*"))可精确限制函数与网络地址白名单/黑名单,例如禁止http::post或屏蔽 AWS metadata 端点169.254.169.254。
let capabilities = Capabilities::default().with_function_denied("http::*")?; let config = Config::default().capabilities(capabilities); let db = Surreal::new::<RocksDb>(("temp.db", config)).await?;进阶阅读指引
围绕本文涉及的主题,仓库内可继续深入的材料包括:
- 语言测试:language-tests/tests/language 下按主题组织的 1000+ 个
.surql用例,覆盖 statements、functions、graph、indexes、planner 等; - 回归用例:language-tests/tests/reproductions 记录了历史上各 issue 的复现与修复用例;
- 核心实现:surrealdb/core/src/sql(SurrealQL 语法与 AST)、surrealdb/core/src/exec(语句执行器)、surrealdb/core/src/idx(索引);
- 嵌入式用法:surrealdb/src/engine/local 与 surrealdb/src/engine/any 的模块文档,包含完整的嵌入式接入示例;
- SDK 测试:surrealdb/tests/api_integration 展示了 CRUD、live query、备份、版本协商等端到端行为。
结语
CARGO.md作为surrealdbcrate 在 crates.io 上的门面文档,浓缩了 SurrealDB 从产品定位、安装部署到 SurrealQL 核心语法的完整面貌。无论你打算把它作为嵌入式数据库直接嵌入 Rust 应用,还是启动独立服务器、用任意语言的官方 SDK 连接,本文覆盖的安装命令、SQL 示例与 Rust SDK 用法都可以直接落地。借助仓库中丰富的语言测试与源码实现,你还可以进一步验证每个语法行为的底层执行逻辑。
【免费下载链接】surrealdbA scalable, distributed, collaborative, document-graph database, for the realtime web项目地址: https://gitcode.com/GitHub_Trending/su/surrealdb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考