产品数据库设计:插件独立表 vs 主表新增字段
业务场景:网站总用户 10000 人,仅 100 人拥有勋章。
- 插件模式:勋章使用独立数据表,只记录已授予勋章的用户
- 集成模式:直接在用户表增加勋章字段,绝大多数用户该字段为空
方案对比
表格
维度 插件独立表 user_medal集成到 user 主表增加字段 存储占用 仅存储 100 条有效数据,无冗余 10000 行全部携带勋章字段,9900 行为空,大量稀疏空数据 主表性能 user 表结构轻薄,普通用户查询完全不受勋章业务影响 用户列表、登录等高频查询都会加载冗余字段;行体积变大,缓存、索引效率下降 业务扩展 新增勋章属性仅修改子表,不触碰核心用户表 新增勋章类型需要 DDL 修改大用户表,线上 ALTER 存在锁表风险 查询开销 仅查询勋章时才访问该表;不需要勋章则完全不访问 读取用户数据就会加载勋章字段,无关场景也要读取空值 插件化解耦 勋章模块可开关、卸载;卸载仅处理子表,不污染主用户数据 模块逻辑固化内核;移除勋章需要执行删字段 DDL,风险高 编码简单度 读取单用户勋章需要 JOIN 或者二次查询 单表直接读取勋章数据,编码简单 统计能力 可方便做索引,支持统计勋章发放人数、时间、来源 空值多索引效率差;很难保存发放时间、渠道等附加信息 场景结论
一万用户仅 100 人获得勋章:优先选择独立子表(插件模式),不要在 user 主表堆砌勋章字段。
- 99% 用户没有勋章,主表新增字段属于稀疏数据,浪费存储同时拖累最高频的用户表;
- 勋章业务天然附带扩展字段:获取时间、过期时间、发放来源,简单字段很难承载;
- 不建议使用 JSON 字段存储勋章列表:JSON 无法建立有效索引,无法快速筛选拥有某类勋章的用户。
什么时候适合直接加到 user 主表?
只有几乎全部用户都一定具备、不会为空的属性,才放入用户主表。例如:性别、注册时间。误区:插件多了,全部集成到内核是不是更好?
不建议。插件数量越多,越要避免把插件业务字段全部堆入主用户表。
全部集成的代价:
- user 表持续膨胀,高频核心表变得臃肿;
- 业务强耦合,关闭功能模块无法干净剥离数据库;
- 后期迭代 DDL 风险巨大,大表 ALTER 是线上高危操作。
设计原则
- 稀疏业务(仅少数用户存在数据):独立子表,插件自有数据表。 勋章、临时会员、任务记录等属于此类。
- 全局高频、每个用户必有数据:集成进 user 主表。
- 插件带来的成本主要是多表 JOIN 与代码分层;换取内核干净、模块可插拔、数据库性能可控。
最后由 bbs1org 编辑于 2026-09-04 14:22主楼大部分插件功能,都是如此。比如投票帖、抽奖帖、悬赏帖。都是小众情况。
所以,
插件机制整体来说,不会比内核集成差!有道理。
不错
又涨姿势了
涨姿势了。。
支持