关系数据理论(包含什么是数据依赖、函数依赖)
https://www.cnblogs.com/JCSU/articles/1324032.html
数据库需求的作用点:
有的数据增长量很大,但它们不是核心数据,对这些数据可采用分库分表存储。如,开发人员希望把日志类数据存储在数据库中,从数据库管理员的角度来看,这种数据是不适合存储在数据库中的。因为日志这种数据增长量极大,并且不属于核心数据。如果非要存储在数据库中的话,可在数据库存储之前定义好这类数据的归档或清理规则。随着数据库的上限,就会进行数据库的归档。如果当这个表增长量很大的时候,再进行归档,工作量会很大还会影响线上的使用。
使用ER图进行数据库逻辑建模
1、将需求转为数据库的逻辑模型
2、通过ER图的形式对逻辑模型进行展示
3、同所选用的具体的DBMS系统无关
操作异常
数据冗余
指相同数据在多个地方存在,或者说表中的某个列可由其他列计算得到,这样就说表中存在着冗余数据。
第一范式(1NF)
数据库表中的所有字段都是单一属性,不可再分的,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。这个单一属性是由基本的数据类型所构成的,如整数、浮点数、字符串等;总而言之第一范式要求数据库中的表都是二维表(二维表:由行和列所组成的表)。’
下图是一张不符合1NF的表:
第二范式(2NF)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。例如,员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。
若关系模式R∈1NF(即R符合第一范式),并且每一个非主属性都完全依赖于R的主码,则R∈2NF(即R符合第二范式)。
所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,理解了完全依赖和部分依赖,就很容易理解第二范式,下面举例说明一下。
1、不符合2NF的例子
该表中主键为(货物类型、货物id),货物名称字段完全依赖于这个主键,换句话说货物的名称是完全取决于这个主键的值。但“注意事项”这一列,仅依赖于“货物类型”这一个属性。简单的说,2NF要求每个非主属性完全依赖于主键,而不是仅依赖于其中一部分属性。那么,既然表中存在一个对主键不是完全依赖的属性,就可以确定此表是不符合2NF的。
2、符合2NF的例子
该表中的主键依然是(货物类型,货物id),非主键字段(即其它属性)“货物名称”完全依赖于此主键,那么这张表就是符合2NF的。
第二范式的优缺点
一个关系模式的分级例子
第三范式
第三范式(Third Normal Form,3rd NF)就是指表中的所有数据元素不但要能惟一地被主关键字所标识,而且它们之间还必须相互独立,不存在其他的函数关系。也就是说,对于一个满足2nd NF 的数据结构来说,表中有可能存在某些数据元素依赖于其他非关键字数据元素的现象,必须消除。
采用投影分解法将一个2NF的关系分解为多个3NF的关系,可以在一定程度上解决原2NF关系中存在的插入异常、删除异常、数据冗余度大、修改复杂等问题。
将一个2NF关系分解为多个3NF的关系后,并不能完全消除关系模式中的各种异常情况和数据冗余。
例:如S1(SNO,SNAME,DNO,DNAME,LOCATION) 各属性分别代表学号,姓名,所在系,系名称,系地址。
关键字SNO决定各个属性。由于是单个关键字,没有部分依赖的问题,肯定是2NF。但这关系肯定有大量的冗余,有关学生所在的几个属性DNO,DNAME,LOCATION将重复存储,插入,删除和修改时也将产生类似以上例的情况。原因:关系中存在传递依赖造成的。即SNO -> DNO。 而DNO -> SNO却不存在,DNO -> LOCATION, 因此关键字 SNO 对 LOCATION 函数决定是通过传递依赖 DNO -> LOCATION 实现的。也就是说,SNO不直接决定非主属性LOCATION。
解决目地:每个关系模式中不能留有传递依赖。
解决方法:分为两个关系 S(SNO,SNAME,DNO),D(DNO,DNAME,LOCATION)
注意:关系S中不能没有外关键字DNO。否则两个关系之间失去联系。
将第一范式,第二范式化为第三范式的步骤:
BC范式
BC范式一定满足第三范式,简单来说所有的非主码属性都需要消除传递函数依赖,包括候选码,则称为BC范式。
例子1:
比如我们有一个学生导师表,其中包含字段:学生ID,专业,导师,专业GPA,这其中学生ID和专业是联合主键。
这个表的设计满足三范式,有主键,不存在主键的部分依赖,不存在非主键的传递依赖。但是这里存在另一个依赖关系,“专业”函数依赖于“导师”,也就是说每个导师只做一个专业方面的导师,只要知道了是哪个导师,我们自然就知道是哪个专业的了。
所以这个表的部分主键依赖于非主键部分,那么我们可以进行以下的调整,拆分成2个表:
例子2:
物理设计(下面是以mysql为例)
根据数据库自身的特点把逻辑设计转换为物理设计(涉及到选用哪种数据库)
使用什么数据库管理系统,要考虑用途、开发语言、安全性,,,,等等因素
MySQL的存储引擎
表及字段的命名规则
1、可读性原则:
使用大写和小写来格式化的库对象的名字以获得良好的可读性。(如,使用CustAddress而不是custaddress来提高可读性;这里要注意有的DBMS是对大小写敏感的)
2、表意性原则
对象的名字应该能够描述它所标识的对象。例如,对于表,表的名字应该能够体现表中存储的数据内容;对于存储过程,存储过程应该能够体现存储过程的功能。
3、长名原则
尽可能少使用或不适用缩写,这样会降低可读性及它实际表达的功能
列的数据类型一方面影响数据存储空间的开销,另一方面影响数据查询性能。当一个列可以选择多种数据类型时,应该优先考虑数字类型,其次是日期或二进制类型,最后是字符类型。对于相同级别的类型,应该优先选择占用空间小的数据类型。
以上选择原则又从两个方面进行考虑:
如,一个birthday字段有以下数据类型可选择:
MySql中数据库类型所占空间介绍:
数据如何具体选择数据类型
Char和varchar如何选择:
Decimal和float类型如何选择:
时间类型如何选择
1、使用int类型来存储时间字段的优缺点:
优点:字段长度比datetime小
缺点:使用不方便,要进行函数转换
限制:
2、需要存储的时间粒度
年 月 日 小时 分 秒 周
反范式化是针对范式化而言的,在前面介绍了数据库设计的第三范式,所谓的反范式化就是为了性能和读取效率的考虑而适当的对第三范式的要求进行违反,而允许少量的数据冗余,话句话说反范式化就是使用空间来换取时间(可以减少查询时表的连接)。
一个表的设计往往读操作和写操作的成本比例如果是3:1那还是比较划算的。
反范式化的有点:
索引注意事项:
如何维护表结构
当需求增加,表的列越来越多
对每条数据的主键进行hash操作;比如说对主键进行按模取值,将一张大表的数据平均的分到了多张小表中
一个电商系统为例它里面所包含了模块,用户模块、商品模块、订单模块、购物车模块、供应商模块(只是为了展示,真正系统中肯定不止这些模块)。
ER图(只列出了每个实体中的关键属性;途中加了下滑线的属性表示主键):
把哪些实体信息应该存储到用一张表中,哪些该单独存。如下图所示,用户信息和购物车信息是该一起存在一张表中还是单独存在一张表中: