PG 模式云存储
阅读前建议先了解 PG 模式概述,明确该模式与传统模式的整体差异。
PG 模式下,云存储与数据库共用同一套权限模型——文件的元数据由 PostgreSQL 的 storage schema 管理,访问权限完全由 RLS Policy 描述。无需再使用 READONLY / PRIVATE 等内置权限标签,也不必再编写云存储专用的 JSON 安全规则——与业务表完全相同的 SQL Policy 同时控制了文件读写。
本目录聚焦通用文件 Bucket 的存储、访问与权限管理,适用于图片、视频、文档、压缩包、用户上传内容、静态资源等 File Bucket 场景。
其他云存储类型
CloudBase 还提供 传统模式云存储,可根据环境形态选择合适的云存储类型。
与传统模式的核心差异
PG 模式与传统模式在三件事上有本质区别:
1. Bucket 是一等公民,可按 Bucket 维度做 SQL 级权限控制
- 传统模式:环境与底层 COS 桶强绑定,开发者面向的是"路径前缀"而非真正意义上的多 Bucket;权限选项也只能在创建桶时挑一种内置模式
- PG 模式:
storage.buckets是 PostgreSQL 中的一张表,每个 Bucket 就是其中一行,可以按 Bucket 维度:- 配置
public/file_size_limit/allowed_mime_types等元数据 - 在 RLS Policy 中用
bucket_id = 'xxx'直接做条件匹配 - 通过 SQL 直接增删改查桶元数据,无需控制台或专用 API
- 配置
2. Object 权限完全基于 RLS,告别 JSON 安全规则
- 传统模式:用内置权限标签(
READONLY/PRIVATE/ADMINWRITE/ADMINONLY/CUSTOM)或独立的 JSON 安全规则描述权限,粒度限于桶 / 路径前缀 / 简单角色 - PG 模式:所有读写权限由
storage.objects/storage.buckets上的 RLS Policy 表达。storage.objects默认GRANT ALL TO anon, authenticated, service_role——RLS 是唯一闸门。可使用任意 SQL 表达式,跨 schema JOIN 业务表,与数据库权限同语言同语义
3. 不走客户端直传 COS,统一经由 Storage API
为保证元数据、对象、RLS 校验三者的强一致性,PG 模式所有读写经由 Storage API 统一入口,由它在事务中协调 storage.objects 元数据写入与 COS 对象操作,杜绝"COS 有文件但 storage.objects 无记录"或反之的孤儿状态。
| 维度 | 传统模式 | PG 模式 |
|---|---|---|
| 客户端上传链路 | SDK 拿临时签名后直传 COS,后端不参与字节流转 | SDK → Storage API → COS,由统一入口协调 |
| 元数据写入时机 | COS 回调 / 业务补齐 | Storage API 在事务中自动写入 storage.objects |
owner_id 注入 | 业务侧维护 | Storage API 写入时自动用 JWT sub 注入,前端无法伪造 |
| RLS 校验 | 不适用 | INSERT 的 WITH CHECK 在数据库侧拦截,越权请求落不到 COS |
| 删除一致性 | 业务侧自检 | protect_delete 触发器强制经由 Storage API,先删对象再删行 |
| 大文件分片 | COS 分片直传 | 通过 storage.s3_multipart_uploads 中转表协调的分片上传 |
| 文件元信息读取(size / mimetype 等) | 需额外调用 COS API | 直接 SELECT metadata FROM storage.objects,与业务表 JOIN |
SDK 使用建议
PG 模式下推荐使用原生 Bucket 语义的 SDK / API,例如 JS SDK 的 app.storage.from(bucketId)、CLI 的 tcb storage objects 命令组,或 PG 模式云存储 HTTP API。完整示例见 SDK 使用。
差异速览
| 维度 | 传统模式云存储 | PG 模式云存储 |
|---|---|---|
| Bucket 概念 | 与环境强绑定,主要做路径前缀 | storage.buckets 表的一行,支持 SQL 级控制 |
| 权限描述 | 内置权限模式或 JSON 安全规则 | RLS Policy(SQL) |
| 权限粒度 | 桶级 / 路径前缀 / 简单角色 | 任意 SQL 表达式,可跨表 JOIN |
| 元数据访问 | 控制台 / SDK | 直接 SQL 查询 storage.objects |
| 与业务数据联动 | 业务自行同步 | 同实例同 schema,可直接 JOIN |
| 上传链路 | 客户端直传 COS | 客户端 → Storage API → COS |
| 选择方式 | 创建 Bucket 时挑选权限模式 | 由环境类型自动决定,无需选择 |
PG 环境下,云存储的权限校验路径自动走 RLS,由环境类型决定,开发者无需做任何切换。
整体架构
客户端(Web / 小程序 / 云函数)
│ Authorization: Bearer <Token>
▼
CloudBase 网关
│ 解析 JWT → 设置 role + request.jwt.claims
▼
Storage API
│ 写入 / 读取 storage schema 元数据
▼
PostgreSQL · storage schema ←┐
├─ storage.buckets │ RLS 策略校验
├─ storage.objects │
└─ storage.s3_multipart_uploads ←┘
│
▼
对象存储后端(COS) ← 文件实体
关键事实:
- 文件实体存在对象存储后端,元数据存在
storageschema storage.buckets/storage.objects已默认GRANT ALL TO anon, authenticated, service_role——权限的唯一闸门是 RLS Policy(这是与业务表"双层 GRANT + RLS"模型的差别)- 不允许直接
DELETE FROM storage.objects:表上有protect_delete触发器,删除必须通过 Storage API 走,避免对象存储残留孤儿对象
阅读路径
| 你的目标 | 阅读建议 |
|---|---|
| 第一次接触,想跑通 Hello World | 快速体验 |
| 设计 Bucket、公开 / 私有访问模型和上传限制 | Bucket 管理 |
| 上传文件、处理覆盖和自定义元数据 | 上传文件 |
| 下载文件、生成签名链接或公开 URL | 访问与下载文件 |
| 列出、复制、移动、删除文件 | 管理文件 |
| 理解 schema 字段与权限模型 | 权限管理 |
| 照着模板写 RLS 策略 | RLS 策略模式库 |
| 查看命名、大小、MIME 和覆盖建议 | 限制与最佳实践 |
| 理解 CDN 缓存、Public / Private 缓存差异 | CDN 加速与缓存 |
| 从 Supabase Storage 迁移 | 从 Supabase Storage 迁移 |
| 服务端 / 跨语言调用 HTTP API | PG 模式云存储 HTTP API |
| 遇到 403 / 越权 / 直接 DELETE 报错 | 常见问题 |
| 内容审核 / 数据万象 / 图片处理 | 与传统模式共用,参见 传统模式云存储 |
HTTP API
PG 模式云存储提供完整的 RESTful HTTP API,可在任意后端语言中调用:
完整接口列表见 PG 模式云存储 HTTP API。
下一步
- 快速体验 — 5 分钟跑通"上传 + RLS + 越权拒绝"
- Bucket 管理 — Bucket 字段、Public / Private 访问模型、上传限制
- 上传文件 —
contentType、metadata、upsert、路径设计 - 访问与下载文件 —
download()、签名链接、公开 URL - 管理文件 — 列表、信息、复制、移动、删除
- 权限管理 —
storageschema、辅助函数、RLS-only 权限模型 - RLS 策略模式库 — PUBLIC / READONLY / PRIVATE / ADMINWRITE / ADMINONLY 等可复制模板
- 限制与最佳实践 — 命名、大小、MIME、覆盖文件、AI 友好契约
- CDN 加速与缓存 — CDN 访问链路、Public / Private 缓存差异、
cacheControl - 从 Supabase Storage 迁移 — 迁移清单、差异点和回归测试
- PG 模式云存储 HTTP API — 服务端 / 跨语言调用接口
- PG:身份认证 —
auth.uid()与三角色机制