优良的设计 | 糟糕的设计 |
---|---|
减少数据冗余 | 存在大量数据冗余 |
避免数据维护异常 | 存在数据插入,更新,删除异常 |
节约存储空间 | 浪费大量存储空间 |
高效的访问 | 访问数据低效 |
数据库需求的作用点:
使用ER图对数据库进行逻辑建模
根据数据库自身的特点把逻辑设计转换为物理设计。
以一个小型的电子商务网站为例,在这个电子商务网站的系统中包括了几个核心模块:用户模块,商品模块,订单模块,购物车模块,供应商模块。
用于记录注册用户信息
包括属性:用户名,密码,电话,邮箱,身份证号,地址,姓名,昵称…
可选唯一标识属性:用户名,身份证,电话
存储特点:随系统上线时间逐渐增加,需要永久存储。
用于记录网站中所销售的商品信息
包括属性:商品编码,商品名称,商品描述,商品品种,供应商名称,重量,有效期,价格…
可选唯一标识属性:(商品名称,供应商名称),(商品编码)
存储特点:对于下线商品可以归档存储。
用于用户订购商品的信息
包括属性:订单号,用户姓名,用户电话,收获地址,商品编号,商品名称,数量,价格,订单状态,支付状态,订单类型…
可选唯一标识属性:(订单号)
存储特点:永久存储(分表,分库存储)
用于保存用户购物时选对的商品
包括属性:用户名,商品编号,商品名称,商品价格,商品描述,商品分类,加入时间,商品数量…
可选唯一标识(用户名,商品编号,加入时间),(购物车编号)
存储特点:不用永久存储(设置归档,清理规则)
用于保存所销售商品的供应商信息
包括属性:供应商编号,供应商名称,联系人,营业执照号,地址,法人…
可选唯一标识:(供应商编号),(营业执照号)
存储特点:永久存储
关系:一个关系对于通常所说的一张表。
元组:表中的一行即为一个元组。
属性:表中的一列即为一个属性;每一个属性都有一个名称,称为属性名。
候选码:表中的某个属性组,它可以唯一确定一个元组,即主键或唯一索引。
主码:一个关系有多个候选码,选的其中一个为主码。
域:属性的取值范围。
分量:元组中的一个属性值。
矩形:表示实体集,矩形内写实体集的名字。
菱形:表示联系集。
椭圆:表示实体的属性。
线段:将属性连接到实体集,或将实体集连接到联系集。
常见数据库设计范式包括:
第一范式,第二范式,第三范式及BC范式
当然还有第四及第五范式
这是目前我们大多数数据库设计所要遵循的范式。
操作异常:
数据冗余:是指相同的数据在多个地方存在,或者说表中的某个列可以由其他列计算得到,这样就说表中存在着数据冗余。
定义:数据库表中的所有字段都是单一属性,不可再分的。这个单一属性是由基本的数据类型所构成的,整数,浮点数,字符串,等;
换句话说 第一范式要求数据库中的表都是二维表。都有行和列构成。
定义:数据库的表中不存在非关键字端对任一候选关键字段的部分函数依赖。
部分函数依赖是指存在着组合关键字(多个主键)中的某一关键字决定非关键字的情况。
换句话说:所有单关键字段的表都符合第二范式。
存在的问题:
定义:第三范式是在第二范式的基础之上定义的,如果数据表中不存在非关键字段对任意候选关键字段的传递函数依赖则符合第三范式。
上述表存在问题:
(分类,分类描述)对于每一个商品都会进行记录,所以存在着数据冗余。同时也还存在数据的插入,更新及删除异常。
定义:在第三范式的基础之上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合BC范式。
也就是说如果是复合关键字,则复合关键字之间也不能存在函数依赖关系。
假定:供应商联系人只能受雇于一家供应商,每家供应商可以供应多个商品则存在如下决定关系:
(供应商,商品ID)->(联系人,商品数量)
(联系人,商品ID)->(供应商,商品数量)
存在下列关系因此不符合BCNF要求:
(供应商)->(供应商联系人)
(供应商联系人)->(供应商)
并且存数据操作异常及数据冗余。
第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。
第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。
第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF.
注:关系实质上是一张二维表,其中每一行是一个元组,每一列是一个属性
每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来。
例如:订单表只能描述订单相关的信息,所以所有的字段都必须与订单ID相关。产品表只能描述产品相关的信息,所以有的字段都必须与产品ID相关。因此在同一张表中不能同时出现订单信息与产品信息。
比如一张表是(A,B,C,D),其中(A,B)是主键,如果存在B->C就违反了2NF,因为C只需要主键的一部分就可以被决定了
数据不能存在传递关系,即没个属性都跟主键有直接关系而不是间接关系。像:a–>b–>c属性之间含有这样的关系,是不符合第三范式的。比如Student表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)
这样一个表结构,就存在上述关系。 学号–> 所在院校 --> (院校地址,院校电话)
这样的表结构,我们应该拆开来,如下。
(学号,姓名,年龄,性别,所在院校)–(所在院校,院校地址,院校电话)
在第三范式的基础上,不允许出现有主键的一部分被主键另一部分或者其他部分决定。
1.第二范式与第三范式的本质区别:在于有没有分出两张表。
第二范式是说一张表中包含了多种不同实体的属性,那么必须要分成多张表,第三范式是要求已经分好了多张表的话,一张表中只能有另一张标的ID,而不能有其他任何信息,(其他任何信息,一律用主键在另一张表中查询)。
2.必须先满足第一范式才能满足第二范式,必须同时满足第一第二范式才能满足第三范式。
所有的对象命名应该遵循下述原则:
列的数据类型一方面影响影响数据存储空间的开销,另一方面也会影响数据查询性能。当一个列可以选择多种数据类型时,应该优先考虑数字类型,其次是日期或二进制类型,最后是字符类型,对于相同级别的数据类型,应该优先选择占用空间小的数据类型。
以上选择原则主要是从下面两个角度考虑:
原则:
注:utf-8每个占3个Byte 16个字符占48个Byte。
原因:varchar除了必要的数据外还需要额外的数据存储变长数据的相关信息,而在检索数据时也要检索数据的起始位置。
原则:
使用int来存储时间字段的优缺点
优点:字段长度比datetime小。
缺点:使用不方便,要进行函数转换。
限制:只能存储到2038-1-19 11:14:07即2^32为2147483648
需要存储的时间粒度
年 月 日 小时 分 秒 周
但使用int存储取出的时候还有进一步转化为datetime类型故如果存储的日期不常用到则使用int经常要用到则用datetime
反范式化是针对范式化而言的,在前面介绍了数据库设计的第三范式,所谓的反范式化就是为了性能和读取效率的考虑而适当的对第三范式的要求进行违反,而允许存在少量的数据冗余,换句话来说反范式化就是使用空间来换取时间。
如何选择合适的列建立索引?
注意事项
注意事项
减少页每一行数据的数据量,提高查找速度。但数据量不能有变化。
减少每张表的数据量
参考