数据库设计中类型存储用独立type表还是直接在表中加type列?
三个方案优劣对比
方案1:独立type表,用type_id外键关联
- 优势:
- 符合数据库范式设计,数据冗余度极低,后续如果要给type扩展属性(比如展示名、排序规则、启用状态等),只需要修改type表即可,不用动category表结构
- 数字id作为主键占用存储空间更小,category表的查询、索引性能都更高
- 要修改type的名称时,仅需修改type表的单条记录,不会出现数据不一致问题
- 劣势:
- 查询category对应的type名称时必须关联type表做join,多表查询比单表稍复杂,性能有可忽略的微小损耗

- 查询category对应的type名称时必须关联type表做join,多表查询比单表稍复杂,性能有可忽略的微小损耗
方案2:独立type表,用type_name字符串作为关联键
- 优势:
- 查询category时不需要join就能直接拿到type名称,单表查询更简单,性能更高
- 保留了独立type表,type的其他属性依然可以扩展,规范性比方案3好
- 劣势:
- 字符串作为外键的存储空间远大于数字id,category表数据量大的话,存储空间开销、索引性能都会比方案1差很多
- 修改type名称时需要批量更新category表的所有对应记录,操作成本高,很容易出现数据不一致
- 不符合常规范式设计,多数ORM框架对字符串外键的支持也不如数字主键友好

方案3:category表直接存type字段,不单独建type表
- 优势:
- 实现逻辑最简单,单表查询不需要任何关联,开发成本最低
- 单表查询性能最高
- 劣势:
- 数据冗余极高,相同type值会在category表重复存储无数次
- 后续要给type加属性(比如描述、排序、图标、启用状态等)完全无法扩展,只能硬往category表加字段,冗余会更严重
- 修改type名称、删除旧type时都需要批量操作category表,非常容易产生脏数据,也没法做type的合法性校验,很容易存入无效的type值

实际开发选型建议
- 如果是临时项目、内部小工具,type基本不会变更,也不需要加额外属性,category数据量很小,追求极致简单可以选方案3,正常业务项目不推荐
- 只有确定type名称几乎不会修改,type名称展示频率极高,category数据量不大,能接受字符串外键开销的极特殊场景,可以选方案2
- 90%以上的常规业务场景优先选方案1,符合设计规范、扩展性强、维护成本低,在有索引的前提下join带来的性能损耗几乎可以忽略,是最稳妥的选择
内容的提问来源于stack exchange,提问作者Mohammad Karimi
相关产品推荐
相关产品推荐

