6.2 KiB
6.2 KiB
asset_object 表设计
日期:2026-04-21
1. 文档目的
这份文档用于把 asset_object 从“概念字段列表”推进到可以直接编码的级别。
当前要冻结的不只是字段名,还包括:
- 表职责边界
bucket + object_key的正式主存储口径- 首版字段类型
- 当前阶段必须先落下的索引
- 与
api-server / platform-oss / 后续业务绑定表的边界
2. 当前已确认前提
目前与 asset_object 直接相关的事实已经确认如下:
- 阿里云 OSS 当前按私有 bucket 模式接入。
- 浏览器上传通过
POST /api/assets/direct-upload-tickets下发的PostObject票据完成。 platform-oss已输出:bucketobjectKeylegacyPublicPathaccess
- 匿名公开 URL 当前返回
403,不能作为正式读取真相。
因此 asset_object 必须承担的真实职责是:
- 记录对象在 OSS 中的唯一定位
- 记录对象元数据
- 为后续业务绑定表提供稳定引用
- 不把 URL 当成正式主键
3. 表职责边界
3.1 asset_object 负责的内容
asset_object_id:对象主键bucket:对象所属 bucketobject_key:bucket 内对象路径access_policy:对象访问策略content_typecontent_lengthcontent_hashversion- 来源任务、归属用户、profile、业务实体等轻量关联键
asset_kindcreated_at / updated_at
3.2 asset_object 不负责的内容
- 不负责大对象二进制本体
- 不负责生成任务完整编排状态
- 不负责直接暴露公共 URL
- 不负责角色、动作、场景、精灵表等强业务关系本身
3.3 与其他表的边界
asset_job负责任务态,不替代对象真相。asset_manifest负责对象集合或发布清单,不替代单对象行。character_visual_asset / scene_image_asset / sprite_sheet_asset这类强业务关系表优先引用asset_object_id。
4. 表访问级别
asset_object 当前固定为 private table。
原因:
- bucket 当前是私有读写。
- 对象读取需要服务端签名 URL 或下载代理。
- 前端不应直接把
asset_object当公开订阅表使用。
补充口径:
- 当前阶段先不把
asset_object做成 public。 - 未来若要给客户端读对象列表,优先通过 view 或 Axum facade 输出脱敏 DTO。
5. 首版字段设计
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
asset_object_id |
String |
是 | 主键,固定使用 assetobj_ 前缀的稳定字符串 ID。 |
bucket |
String |
是 | 正式对象仓名称。 |
object_key |
String |
是 | bucket 内对象路径,不带前导 /。 |
access_policy |
AssetObjectAccessPolicy |
是 | 当前先冻结为 private / public_read。 |
content_type |
Option<String> |
否 | 真实对象 MIME。 |
content_length |
u64 |
是 | 已确认对象大小,单位字节。 |
content_hash |
Option<String> |
否 | 内容摘要,当前先保留为空间,不预设算法强制值。 |
version |
u32 |
是 | 对象版本号,首版默认 1。 |
source_job_id |
Option<String> |
否 | 来源任务 ID。 |
owner_user_id |
Option<String> |
否 | 归属用户 ID。 |
profile_id |
Option<String> |
否 | 归属 profile ID。 |
entity_id |
Option<String> |
否 | 归属业务实体 ID。 |
asset_kind |
String |
是 | 资产业务类型,例如 character_visual、scene_image。 |
created_at |
Timestamp |
是 | 创建时间。 |
updated_at |
Timestamp |
是 | 最近更新时间。 |
补充约束:
bucket与object_key是正式对象定位真相。- 允许存在
asset_object_id,但不允许回退成单列storage_path作为真相字段。 content_hash先允许为空,避免在上传确认链路未落地前把 schema 卡死。
6. 索引与查询约束
6.1 当前阶段必须先落的索引
bucket + object_key组合 B-Tree 索引 作用:按真实对象定位回查对象元数据asset_kind单列索引 作用:后续按业务类型聚合或清理对象
6.2 为什么先不加更多索引
当前阶段只先解决:
- 正式对象定位
- 业务类型过滤
而以下能力尚未落地:
asset_job- 上传完成确认 reducer
- 业务绑定 reducer
因此暂不提前为每个可空关联键堆索引,避免在真实访问模式还没固定前把 schema 复杂度拉高。
7. 写入约束
7.1 当前阶段允许的对象写入时机
后续真正写 asset_object 时,必须满足以下前提之一:
- 浏览器直传成功,服务端确认对象存在
- 后台 worker 成功上传对象到 OSS
- 旧对象迁移脚本确认对象存在并完成元数据回填
7.2 当前阶段不允许的漂移
- 只根据
legacyPublicPath就写入对象真相 - 只存完整 URL,不拆
bucket/object_key - 在
asset_object里重复塞角色、场景、动作等业务专属冗余字段 - 先落
bucket/object_key之外的单列字符串路径,再计划后续拆列
8. 与当前代码的对接关系
当前工程中的直接对接关系固定如下:
platform-oss- 负责生成
bucket + object_key对象定位
- 负责生成
api-server- 负责输出直传票据与私有读签名 URL
module-assets- 负责沉淀
AssetObjectAccessPolicy与字段校验 helper
- 负责沉淀
spacetime-module- 负责聚合
asset_object首版表骨架
- 负责聚合
9. 当前阶段完成定义
当以下条件满足时,asset_object 的首版设计与骨架视为完成:
bucket + object_key已在表结构中固定为两列- 表访问级别已固定为 private
- 字段和索引已具体到可直接编码
module-assets与spacetime-module已落真实 crate scaffold