数据表设计规范
设计范式
数据库设计三范式:
- 第一范式:数据表中的每一列都是原子的,不可再拆分
- 第二范式:每张表中的一条记录只描述一个实体
- 第三范式:数据表中不要存在冗余字段(可以通过其他字段推导出的字段)
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 |
设计思路
设计数据表主要参考原型图和需求文档,大体思路如下:
- 表设计:
- 表名:见名知义,不要使用驼峰,不要使用关键字,尽量不要使用复数(非强制)
- 字段:数量不易过多(最好保持在20以内),大文本应当单独建立副表存储
- 字段获取:主要的依据就是原型图,大体分为三类
- 基础字段:从原型图的新增、查询、修改页面中找
- 辅助字段:创建时间、修改时间、创建人、修改人、逻辑删除、备注
- 主键外键:主键尽量不要跟业务有关联(非强制),外键要根据表间关系来设计
- 字段类型:常用的数据类型如下
- 数值:tinyint、int、bigint、double(小数,建议使用decimal)
- 字符串:char(定长)、varchar(变长)、text(大文本)
- 时间:date(日期)、datetime(日期时间)、timestamp(自动更新时间戳)
- 金钱: decimal
- 约束、索引:
- 主键:必须要有,最好是非业务性质(非强制)
- 唯一、非空、默认值
- 外键:目前不建议添加物理外键,影响性能,使用逻辑外键即可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Norlcyan's Blog!
