设计范式

数据库设计三范式:

  • 第一范式:数据表中的每一列都是原子的,不可再拆分
  • 第二范式:每张表中的一条记录只描述一个实体
  • 第三范式:数据表中不要存在冗余字段(可以通过其他字段推导出的字段)

1)第一范式:数据表中的每一列都是原子的,不可再拆分

有一张用户考勤表设计如下

id 用户名 考勤时间
1 张三 9:00 - 18:00
2 李四 9:30 - 18:00

表中的考勤时间字段明显不是原子的,可以拆分为:上班时间和下班时间

id 用户名 上班时间 下班时间
1 张三 9:00 18:00
2 李四 9:30 18:00

2)第二范式:每张表中的一条记录只描述一个实体

有一张会员账户表设计如下

会员编号 会员名称 手机号 账户编号 账户类型 账户余额
C00001 张三 13800000001 ACC001 红包 200
C00001 张三 13800000001 ACC002 红包 300
C00001 张三 13800000001 ACC003 金币 500

目前表中明显分为两部分数据:会员表和账户表,应该拆到两张表中,两表通过外键建立关联

会员编号 会员名称 手机号
C00001 张三 13800000001
账户编号 账户类型 账户余额 所属会员编号
ACC001 红包 200 C00001
ACC002 红包 300 C00001
ACC003 金币 500 C00001

3)第三范式:表中不存在冗余字段(可以通过其他字段推导出的字段)

有一张账户表和会员表设计分别如下

账户编号 账户余额 所属会员编号 所属会员名称
ACC001 200 C00001 张三
ACC002 300 C00001 张三
会员编号 会员名称 手机号
C00001 张三 13800000001

正例:在账户表中只保存会员编号就可以,因为可以通过此字段推导出会员名称

账户编号 账户余额 所属会员编号
ACC001 200 C00001
ACC002 300 C00001
会员编号 会员名称 手机号
C00001 张三 13800000001

数据库设计反三范式:添加一定的冗余字段,减少多表查询或者字段计算

  • 优点:提高查询效率,降低了数据计算成本
  • 缺点:数据冗余,增加了存储空间的占用;数据一致性维护难度增加

例如下表:在账户表中添加了会员名称,一定程度上避免了跟会员表的联合查询

账户编号 账户余额 所属会员编号 所属会员名称
ACC001 200 C00001 张三
ACC002 300 C00001 张三

例如下表:在订单表中添加了总价,避免了查询过程中进行的计算

订单编号 商品名称 商品单价 购买数量 总价
ACC001 水杯 10 5 50
ACC001 钢笔 15 10 150

设计思路

设计数据表主要参考原型图和需求文档,大体思路如下:

  1. 表设计:
    1. 表名:见名知义,不要使用驼峰,不要使用关键字,尽量不要使用复数(非强制)
    2. 字段:数量不易过多(最好保持在20以内),大文本应当单独建立副表存储
  2. 字段获取:主要的依据就是原型图,大体分为三类
    1. 基础字段:从原型图的新增、查询、修改页面中找
    2. 辅助字段:创建时间、修改时间、创建人、修改人、逻辑删除、备注
    3. 主键外键:主键尽量不要跟业务有关联(非强制),外键要根据表间关系来设计
  3. 字段类型:常用的数据类型如下
    1. 数值:tinyint、int、bigint、double(小数,建议使用decimal)
    2. 字符串:char(定长)、varchar(变长)、text(大文本)
    3. 时间:date(日期)、datetime(日期时间)、timestamp(自动更新时间戳)
    4. 金钱: decimal
  4. 约束、索引:
    1. 主键:必须要有,最好是非业务性质(非强制)
    2. 唯一、非空、默认值
    3. 外键:目前不建议添加物理外键,影响性能,使用逻辑外键即可