1. 物理设计要做什么?
Ø 选择合适的数据库管理系统
Ø 定义数据库、表及字段的命名规范
Ø 根据所选的DBMS系统选择合适的字段类型
Ø 反范式设计
2. 选择哪种数据库
Ø 成本和性能
Ø Oracle、SQLServer等商业数据库更适合企业级项目
Ø MySQL、PgSQL等开元数据库适用于互联网项目
3. MySQL常用的存储引擎
表8MySQL常用的存储引擎
存储引擎 |
事务 |
锁粒度 |
主要应用 |
忌用 |
MylSAM |
不支持 |
支持并发插入的表级锁 |
SELECT,INSERT |
读写操作频繁 |
MRG_MYISAM |
不支持 |
支持并发插入的表级锁 |
分段归档,数据仓库 |
全局查找过多的场景 |
Innodb |
支持 |
支持MVCC的行级锁 |
事务处理 |
无 |
Archive |
不支持 |
行级锁 |
日志记录,只支持insert,select |
需要随机读取,更新,删除 |
Ndb cluster |
支持 |
行级锁 |
高可用性 |
大部分应用 |
4. 表及字段的命名规则
Ø 可读性原则
Ø 表意性原则
Ø 长名原则
5. char与varchar如何选择
Ø 如果列中要存储的数据长度差不多是一致的,则应该考虑用char;否则应该考虑用varchar。
Ø 如果列中的最长长度小于50Byte,则一般也考虑用char。
Ø 一般不宜定义大于50Byte的char类型列。
6. decimal与float如何选择
Ø decimal用于存储精确数据,而float只能用于存储非精确数据。故精确数据只能选择用decimal类型。
Ø 由于float的存储空间开销一般比decimal小(精确到7为小数只需要4个字节,而精确到15位只需要8字节),故非精确数据有限选择float类型。
7. 时间类型如何存储
Ø 使用int来存储时间字段的优缺点
n 优点:字段长度比datetime小
n 缺点:使用不方便,要进行函数转换
n 限制:只能存储到2038-1-19 11:14:07即2^32为2147483648
Ø 需要存储的时间粒度
n 年 月 日 小时 分 秒 周
8. 如何选择主键
Ø 区分业务主键和数据库主键
n 业务主键用于标识业务数据,进行表与表之间的关联;
n 数据库主键为了优化数据存储(Innodb会生成6个字节的隐含主键)
Ø 根据数据库的类型,考虑主键是否要顺序增长
n 有些数据库是按主键的顺序逻辑存储额
Ø 主键的字段类型所占空间要尽可能的小
n 对于使用聚集索引方式方式存储的表,每个索引后都会附加主键信息
9. 避免使用外键约束
Ø 降低数据导入的效率
Ø 增加维护成本
Ø 虽然不建议使用外键约束,但在相关联的列上一定要建立索引
10. 避免使用触发器
Ø 降低数据导入的效率
Ø 可能会出现意想不到的数据异常
Ø 使业务逻辑便的复杂
11. 关于预留字段
Ø 无法准确的指导预留字段的类型
Ø 无法准确的知道预留字段中所存储的内容
Ø 后期维护预留字段所要的成本,同增加一个字段所需要的成本是相同的
Ø 严禁使用预留字段
12. 反范式化
Ø 反范式化是针对范式化而言的,在前面介绍了数据库设计的第三范式,所谓的反范式化就是为了性能和读取效率的考虑而适当的对第三范式的要求进行违反,而允许存在少量的数据冗余,换句话说反范式化就是使用空间来换取时间。
13. 反范式化的设计
表9 范式化的设计
用户表 |
用户ID |
姓名 |
电话 |
地址 |
邮编 |
||||
订单表 |
订单ID |
用户ID |
下单时间 |
支付类型 |
订单状态 |
||||
订单商品表 |
订单ID |
商品ID |
商品数量 |
商品价格 |
|||||
商品表 |
商品ID |
名称 |
描述 |
过期时间 |
Ø 如何查询订单信息
SELECT b.用户名,b.电话,b.地址,a.订单ID,SUM(c.商品价格*c.商品数量) as 订单价格FROM‘订单表’a JOIN‘用户表’b ON a.用户ID=b.用户ID JOIN ‘订单商品表’c ON c.订单ID=b.订单IDGROUP BY b.用户名,b.电话,b.地址,a.订单ID
à
SELECT b.用户名,b.电话,b.地址,a.订单ID,c.商品名称,c.过期时间,c.商品数量,c.商品价格 FROM‘订单表’a JOIN‘用户表’b ON a.用户名ID=b.用户IDJOIN‘订单商品表’c ON c.订单ID=b.订单ID
Ø 如何查询订单信息
SELECT b.用户名,b.电话,b.地址,a.订单ID,SUM(c.商品价格*c.商品数量) as 订单价格,c.商品价格 FROM‘订单表’a JOIN‘用户表’b ON a.用户ID=b.用户IDJOIN‘订单商品表’c ON c.订单ID=b.订单ID JOIN‘商品表’d on d.商品ID=c.商品ID
à
SELECT a.用户名,a.电话,a.地址,a.订单ID,a.订单价格 FROM‘订单表’a
表10 反范式化的设计
用户表 |
用户ID |
姓名 |
电话 |
地址 |
邮编 |
|||||||||||||
订单表 |
订单ID |
用户ID |
下单时间 |
支付类型 |
订单状态 |
订单价格 |
姓名 |
地址 |
电话 |
|||||||||
订单商品表 |
订单ID |
商品ID |
食品 数量 |
商品 价格 |
商品 名称 |
过期 时间 |
||||||||||||
商品表 |
商品ID |
名称 |
描述 |
过期时间 |
14. 为什么反范式化
Ø 减少表的关联数量
Ø 增加数据的读取效率
Ø 反范式化一定要适度
Ø 在适当的时候对表进行水平拆分或垂直拆分