5.8 KiB
5.8 KiB
SpacetimeDB 资产对象存储设计
日期:2026-04-21
1. 文档目的
这份文档用于冻结当前 assets / OSS 前置落地后的两个关键口径:
- 阿里云 OSS 当前按私有 bucket 模式接入。
- 后续
SpacetimeDB的资产对象引用统一按bucket与object_key两列存储,而不是拼成单个路径字符串。
这份文档直接服务于以下工程收口动作:
platform-oss的输出 contract 收敛。api-server的直传票据接口收敛。- 后续
asset_object、asset_manifest、业务绑定表的字段设计收敛。
2. 当前已确认事实
2.1 Bucket 访问策略
当前阿里云 OSS bucket:
bucket:xushi-devendpoint:oss-cn-beijing.aliyuncs.com
已确认:
- bucket 当前为私有读写。
- 服务端可通过
AccessKeyId / AccessKeySecret正常访问 bucket。 - 浏览器可通过服务端签发的
PostObject票据完成上传。 - 未签名的对象公开 URL 返回
403,不能当成正式读取链路。
2.2 当前工程能力状态
当前 server-rs 已落地:
platform-oss:浏览器PostObject直传签名api-server:POST /api/assets/direct-upload-ticketsplatform-oss:私有对象短期签名读取 URLapi-server:GET /api/assets/read-urlserver-rs/scripts/oss-smoke.ps1:真实 OSS 联调脚本platform-oss:私有HEAD Object探测api-server:POST /api/assets/objects/confirmmodule-assets:进程内asset_object确认服务platform-oss:服务端PutObject上传 helperapi-server:POST /api/assets/sts-upload-credentials禁用式 contract
当前仍未落地:
STS真实临时授权下发- multipart 分片上传
- 内容 hash 自动计算与版本字段细化
当前上传完成确认接口的详细请求、校验顺序与写入规则见:
服务端上传与 STS 禁用式 contract 的详细设计见:
3. 正式存储口径
3.1 SpacetimeDB 中的对象引用格式
后续 SpacetimeDB 中凡是需要引用 OSS 对象的地方,统一按以下两列存储:
bucketobject_key
不采用以下做法作为正式真相:
- 不存完整公开 URL
- 不存
bucket/object_key拼接后的单字符串 - 不存依赖 bucket 权限假设的匿名可读 URL
3.2 为什么必须拆成两列
原因固定如下:
- bucket 后续可能按环境、业务线或冷热分层拆桶。
object_key本身才是对象路径主键;bucket是对象所属仓。- 后续签名下载 URL、服务端代理读取、对象迁移都需要分别拿到
bucket与object_key。 - 若只存拼接字符串,后续查询、迁移、批量回填和索引都更差。
4. 推荐表字段
4.1 asset_object
后续 asset_object 至少应包含:
idbucketobject_keyaccess_policycontent_typecontent_lengthcontent_hashversionsource_job_idowner_user_idprofile_identity_idasset_kindcreated_atupdated_at
当前已落到可编码级别的字段类型、索引和访问级别见:
4.2 业务资产表
如:
character_visual_assetcharacter_animation_assetscene_image_assetsprite_sheet_asset
这些表不直接重复存 URL,而是引用:
asset_object_id- 或明确的
bucket + object_key
优先建议:
- 强业务关系表引用
asset_object_id asset_object再统一承载bucket + object_key
5. API 输出口径
5.1 直传票据接口
POST /api/assets/direct-upload-tickets 的正式输出应以以下字段为核心:
bucketobjectKeylegacyPublicPathaccessformFieldsexpiresAt
补充说明:
publicUrl在私有 bucket 模式下不是正式读取真相。- 若当前为了调试保留
publicUrl,也只能视为“候选直连 URL”,不能代表对象一定可匿名读取。
5.2 私有读取链路
后续正式读取私有对象时,应采用以下方案之一:
api-server输出短期签名 URLapi-server做下载代理- CDN 私有回源 + 服务端签名
当前仓库已实现第一种最小闭环:
- 服务端落库保存
bucket + object_key - Web 端请求
GET /api/assets/read-url api-server返回短期signedUrl- 浏览器再使用该
signedUrl执行展示或下载
当前阶段不允许:
- 把长期
AccessKeyId / AccessKeySecret下发给客户端 - 让浏览器直接持有长期主凭证读取私有对象
6. platform-oss 的实现约束
从当前版本开始,platform-oss 需要遵守以下约束:
- 默认按私有对象思维设计,不假设对象可匿名读取。
PostObject直传输出必须显式带bucket与object_key。publicUrl若存在,只能作为派生信息,不能替代bucket/object_key。- 后续新增签名下载能力时,输入必须是
bucket + object_key。
7. SpacetimeDB 表设计约束
结合 SpacetimeDB 的 schema 演进约束,当前先冻结:
- 资产对象表必须尽早固定
bucket与object_key两列。 - 不要先落单列字符串,后续再拆列,这会放大 schema 迁移成本。
- 对象 URL、签名 URL、CDN URL 都属于派生读模型,不是主存储字段。
8. 一句话结论
当前 assets / OSS 的正式真相应当是:
阿里云 OSS 用私有 bucket 持有二进制对象,SpacetimeDB 用 bucket + object_key 两列持有对象引用,任何 URL 都只能是运行时派生结果。