
后端数据库【免费下载链接】instantInstant is the best backend for AI-coded apps. You get auth, permissions, storage, presence, and streams — everything you need to ship apps your users will love.项目地址https://gitcode.com/gh_mirrors/inst/instant点击查看免费下载Instant 是一套面向 AI 编码应用的实时后端提供认证、权限、存储、在线状态presence与数据流streams能力。本文以 Instant 官方 2025 年 2 月发布的 Instant News 更新通讯为主线逐项拆解该月发布的重点功能——Explorer 数据浏览器的查询与建链升级、onDelete: cascade级联删除、面向所有应用的$files文件存储命名空间、InstaQL 的fields字段裁剪子句以及 devtool、CLI 等周边工具的配置化改进并结合当前仓库中的官方文档与源码实现给出可直接落地的配置示例与调用代码。读完本文你将掌握这些新特性的完整用法与底层原理能够直接在你的 Instant 应用中上手实践。Explorer 数据浏览器迎来一轮功能升级2025 年 2 月更新中Instant 的 Explorer数据浏览器获得了一轮集中升级主要围绕三个痛点查找与过滤数据、在可视化界面中创建实体链接、以及浏览器状态的可分享性。字段级筛选字符串、比较操作符与精确匹配此前在 Explorer 中筛选数据的能力有限本次更新后你可以选择字段并对字符串进行查询直接选中某个属性字段输入字符串进行模糊匹配快速定位符合条件的行使用比较操作符对数值、日期等类型的字段应用$gt、$lt、$gte、$lte等比较运算符构造范围查询设置精确匹配例如针对 ID 这类唯一标识直接做等值匹配精确锁定某一条记录。这对应了 Explorer 前端中查询输入与行编辑的能力。在仓库中Explorer 组件位于 client/packages/components/src/components/explorer其中 search-input.tsx 承担查询输入交互edit-row-dialog.tsx 承担行级编辑弹窗。在底层查询层面比较操作符与精确匹配由 InstaQL 的where子句驱动完整的查询语法说明见 InstaQL 官方文档。在界面中为实体添加链接LinksExplorer 的第二个重要变化是为实体之间添加链接提供了可视化 UI。在此之前如果你要建立两个命名空间namespace之间的关联要么进入 Sandbox 沙箱环境操作要么编写一段事务脚本来完成门槛较高。现在可以直接在 Explorer 界面中操作例如把一条posts记录关联到某个profiles作者或者把一个$files文件挂到某个profiles之下。这一能力背后对应的是 Instant 的 Links 数据模型——它把posts.author与profiles.authoredPosts这类双向关联定义在 schema 中链接本身既可以由 Explorer 可视化创建也可以在代码中通过事务transact创建。数据建模与 Links 的完整说明见 Modeling data 文档。深链接Deep-linking可分享、可回溯的 Explorer 状态本次更新还为 Explorer 加入了深链接支持浏览器前进/后退按钮现在可以在不同的 Explorer 视图状态之间导航你可以直接把当前 Explorer 状态对应的 URL 发送给团队伙伴对方打开即可直达同一筛选、同一命名空间的视图。这让 Explorer 从一次性工具变成了可协作、可复现的调试入口尤其适合团队间分享问题复现场景。Cascade Delete一条事务完成级联删除当业务对象之间存在依赖关系时例如删除一篇post时其下所有comments也应一并删除级联删除就非常有用。2025 年 2 月更新中Instant 在 Explorer 中为这一能力提供了一键配置入口你不需要再写代码在 Explorer 的链接配置界面中即可开启。配置方式onDelete: cascade在 schema 中级联删除通过链接定义中的onDelete: cascade来声明。它只适用于has: one方向上的链接当一侧实体被删除时所有通过该链接关联的多侧实体也会被自动删除。以官方 Modeling data 文档 中的微博客示例为例postAuthor: { forward: { on: posts, has: one, label: author, onDelete: cascade }, reverse: { on: profiles, has: many, label: authoredPosts }, } // 这条事务会同时删除 profile 以及所有关联的 posts db.tx.profiles[user_id].delete();如果不加onDelete: cascade删除一个profile只会解除链接关系而不会删除底层的posts数据postAuthor: { forward: { on: posts, has: one, label: author }, reverse: { on: profiles, has: many, label: authoredPosts }, }链接方向也可以反过来建模只要在has: one那一侧声明级联即可postAuthor: { forward: { on: profiles, has: many, label: authoredPosts }, reverse: { on: posts, has: one, label: author, onDelete: cascade }, }性能设计级联在单次调用内完成官方更新通讯特别强调该功能在设计时考虑了性能所有 on-delete 级联删除在底层都通过一次调用完成而不是逐条递归发起删除请求。这意味着即使一个实体的关联子树规模较大删除操作也能以单次事务的语义原子地完成避免了多次网络往返和中间态暴露。从源码结构看这一设计在服务端事务执行层落地删除请求携带级联信息后由服务端一次性解析出全部受影响实体并统一删除。Storage 面向所有应用开放$files系统命名空间2025 年 2 月最重要的更新之一是存储能力对所有应用开放。每个应用现在都会在 Explorer 中看到一个全新的$files系统命名空间它与既有的$users命名空间一样属于 Instant 的特殊系统命名空间专门用于上传和托管应用资源图片、视频、文档等任意文件类型。一行代码上传文件客户端上传文件非常简单只需一行调用db.storage.uploadFile(hello-world, file);上传完成后通过查询$files命名空间即可拿到文件的下载 URL。$files与其他任何表的行为一致你可以把文件链接到其他命名空间、进行过滤、排序甚至为文件设置CASCADE DELETE——例如当某个profiles被删除时其关联的全部资产文件也会被自动清理。配额方面免费应用可存储最多 1GB付费应用可存储最多 10GB超出部分按 $0.125/GB 计费该数据来自官方通讯原文。Storage 快速上手完整可运行示例仓库中的 Storage 官方文档 提供了从零搭建图片上传应用的完整示例步骤如下。第 1 步创建项目并安装 SDKnpx create-next-app instant-storage --tailwind --yes cd instant-storage npm i instantdb/react第 2 步初始化 schema 与权限文件npx instant-clilatest init打开instant.schema.ts声明$files实体import { i } from instantdb/react; const _schema i.schema({ entities: { $files: i.entity({ path: i.string().unique().indexed(), url: i.string(), }), $users: i.entity({ email: i.string().unique().indexed(), }), }, links: {}, rooms: {}, }); // 便于 TypeScript 提供更友好的智能提示 type _AppSchema typeof _schema; interface AppSchema extends _AppSchema {} const schema: AppSchema _schema; export type { AppSchema }; export default schema;打开instant.perms.ts配置$files的权限示例放开全部权限便于上手生产环境不推荐import type { InstantRules } from instantdb/react; const rules { $files: { allow: { view: true, create: true, delete: true } } } satisfies InstantRules; export default rules;推送 schema 与权限到云端npx instant-clilatest push第 3 步编写上传与展示代码use client; import { init, InstaQLEntity } from instantdb/react; import schema, { AppSchema } from ../instant.schema; type InstantFile InstaQLEntityAppSchema, $files const APP_ID process.env.NEXT_PUBLIC_INSTANT_APP_ID; const db init({ appId: APP_ID, schema }); // uploadFile 是实际执行上传的 API // 上传完成后 $files 查询会自动更新 async function uploadImage(file: File) { try { // 可选的上传元数据 const opts { // 对应 HTTP Content-Type 头默认 application/octet-stream contentType: file.type, // 对应 HTTP Content-Disposition 头默认 inline contentDisposition: attachment, }; await db.storage.uploadFile(file.name, file, opts); } catch (error) { console.error(Error uploading image:, error); } } // $files 是查询存储数据的专用命名空间 function App() { const { isLoading, error, data } db.useQuery({ $files: { $: { order: { serverCreatedAt: asc }, }, }, }); // $files 查询结果包含元数据与可用于提供文件的下载 URL const { $files: images } data; // ... 渲染图片网格使用 image.url 作为 img 的 src } // 使用 db.transact 删除文件 const handleDelete async (image: InstantFile) { db.transact(db.tx.$files[image.id].delete()); }启动应用即可看到实时刷新的图片流npm run dev存储客户端 SDK 的完整 APIStorage 客户端 SDK 围绕db.storage提供了一套完整 API详见 Storage 官方文档。上传Uploaddb.storage.uploadFile(path, file, opts?)三个参数的作用path文件在存储中的存放路径可用于权限规则限制对特定路径的访问fileFile类型对象通常来自input typefileopts可选的元数据如contentType与contentDisposition。// 以文件名作为路径 await db.storage.uploadFile(file.name, file); // 自定义路径例如按用户 ID 分目录 const path ${user.id}/avatar.png; await db.storage.uploadFile(path, file); // 设置 content-type 与 content-disposition const path ${user.id}/orders/${orderId}.pdf; await db.storage.uploadFile(path, file, { contentType: application/pdf, contentDisposition: attachment; filename${orderId}-confirmation.pdf, });覆盖Overwrite如果path已存在再次上传会直接覆盖原文件若不想覆盖需要保证每个文件的路径唯一。查看View查询$files命名空间即可获取文件列表返回的对象包含id、path、可直接用于提供文件的url、content-type、content-disposition等字段。也可以像查询普通命名空间一样用过滤器与关联对文件进行过滤和排序const query { $files: { $: { order: { serverCreatedAt: asc }, }, }, }; const { isLoading, error, data } db.useQuery(query);删除Delete通过db.transact删除文件支持按 id、按 path使用lookup、批量删除// 按 id 删除 db.transact(db.tx.$files[fileId].delete()); // 按 path 删除 db.transact(db.tx.$files[lookup(path, photos/demo.png)].delete()); // 批量删除 db.transact(fileIds.map((id) db.tx.$files[id].delete()));更新Update可以用db.transact更新文件的path以及自定义列。由于path是唯一属性若目标 path 已存在事务会失败。目前仅允许更新$files的path属性和自定义列更新content-type等内置属性会导致事务失败。const { data } await db.query({ $files: { $: { where: { path: { $like: documents/my-video-project/% } } } }, }); await db.transact( data.$files.map((file) db.tx.$files[file.id].update({ path: file.path.replace( documents/my-video-project/, videos/my-video-project/, ), isFavorite: true, }), ), );链接Link上传成功后uploadFile返回包含文件 ID 的data对象可以用它把文件链接到其他命名空间async function uploadImage(file: File) { const path ${user.id}/avatar; const { data } await db.storage.uploadFile(path, file); await db.transact(db.tx.profiles[profileId].link({ avatar: data.id })); }存储上传的底层实现db.storage.uploadFile在客户端最终会向服务端发起一次PUT 请求到/storage/upload端点把文件二进制作为请求体并在请求头中携带app-id、path、authorizationBearer token、content-type与可选的content-disposition。对应的实现位于 StorageAPI.tsexport async function uploadFile({ apiURI, appId, path, file, refreshToken, contentType, contentDisposition }) { const headers { app-id: appId, app_id: appId, path, authorization: Bearer ${refreshToken}, content-type: contentType || file.type, }; if (contentDisposition) { headers[content-disposition] contentDisposition; } const data await jsonFetch(${apiURI}/storage/upload, { method: PUT, headers, body: file, }); return data; }删除文件则对应DELETE /storage/files?app_id...filename...端点见 StorageAPI.ts。从源码结构看旧版基于预签名 URL 的getSignedUploadUrl/getDownloadUrlAPI 已在代码中标记为Deprecated2025 年 1 月起弃用新应用应直接使用db.storage.uploadFile与$files命名空间。存储权限模型Storage 权限默认是禁用的在你显式设置权限之前任何上传和下载都不会被允许。权限与$files命名空间的操作一一对应create权限启用上传$filesview权限启用查看$filesupdate权限启用更新$filesdelete权限启用删除$files对$files的view权限加上对正向实体的update权限可以启用文件的链接/取消链接操作。权限规则中可以使用auth访问当前认证用户使用data访问文件元数据。目前唯一可用的文件元数据是data.path文件在存储中的路径。几个典型示例允许任何人上传与查看易上手不建议生产使用{ $files: { allow: { view: true, create: true } } }仅允许已登录用户查看与上传{ $files: { allow: { view: isLoggedIn, create: isLoggedIn }, bind: [isLoggedIn, auth.id ! null] } }已登录用户只能上传、查看、更新自己子目录下的文件{ $files: { allow: { view: isOwner, update: isOwner, create: isOwner }, bind: [isOwner, data.path.startsWith(auth.id /)] } }React Native 与 Admin SDK 下的存储使用React NativeuploadFile期望File或Blob。Expo SDK 56 及以上版本中expo/fetch是全局 fetch 且可直接读取本地文件可从expo-file-system传入File对象Expo SDK 55 及以下或裸 React Native则先用fetch读取本地文件再包装成File。详见 Storage 官方文档。Admin SDK服务端同样提供db.storage.uploadFile(path, file, opts?)此时file必须是 buffer 或 stream以 stream 上传时必须额外提供fileSize选项。Admin SDK 不强制校验权限因此可以在无认证环境下管理文件查询使用db.query()而非db.useQuery()。InstaQLfields子句按需裁剪查询字段默认情况下InstaQL 查询会返回对象的所有字段。2025 年 2 月更新新增了fields子句允许你只取需要的字段子集或桩数据stub官方文档见 InstaQL 文档的 Select fields 小节。基础用法const query { goals: { $: { fields: [status], }, }, }; const { isLoading, error, data } db.useQuery(query);返回结果中只会包含id与指定的status字段注意id始终会被返回即使未显式声明{ goals: [ { id: standupId, status: in-progress }, { id: standId, status: completed } ] }嵌套关联中使用fields同样适用于嵌套关联——每个层级的$块都可以独立指定fieldsconst query { goals: { $: { fields: [title], }, todos: { $: { fields: [id], }, }, }, }; const { isLoading, error, data } db.useQuery(query);返回的每个goal只带title与其下仅含id的todos列表。这在查询深层关联结构时尤其有用可以显著压缩查询载荷。性能收益官方文档明确指出使用fields有两个层面的性能收益减少传输数据量服务端只需要返回被选中的字段降低了网络带宽消耗减少 React 重渲染次数当查询结果中未选中的字段发生变化时不会触发组件重新渲染——只要所选字段没有变化前端就不会发生不必要的 re-render。因此在构建列表页、卡片墙这类只需要展示字段子集的场景时fields是一个低成本、高收益的查询优化手段。其余周边更新一览2025 年 2 月还有几项值得关注的周边改进React Native Web 改用 IndexedDBinstantdb/react-native现在在react-native-web环境中使用IndexedDB作为存储后端与 Web 端的 react 包行为保持一致。这意味着同一个应用在 Web 与 React Native Web 之间的数据缓存与同步行为将更加统一降低了跨端调试的心智负担。Rooms 使用静态 hooks 并返回稳定值Rooms在线状态/presence 相关被更新为使用静态 hooks并返回稳定值stable values。这消除了使用 presence 时产生的类型告警同时提升了性能——稳定的返回值意味着 React 组件不会因引用变化而频繁重渲染。Devtool 更可配置Instant 的开发工具条devtool现在支持更多配置项。在 coreTypes.ts 中DevtoolConfig定义了三个可配置项配置项含义默认值positiondevtool 面板在屏幕上的位置bottom-rightallowedHosts允许展示 devtool 的主机列表[localhost]dashURI用于渲染 devtool 的 Dashboard URIhttps://instantdb.composition支持bottom-left、bottom-right、top-right、top-left四种取值。官方通讯中提到Vercel 的开发工具默认放在左下角所以你可以把 Instant 的 devtool 移到右下角以避免重叠同时如果你在 localhost 之外的开发环境运行应用可以配置allowedHosts让 devtool 仍然正常展示。对应的渲染实现位于 devtool.tsinit的配置入口在 core/src/index.tsdevtool 通过 iframe 方式挂载元素类名包括instant-devtool-iframe、instant-devtool-toggler、instant-devtool-container。CLI 支持从自定义路径加载 schema 与 permsCLI 现在可以从自定义路径加载instant.schema.ts与instant.perms.ts。从源码 findConfigCandidates.ts 看实现机制如下支持通过环境变量INSTANT_SCHEMA_FILE_PATH与INSTANT_PERMS_FILE_PATH显式指定配置文件路径写入时同样会优先使用这两个环境变量见getSchemaPathToWrite/getPermsPathToWrite未设置环境变量时CLI 会按优先级自动查找项目根目录的instant.schema/instant.permssrc目录下最多 3 层深度的同名文件lib目录下最多 2 层深度的同名文件以及app/instant.schema/app/instant.perms每种配置都支持ts、mts、cts、js、mjs、cjs多种扩展名查找机制同样适用于 email 模板文件instant.email支持INSTANT_EMAIL_FILE_PATH环境变量。另外值得注意的是schema 文件中的框架包导入会被重写由于instantdb/react-native、instantdb/svelte、instantdb/vue等包无法在 Node.js CLI 上下文中加载它们会引入 react-native、.svelte、.vue文件CLI 会将这些导入重写为对应包的dist/cli入口该入口仅从instantdb/core重新导出 schema 所需的类型i、id、tx等从而保证 CLI 在任何框架项目中都能顺利解析 schema。技术文章零停机迁移 Postgres 16对于喜欢技术内容的读者官方同步发布了一篇关于零停机迁移到 Postgres 16的文章该文章与本文档同处仓库中pg_upgrade.md。文章探讨了 Instant 后端在保持服务可用性的同时完成 Postgres 大版本升级的方案对数据库运维与迁移设计感兴趣的读者可以继续深入。小结2025 年 2 月的这轮更新让 Instant 的日常开发体验上了一个台阶Explorer 从只读工具进化为可筛选、可建链、可分享的可视化开发台级联删除让数据清理变得声明式且高性能$files存储命名空间把文件上传、托管、查询、链接与权限统一进了既有的数据模型fields子句则为查询瘦身提供了官方原生的手段。如果你正在使用 Instant 构建应用可以对照本文的示例从 Explorer 的深链接分享、级联删除配置、$files图片上传与fields查询优化这四个切入点开始实践并结合 Storage 官方文档、Modeling data 文档 与 InstaQL 文档 进一步挖掘能力。赞分享后端数据库【免费下载链接】instantInstant is the best backend for AI-coded apps. You get auth, permissions, storage, presence, and streams — everything you need to ship apps your users will love.项目地址https://gitcode.com/gh_mirrors/inst/instant点击查看免费下载相关推荐MinIO对象存储系统2025年2月安全与性能优化版本解析MinIO对象存储系统2025年2月安全与性能优化版本解析 MinIO是一个高性能、云原生的分布式对象存储系统采用Apache License 2.0开源协议后端存储对象存储分布式存储云原生Fabric 2025 年 9 月 Go 与依赖升级实战Go 1.25.1 升级与 AI SDK 全面更新指南Fabric 2025 年 9 月 Go 与依赖升级实战Go 1.25.1 升级与 AI SDK 全面更新指南 本文档主体 docs/Go UpdatesAI 应用人工智能提示工程CLI本地部署上一篇CANN opbase 算子日志与校验宏全解析OP_LOGE 系列与错误码上报机制实战指南下一篇dotnet/skills 评测缺陷诊断目录实战用「症状 → 原因 → 修复」体系为技能评估排障创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考