资讯动态

SpacetimeDB 技术全解析:数据库即服务器、模块即后端,从快速上手到源码级原理

发布时间:2026/9/12 3:18:05 来源:尧图企业网站定制
SpacetimeDB 技术全解析数据库即服务器、模块即后端从快速上手到源码级原理【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDBSpacetimeDB 是一个关系型数据库 应用服务器二合一的实时后端系统开发者把表结构与业务逻辑直接编译进数据库客户端直连数据库执行逻辑并实时同步状态省去独立的 Web/游戏服务器、容器、Kubernetes 与 DevOps 链路。本文以本仓库根目录 README.md 为骨架结合仓库内的 CLI、模板与订阅引擎源码完整讲解其核心概念、快速上手流程、模块/表/Reducer/订阅编程模型、多语言支持、Docker 与源码构建方式并深入到底层实现证据读完即可上手用模块化方式构建实时多人应用。SpacetimeDB 是什么一个同时是服务器的数据库SpacetimeDB 的定位是a relational database that is also a server——既是一个关系型数据库又是一个服务器。它的用法与传统后端架构有本质区别传统模式客户端 → Web/游戏服务器 → 数据库开发者需要独立部署服务端进程、处理鉴权、做缓存与运维。SpacetimeDB 模式把模式schema与业务逻辑作为一个module模块直接上传进数据库。SpacetimeDB 编译模块、在数据库内部运行并把状态实时同步给已连接的客户端。客户端之间不再隔着一层自建服务器而是直连数据库执行模块中的业务逻辑。这意味着权限与授权逻辑可以像写普通服务器那样直接写在模块里整个应用可以用一种语言编写、以一个二进制部署——不再需要单独的 Web 服务器、容器、Kubernetes、虚拟机、缓存层基础设施管理量趋近于零见 README.md。性能与一致性方面README 明确给出了两条设计取向所有应用状态保存在内存中以获得快速访问磁盘上的commit log提交日志提供持久化与崩溃恢复能力同时提供传统关系型数据库的完整 ACID 保证以及优化过的 Web 服务器的吞吐与延迟表现。从仓库结构看这两点分别由独立 crate 承担内存/事务层集中在 crates/datastore 与 crates/table持久化与恢复则由 crates/commitlog、crates/durability、crates/snapshot 支撑。核心架构客户端订阅、模块代码与数据库下图是 README 中给出的 SpacetimeDB 应用架构图白色区域为 SpacetimeDB 提供的能力图中体现了两个关键交互路径查询与订阅SQL客户端以 SQL如SELECT * FROM Table;向数据库请求数据服务器执行后把结果推送到客户端的Subscribed Data订阅数据区域数据变更时SpacetimeDB 自动向订阅客户端推送增量更新。远程调用RPC/Reducer客户端代码调用call_my_reducer()之类的函数触发服务器端Module Code模块代码中的业务逻辑。从 crates/subscription/src/lib.rs 的注释可以看到订阅的底层定义A subscription is a view over a particular table——订阅本质上是特定表上的一个视图通过insert_plans / delete_plans两组查询片段做增量维护select 场景各 1 个片段join 场景各 4 个片段再结合 crates/core/src/client 中的客户端连接与消息处理逻辑实现数据一变、客户端立即收到的实时同步。这正是客户端侧useTable(tables.message)无需轮询即可自动更新的服务器端原理。快速开始安装、登录、一键开发README 给出了三步上手流程1. 安装 CLI# macOS / Linux curl -sSf https://install.spacetimedb.com | sh # Windows (PowerShell) iwr https://windows.spacetimedb.com -useb | iex安装脚本在仓库中也有对应实现crates/update/spacetime-install.shShell与 crates/update/spacetime-install.ps1PowerShell。安装得到的是spacetime命令由spacetimedb-update充当升级入口。2. 登录spacetime login该命令会打开浏览器通过 GitHub 完成身份认证将你的身份与账号绑定以便后续发布数据库。从 crates/cli/src/subcommands/login.rs 的源码看login还支持以下参数适合 CI 或无法打开浏览器的环境参数说明--auth-host URL从不同的认证主机获取登录令牌默认https://spacetimedb.com--token TOKEN跳过浏览器流程直接用登录令牌写入本地配置--no-browser不自动打开浏览器spacetime login show显示当前登录信息--token可同时显示令牌3. 开始开发spacetime dev --template chat-react-ts这条命令会做三件事从模板创建项目、发布到 SpacetimeDB 云端Maincloud、监听文件变化并在保存时自动重建与重新发布。关于 Maincloud 的部署细节见官方部署指南本仓库对应的 CLI 实现位于 crates/cli/src/subcommands/dev.rs。spacetime dev在源码中支持的常用参数如下节选自dev.rs的 clap 定义参数默认值说明database位置参数—要发布到的数据库名称/标识缺省时交互式询问-t, --template TEMPLATE—模板 ID如chat-react-ts或 GitHub 仓库owner/repo或 URL--project-path PATH.项目目录路径--module-path PATHproject/spacetimedb服务器模块代码所在目录--module-bindings-path PATHproject/src/module_bindings生成的客户端模块绑定输出目录--client-lang LANG自动探测生成客户端绑定的语言typescript、csharp、rust、unrealcpp 等--run COMMAND读取 spacetime.json启动客户端开发服务器的命令覆盖配置--server-onlyfalse只运行服务器模块不启动客户端--no-configfalse忽略 spacetime.json 配置--clear-databasefalse发布前清空目标数据库--native-aotfalseC# 项目使用 NativeAOT-LLVM 构建其工作流auto-generate client bindings → auto-rebuild → auto-publish在源码中使用notify::RecommendedWatcher做文件系统监听每次变更触发重新发布spacetime dev要求服务器模板代码统一放在spacetimedb/目录见 dev.rs 中的注释说明。How It Works表、Reducer 与订阅SpacetimeDB 模块定义两种核心元素tables表——你的数据reducers归约器——你的逻辑等价于你的 API 端点。客户端连接后调用 reducer → 订阅表 → 数据变化时 SpacetimeDB 自动把更新推给已订阅的客户端。服务端Rust 模块示例README 原例// Define a table #[spacetimedb::table(accessor messages, public)] pub struct Message { #[primary_key] #[auto_inc] id: u64, sender: Identity, text: String, } // Define a reducer (your API endpoint) #[spacetimedb::reducer] pub fn send_message(ctx: ReducerContext, text: String) { ctx.db.messages().insert(Message { id: 0, sender: ctx.sender, text, }); }要点说明#[spacetimedb::table(accessor messages, public)]声明一张表public表示表对客户端公开accessor生成表访问器可通过ctx.db.messages()访问。#[primary_key]#[auto_inc]声明自增主键插入时id填0即可由数据库自动分配。#[spacetimedb::reducer]把函数变成可被客户端远程调用的 API 端点ReducerContext提供ctx.sender调用者身份、ctx.db数据库句柄等上下文。相关的宏实现位于 crates/bindings-macro 与 crates/bindings实际执行与调度逻辑位于 crates/core/src/host同时支撑 Rust/WASM 与 TypeScript/V8 两种宿主。客户端订阅并实时更新README 原例const [messages] useTable(tables.message); // messages updates automatically when the server state changes. // No polling. No refetching.服务端任意 reducer 修改表数据后订阅视图会被增量维护见前文crates/subscription的 insert/delete 片段机制变更通过客户端连接推送过来UI 层的useTable随即自动刷新——无需轮询、无需手动 refetch。TypeScript SDK 的完整实现位于 sdks/typescript/src。仓库模板中的完整模块TypeScript 版聊天应用本仓库的chat-react-ts模板templates/chat-react-ts包含一个可直接运行的 TS 服务器模块 templates/chat-react-ts/spacetimedb/src/index.ts展示了比 README 示例更完整的生命周期用法import { schema, t, table, SenderError } from spacetimedb/server; const user table( { name: user, public: true }, { identity: t.identity().primaryKey(), name: t.string().optional(), online: t.bool(), } ); const message table( { name: message, public: true }, { sender: t.identity(), sent: t.timestamp(), text: t.string() } ); const spacetimedb schema({ user, message }); export default spacetimedb; export const set_name spacetimedb.reducer( { name: t.string() }, (ctx, { name }) { if (!name) throw new SenderError(Names must not be empty); const user ctx.db.user.identity.find(ctx.sender); if (!user) throw new SenderError(Cannot set name for unknown user); ctx.db.user.identity.update({ ...user, name }); } ); export const send_message spacetimedb.reducer( { text: t.string() }, (ctx, { text }) { if (!text) throw new SenderError(Messages must not be empty); ctx.db.message.insert({ sender: ctx.sender, text, sent: ctx.timestamp }); } ); // 模块发布时的初始化钩子 export const init spacetimedb.init(_ctx {}); // 客户端连接/断开钩子维护 online 状态 export const onConnect spacetimedb.clientConnected(ctx { /* ... */ }); export const onDisconnect spacetimedb.clientDisconnected(ctx { /* ... */ });这段代码演示了几个值得注意的实战点t.identity().primaryKey()、t.string().optional()、t.timestamp()等类型构建器定义列类型spacetimedb.reducer({...}, (ctx, args) ...)声明 reducerSenderError用于向调用方返回业务错误spacetimedb.init/clientConnected/clientDisconnected是模块生命周期钩子可用于初始化数据、记录在线状态等服务器模板统一放在项目的spacetimedb/子目录这是spacetime dev对模板的约定。仓库 templates 目录下还提供了大量可spacetime dev --template ID一键使用的工程模板覆盖主流前端框架与语言basic-rs、basic-ts、basic-cs、basic-cpp、chat-console-rs、chat-console-cs、chat-react-ts、hangman-react-ts、browser-ts、bun-ts、deno-ts、nodejs-ts、nextjs-ts、nuxt-ts、remix-ts、svelte-ts、solid-ts、tanstack-ts、vue-ts、astro-ts、angular-ts等。语言支持矩阵服务器模块写数据库逻辑语言说明Rust官方主推宏驱动开发#[spacetimedb::table]/#[spacetimedb::reducer]C#经spacetime generate生成绑定可配合 NativeAOTTypeScript基于 V8 宿主直接运行见spacetimedb/server包C服务器模块同样受支持仓库内对应的模块示例与测试模块集中在 modulesRust 服务器模块如module-test、sdk-test-*、modules/module-test-cs、modules/module-test-ts、modules/module-test-cpp宏与绑定代码在 crates/bindings-macro、crates/bindingsC 绑定在 crates/bindings-cpp、C# 运行时在 crates/bindings-csharp。客户端 SDK平台覆盖范围TypeScriptReact、Next.js、Vue、Svelte、Angular、Node.js、Bun、DenoRust原生客户端C#独立应用与 UnityCUnreal EngineSDK 源码位于 sdks/typescript、sdks/rust、sdks/csharp、sdks/unreal仓库内也维护了 Blackholio 等完整的多人游戏演示demo/Blackholio包含 Godot、Unity、Unreal 客户端与 Rust/C#/TS/C 多种服务器实现。用 Docker 运行docker run --rm --pull always -p 3000:3000 clockworklabs/spacetime start该镜像基于 Dockerfile 构建入口为spacetime start命令启动本地 standalone 服务器实现见 crates/cli/src/subcommands/start.rs 与 crates/standalone。--pull always保证每次拉取最新镜像-p 3000:3000把数据库监听端口映射到宿主机。从源码构建如果需要master分支上尚未发布的特性可以本地构建。构建产物是三个二进制# 前置条件Rust 工具链 wasm32-unknown-unknown 目标 curl https://sh.rustup.rs -sSf | sh git clone https://github.com/clockworklabs/SpacetimeDB cd SpacetimeDB cargo build --locked --release -p spacetimedb-standalone -p spacetimedb-update -p spacetimedb-cli三个包对应三个二进制spacetimedb-standalone独立服务器crates/standalone、spacetimedb-update升级/安装入口crates/update、spacetimedb-cli命令行工具crates/cli。--locked使用仓库锁定版本见根目录 Cargo.lock--release生成优化构建。安装二进制macOS / Linuxmkdir -p ~/.local/bin STDB_VERSION$(./target/release/spacetimedb-cli --version | sed -n s/.*spacetimedb tool version \([0-9.]*\);.*/\1/p) mkdir -p ~/.local/share/spacetime/bin/$STDB_VERSION cp target/release/spacetimedb-update ~/.local/bin/spacetime cp target/release/spacetimedb-cli ~/.local/share/spacetime/bin/$STDB_VERSION cp target/release/spacetimedb-standalone ~/.local/share/spacetime/bin/$STDB_VERSION # 添加到 shell 配置如未配置 export PATH$HOME/.local/bin:$PATH # 设置当前生效版本 spacetime version use $STDB_VERSION安装二进制Windows PowerShell$stdbDir $HOME\AppData\Local\SpacetimeDB $stdbVersion .\target\release\spacetimedb-cli --version | Select-String -Pattern spacetimedb tool version ([0-9.]); | ForEach-Object { $_.Matches.Groups[1].Value } New-Item -ItemType Directory -Path $stdbDir\bin\$stdbVersion -Force | Out-Null Copy-Item target\release\spacetimedb-update.exe $stdbDir\spacetime.exe Copy-Item target\release\spacetimedb-cli.exe $stdbDir\bin\$stdbVersion\ Copy-Item target\release\spacetimedb-standalone.exe $stdbDir\bin\$stdbVersion\ # 将 %USERPROFILE%\AppData\Local\SpacetimeDB 加入系统 PATH # 然后在新的 shell 中 spacetime version use $stdbVersion构建完成后用spacetime --version验证。深入源码项目结构与关键实现workspace 布局根目录 Cargo.toml 组织了一个大型 Rust workspace核心分区如下crates/数据库内核与 CLI。除前文提到的cli、standalone、subscription、commitlog外还包括core宿主与客户端消息处理、datastore内存数据存储、table表与索引、sql-parser/expr/query/physical-planSQL 到执行计划的流水线、schema/sats类型系统与 BSATN 序列化、auth身份认证等。modules/以 Rust 编写的服务器测试/示例模块module-test、sdk-test-*、benchmarks等。templates/spacetime dev使用的项目脚手架模板。sdks/官方客户端 SDKTypeScript / Rust / C# / Unreal。docs/Docusaurus 技术文档站源码docs/README.md另有 docs/docs 存放文档正文。skills/面向 AI 助手/Agent 的技能文档cli、concepts、rust-server、typescript-server、csharp-server、cpp-server、unity、unreal、mcp等见 skills 目录。spacetime.json项目的持久化配置spacetime dev、spacetime publish、spacetime generate等命令都会读取项目根目录的spacetime.json文件名常量定义于 crates/cli/src/spacetime_config.rs。该文件的字段采用 kebab-case示例如下{ database: my-database, server: local, module-path: ./server, dev: { run: pnpm dev }, generate: [ { language: typescript, out-dir: ./src/module_bindings } ] }dev.runspacetime dev启动客户端开发服务器时执行的命令如npm run dev、pnpm dev、cargo run源码中对应DevConfiggenerate声明为每个数据库生成客户端模块绑定的语言与输出目录多数据库场景下可用children配置多区域/多数据库{ server: local, module-path: ./server, children: [ { database: region-1 }, { database: region-2, module-path: ./region-server } ] }配置中database、module-path、server等字段都可通过--xxx命令行参数覆盖若在配置文件中写了不支持的键CLI 会给出明确的错误提示见CommandConfigError::UnsupportedConfigKey。JavaScript/TypeScript 项目的包管理器npm / pnpm / yarn / bun也会被自动探测以决定run_dev_command使用的命令。订阅引擎增量视图维护客户端订阅并非简单的全量拉取。在 crates/subscription/src/lib.rs 中订阅被实现为基于执行计划片段的增量视图每个订阅会编译出一组 insert 片段与 delete 片段Fragments查询经spacetimedb_query::compile_subscription编译后由for_each_insert/for_each_delete遍历执行计划把发生变更的行增量推送给客户端。单表 select 只需 1 组片段join 则需 4 组片段对应连接两侧的插入/删除组合并在片段级记录依赖的索引 IDindex_ids()从而保证任意 reducer 提交事务后所有受影响订阅都能被精确、增量地更新。该设计是客户端无轮询实时同步的性能基石。持久化commit log 与快照README 提到的磁盘 commit log 提供持久化与崩溃恢复由 crates/commitlog 承担其 README 标注为内部 crate接口不稳定、可能随时变更配合 crates/durability 与 crates/snapshot 的测试与快照机制构成内存热数据 磁盘持久化的存储架构。文档与许可证仓库内完整的技术文档位于 docsDocusaurus 站点含核心概念、教程、部署指南、CLI 与 SQL 参考等另有历史版本docs/versioned_docs面向 Agent 的快速技能文档见 skills 目录。许可证方面SpacetimeDB 采用Business Source License 1.1BSL 1.1见 LICENSE.txt几年后转换为带链接例外的 AGPL v3.0README 的为什么这样选一节亦表述为带链接例外的 GPLv3。链接例外的意义在于使用 SpacetimeDB 不必开源你自己的代码只需把对 SpacetimeDB 本身的修改回馈给主线即可。README 给出的选择理由是团队无法在把产品构建给 AWS 的同时与之竞争因此选择 MariaDB BSL 4 年过渡期而选择带链接例外的 GPLv3 作为开源许可是为了像 Linux 那样吸引贡献合并回主线同时不强制任何人开源自己的代码。仓库中另有 licenses/BSL.txt 与 licenses/apache2.txt 可查阅。【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价