ReboFiles文档
开始3
什么是 ReboFiles
快速开始
可运行的演示
集成到你的应用6
React 组件
Headless:你自己的界面
不使用框架
样式与主题
键盘与无障碍
语言
文件9
上传
预览与查看器
搜索
实时更改与大文件夹
评论
星标与字段
版本、回收站与空间
打包下载 .zip
Word 文档
服务器14
路由
框架与登录
谁可以做什么
存储:S3、GCS、Azure 与磁盘
检查上传
元数据:SQLite 与 Postgres
数据库结构
共享与链接
动态与通知
钩子、日志与限制
保留、法律保留与导出
桌面端与其他来源
同步文件夹
上线生产环境
协作1
AI 助手(MCP)
参考5
包
组件与 hooks
客户端 API
HTTP 路由
状态与路线图
↑↓ 移动↵ 打开Esc 关闭38 个页面

服务器 元数据:SQLite 与 Postgres

元数据:SQLite 与 Postgres

存储桶没有文件夹、所有者、权限或回收站的概念。这些信息存放在旁边的元数据存储中,它只写入改动的部分,每次一个改动。
选择

各种存储

存储适用于
memoryMetadata()测试和演示:进程结束后即消失。
sqliteMetadata(path)运行在单台服务器上的应用:一个文件,使用 Node 自带的 node:sqlite。
postgresMetadata(pool)多台服务器,或没有磁盘的托管环境:使用你自己的驱动,每次改动都会加数据库锁。
Postgres

使用 Postgres

import pg from 'pg';
import { postgresMetadata } from '@rebofiles/server';

metadata: await postgresMetadata(new pg.Pool({ connectionString: process.env.DATABASE_URL })),

它接受任何带有 query(text, values) 并返回 { rows } 的对象:pg、Neon 的 Pool、PGlite。传入连接池时,每次改动在读写期间都会持有数据库锁,因此两台服务器永远不会同时修改网盘;没有连接池时,同一时刻创建的两个文件夹可能都会被命名为 “(2)”。用 { table: 'acme_files' } 可以指定其他表名。

表

保存的内容

  • 条目:每个一行,以 JSON 形式保存。
  • 网盘和每个人的设置,以及经 scrypt 处理后的链接密码。
  • 动态记录:每条一行,可按条目及其所在文件夹查找。
  • 每个文件的文字:SQLite 的全文搜索,或 Postgres 中的 tsvector。
  • 一个随每次改动递增的修订号,让每个进程知道何时需要重新读取网盘。
自定义

你自己的存储

MetadataStore 只需实现 load() 和 save(changes);revision、lock、设置、record/activity 以及 keepText/findText 都是可选的,缺少时服务器会把这些信息保存在进程中。数据库结构一页列出了所有表。

规模

按需读取

SQLite、Postgres 和内存存储只回答每个请求所需的内容:一个条目及其上层文件夹、文件夹中的内容、某个文件夹下的全部内容、按名称搜索、回收站、与某人共享的内容。网盘从不整体加载,每次更改只写入涉及的部分。其他进程的更改从它们保存的动态中读取。

一百个人,每人两千个文件耗时
自己网盘的最顶层13 ms
包含 2,000 个文件的文件夹22 ms
按名称搜索35 ms
移动一个文件8 ms

查询所用的列和表会在首次打开旧数据库时添加,并一次性填充已有的行。自定义存储通过 scoped 实现同样的功能;没有它时,仍像以前一样整体保存在内存中。