菜谱类移动应用Firebase双集合数据库结构合理性咨询
方案可行性结论
你这套架构完全能支撑基础版本应用的开发需求,核心思路——把列表页高频用到的3个缩略图字段缓存到Firebase、点击进入详情页时再调用外部API拉取全量数据——是非常合理的性能取舍,既规避了外部API单次返回冗余数据的浪费,也能保证菜谱列表的加载速度,比每次渲染列表都调外部API的方案靠谱很多。
当前设计的待调整问题
- 不要把
recentlyViewed、favorited直接作为字段嵌套在用户主文档里。Firestore单条文档存在1MB的硬存储上限,你提到收藏夹没有条目数量限制,等用户收藏量积累到几千条时,会直接触发文档写入失败;另外你后续如果只需要拉取用户昵称这类基础信息,会把整个收藏夹、浏览历史的全量数据一起拉下来,平白消耗用户流量和读配额。
更合理的结构是在每个用户文档下建两个子集合:
每条子文档只需要存对应的时间戳(浏览时间/收藏时间)即可,既不会突破单文档大小限制,查询的时候也可以按需拉取,还能直接按时间戳排序,不用在客户端额外处理排序逻辑。/users/{userId}/recentlyViewed/{recipeId} /users/{userId}/favorites/{recipeId} - 给缩略图集合增加去重和过期更新逻辑。你现在设计的是用户每次浏览菜谱就写入一次缩略图数据,同一个菜谱被多个用户浏览会产生大量重复写入,浪费写配额。实际写入前先判断对应菜谱ID的文档是否存在,不存在再写入即可;如果担心外部API的菜谱信息(比如标题、封面)有更新,可以给缩略图文档加个
lastSyncedAt时间戳,超过7天再拉取最新的三个字段覆盖,不需要每次浏览都更新。 - 最近浏览的25条上限不要在客户端维护。你可以在用户触发浏览菜谱的逻辑时,给
recentlyViewed子集合按浏览时间倒序查询,跳过前24条,把更早的记录批量删掉,就能自动保证列表永远只保留最新的25条,逻辑比客户端维护Map可靠很多。
现有设计的可取之处
- 直接用外部API的菜谱唯一ID作为Firestore缩略图集合的文档ID是非常好的设计,省掉了自己维护ID映射表的额外成本,点击缩略图拉取详情时不需要做额外的ID转换,链路非常简洁。
- 缩略图字段只存列表渲染必须的标题、描述、封面三个字段,没有冗余数据,符合Firestore的文档设计最佳实践。
- 详情页按需拉取全量数据的逻辑,既保证了列表页的轻量快速,也不会出现详情页信息不全的问题,后续如果要加菜谱的营养成分、做法步骤这类信息,完全不用调整现有存储结构。
内容的提问来源于stack exchange,提问作者Green
相关产品推荐
相关产品推荐

