数据库设计笔记
数据库设计学习笔记!
先谢慕课网。
什么是数据库设计?
数据库设计就是根据业务系统的具体需要,结合我们所选用的DBMS(数据库管理系统),为这个业务系统构造出最优的数据存储模型。并建好数据库中的表结构及表与表之间的关联关系的过程。使之能有效地对应系统中的数据进行存储,并可以高效的对已经存储的数据进行访问。
NoSQL系统:Mongo/ Memcache/ Redis
为什么要进行数据库设计?
优良的设计:
减少数据冗余
避免数据维护异常
结构存储空间
高效的访问
糟糕的设计:
存在大量的数据冗余
存在数据插入,更新,删除异常
存在大量空间浪费
访问数据低效
数据库设计步骤
需求分析---->逻辑分析---->物理设计---->维护优化
需求分析:
数据是什么?
术具有哪些属性?
数据和属性各自的特点有哪些?
逻辑设计:
主要是通过ER图对数据库进行逻辑建模
物理设计:
充分的考虑到每一种数据库管理系统的特点;
根据数据库自身的特点把逻辑设计转换成物理设计
维护优化:
新的需求进行建表
索引优化
大表拆分
需求分析:
为什么要进行需求分析?
1.了解系统中所要存储的数据
2.了解数据的存储特点
3.了解数据的生命周期
实体及实体之间的关系(1对1,1对多,多对多)
实体所包含的属性有什么?
那些属性或属性的组合可以唯一标识一个实体?
需求分析举例(小型电子商务网站)
用户模块、商品模块、订单模块、购物车模块、供应商模块
用户模块:
包括属性;
可选唯一标识属性
存储特点:随系统上线时间增加,需要永久保存
商品模块:
存储特点:对于下线商品可以归档存储
订单模块:
存储特点:永久存储
购物车模块:
存储特点:不用永久存储(设置归档,清理规则)
供应商模块:
存储特点:随系统上线时间增加,需要永久保存(数量可能有限制)
逻辑设计:
逻辑设计是做什么的
1.将需求转化为数据库的逻辑模型
2.通过ER图的形式对逻辑模型进行展示
3.同所选的具体的数据库管理系统无关
名词解释:
关系:一个关系对应通常所说的一张表
元组:表中的一行即为一个元组
属性:表中的一列即为一个属性;每一个属性都有一个名称,成为属性名
候选码:表中的某个属性组,它可以唯一确定一个元组
主码:一个关系有多个候选码,选中其中一个为主码
域:属性的取值范围
分量:元组中的一个属性值
设计范式概要:
常见的数据库设计范式包括:
第一范式,第二范式,第三范式及BC范式
重点放在前三个范式上面;
数据操作异常及数据冗余
插入异常、更新异常、删除异常;
相同的数据在多个地方存在,或者某个列可以有其他列计算得到,就是数据冗余
第一范式:数据库中的所有字段都是单一属性,不可再分的。表都是二维表
第二范式:数据库的表中不存在非关键字段对任一候选关键字段的部分函数依赖。
部分函数依赖是指存在着组合关键字中的某一关键字决定非关键字的状况。
第三范式:第三范式是在第二范式的基础上定义的,如果数据表中不存在非关键字段对任意候选关键字段的传递函数依赖则符合第三范式。
BC范式:在第三范式的基础之上,数据表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合BC范式。
物理设计:
物理设计要做什么
1.选择合适的数据库管理系统;
2.定义数据库、表以及字段的命名规范;
3.根据所算的DBMS系统选择合适的字段类型;
4.反范式化的设计。
选择那种数据库?
Oracle、SQLsercer、MySQL、PgSQL
成本上:
Oracle和SQLServer属于商业数据库,需要考虑成本;
MySQL和PgSQL是开源数据库
功能上:
Oracle功能比较强,事务处理好
所以使用的操作系统:
SQLServer只能在Windows上
开发所使用的语言:
PHP使用MySQL
应用的场景:
Oracle和SQLServer更适合企业级项目
MySQL和PgSQL适用于互联网项目
MySQL常用的存储引擎
MyiSAM 写很少,读很多可以使用,读写都很频繁不要使用
MRG_MYISAN 可以把多个结构相同的MyiSAM表合并到一个表处理,不支持行级锁,不支持事物,不适用于全局查到过多的场景
Innodb MySQL5.5之后MySQL默认的存储引擎,支持事务,支持行级锁,大多数场景都可以使用;读写也是很高效的;
Archive 也是行级锁,适用于日志这种场景,支持insert,select,需要随机读取,更新删除的场景
Ndb cluster 要在使用MySQL集群的场景下才可以使用
主要使用、建议Innodb,相比来说是一个比较好的选择
表及字段的命名规范:
1.可读性原则
2.表意性原则
3.长命原则(尽量不要使用缩写)
字段类型选择:
列的数据类型一方面影响数据存储空间的开销,另一方面也会影响数据查询性能。当一个列可以选择多种数据类型时,应该优先考虑数字类型,其次是日期和二进制类型,最后是字符串类型。对于相同级别的数据类型,优选选择占用空间小的数据类型。
TINYINT-->SMALLINT-->MIDIUMINT-->INT-->BINGINT-->DATE-->DATETIME-->TIMESTAMP-->CHAR(M)-->VARCHER(M)
在对数据进行操作时,同样的数据,字符处理往往比数字处理慢。
数据库中数据处理是以页为单位,MySQL在Innodb中16k一页;
数据库最大的瓶颈是磁盘的I/O瓶颈。
char与varchar如何选择:
原则:
1.如果列中要存储的长度差不多是一致的,应该考虑使用char,比如电话号
2.如果列中的最大数据长度小于50Byte,一般考虑用char
3.一般不宜定义大于50Byte的char类型类。
decimal和float如何选择:
原则:
1.decimal适用于存储精确数据,而float只能用于存储非精确数据;
2.由于float的存储空间开销一般比decimal小,所以非精确的数据优先选择float类型。
时间类型如何存储:
1.int长度、其使用不方便、限制
2.需要存储的时间粒度
数据库设计的其他注意:
如何选择主键:
1.区分业务主键和数据库主键
业务主键用于表示业务数据,进行表与表之间的关联;
数据库主键为了优化数据存储
2.根据数据库的类型,考虑主键是否要顺序增长
3.转的字段类型所占空间要尽可能的小
避免使用外键约束
1.降低数据导入的效率
2.增加维护成本
2.虽不建议使用外键约束,但是相关联的列上一定要建立索引;
避免使用触发器
1.降低数据导入的效率
2.可能会出现意想不到的数据异常
3.是业务逻辑表的复杂
严禁使用预留字段
反范式化设计:
反范式化是针对范式化而言的,为了性能和读取效率的考虑而是当的对第三范式的要求进行违反,而存在少量的数据冗余,使用空间来换时间;
维护优化:
维护和优化要做些什么:
1.维护数据字典
2.维护索引
3.维护表结构物
4.在适当的时候对表进行水平拆分或垂直拆分
如何维护数据字典
information_schema表中的TABLES表和COLUMN表
如何维护索引
如何选择合适的列建立索引?
1.出现在WHERE从句,GROUP BY从句,ORDER BY从句中的列
2.可选择性高的列要放到索引的前面
3.索引中不要包括太长的数据类型
注意事项:
1.索引并不是越多越好的,过多的索引不但会降低写效率,而且会降低读的效率;
2.定期维护索引碎片;
3.SQL中不要使用强制索引关键字。
如何维护表结构
1.使用在线变更表结构的工具;
2.同时对数据字典进行维护;
3.控制表的宽度和大小。
数据库中适合的操作:
1.批量操作和逐条操作,批量操作好
2.禁止使用SELECT *这样的查询
3.控制用户使用自定义函数
4.不要使用数据库中的全文索引
表的垂直和水平拆分
垂直拆分:把一张表的列进行拆分
当我们的需求变得越来越多,可能对列进行增加
一张表非常宽的时候,一页中搜索的行数少。
1.经常一起查询的列放到一起;
2.text、blod等大字段拆分到附加表中;
水平拆分:通过主键hash的方式拆分,取模。
2.了解数据的存储特点
3.了解数据的生命周期
实体及实体之间的关系(1对1,1对多,多对多)
实体所包含的属性有什么?
那些属性或属性的组合可以唯一标识一个实体?