一、关系
1、将实体与实体的关系,反映到最终数据库表的设计上,将关系分成三种:一对一、一对多(多对一)和多对多
注:所有的关系都是指表与表之间的关系
2、一对一:一张表的一条记录一定只能与另外一张表的一条记录进行对应,反之亦然。一对一关系的设计方案是保证两张表中使用同样的主键即可
eg:将人员的常用信息(姓名、性别、年龄等)和不常用信息(婚姻、籍贯、家庭住址等)分离存储,提高查询效率。使用一个具有唯一性的字段来共同连接两张表,保证常用信息和不常用信息一一对应
3、一对多:通常也叫多对一。一张表中的一条记录可以对应另外一张表中的多条记录。但反过来,另外一张表的一条记录只能对应第一张表的一条记录。一对多关系的设计方案是在“多”关系的表中维护一个字段,这个字段是“一”关系表的主键(通常是在“多”表中维护“一”表对应的关系)
eg:在孩子表(多表)中增加一个字段指向妈妈表(一表)
4、多对多:表A中的一条记录能够对应表B中的多条记录,同时表B中的一条记录也能对应表A中的多条记录。多对多关系的设计方案是增加一个中间表,让中间表与对应的其他表形成两个多对一的关系,多对一的解决方案是在“多”表中增加“一”表对应的主键字段
问题:多对多的关系如果按照多对一的关系维护,就会出现一个字段中有多个其他表的主键,在访问的时候就会带来不便
解决方案:既然通过两张表自己增加字段解决不了问题,那么就通过第三张表来解决。设计一张中间表,维护两张表对应的联系,每一种联系都包含
eg:增加一张新表,专门维护老师表和学生表之间的(多对多)关系。老师表与中间表是一对多的关系,中间表是多表,维护了能够唯一找到一表的关系;同样的,学生表与中间表也是一对多的关系,中间表是多表,一对多的关系可以匹配到关联表之间的数据
(1)学生找老师:找出学生id --> 中间表寻找匹配记录(多条) --> 老师表匹配(一条)
(2)老师找学生:找出老师id --> 中间表寻找匹配记录(多条) --> 学生表匹配(一条)
二、范式
1、范式:Normal Format。离散数学中的知识,为了解决数据的存储与优化问题。保证数据存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储。终极目标是减少数据冗余(用最少的数据解决最大的存储)
注:范式是为了节省存储空间
2、范式是一种分层结构的规范,分为六层,每一层都比上一层更加严格。若要满足后一层范式,前提是满足前一层范式
注:六层范式:1NF, 2NF, ..., 6NF。1NF是最底层,要求最低;6NF是最高层,最严格
3、MySQL属于关系型数据库,有空间浪费。所以也致力于节省存储空间,与范式要解决的问题不谋而合。在设计数据库的时候,利用范式来指导设计。但数据库不单要解决空间问题,也要保证效率问题。而范式只为解决空间问题,所以数据库的设计不能完全按照范式的要求实现。一般情况下,只有前三种范式需要满足(满足三范式即可)
注:范式在数据库的设计中有指导意义,但不是强制规范
4、1NF:第一范式。第一范式要求字段的数据具有原子性,不可再拆分。在设计表存储数据的时候,如果表中字段存储的数据在取出来使用之前还需要额外的处理(拆分),说明该表的设计不满足第一范式。应该把字段分开存储
5、2NF:第二范式。第二范式要求表设计不允许出现部分依赖。在数据表设计的过程中,如果有复合主键(多字段主键),且表中有字段并不是由整个主键来确定,而是依赖主键中的某个字段(主键的部分),即存在字段依赖主键的部分,就是部分依赖。只要不存在复合主键,就不存在部分依赖,就永远满足第二范式(使用逻辑主键)
6、3NF:第三范式。第三范式解决传递依赖的问题。理论上讲,一张表中的所有字段都应该直接依赖主键(逻辑主键除外)。如果表设计中存在一个字段,该字段并不直接依赖主键,而是通过某个非主键字段依赖,最终实现依赖主键。把这种不直接依赖主键,而是依赖非主键字段的依赖关系称之为传递依赖。解决方案:将存在传递依赖的字段,以及依赖字段本身取出,形成一个单独的表。然后在需要对应的信息时,使用对应的实体表的主键
注:之所以使用逻辑主键是因为逻辑主键可以自增长,数字传递也很方便(业务主键也可以唯一)
7、用id代替值的好处
(1)节省空间
(2)从范式的角度来说,凡是能够结合别的地方查到的数据,就不再重复存储 -- 取消数据冗余(属于一类的东西就用一张表单独存储)
8、逆规范化
(1)在设计表的时候,如果一张表中有几个字段需要从另外的表中去获取信息,理论上,的确可以获取到想要的数据,但是效率会降低。刻意的在某些表中,不保存另外表的主键(逻辑主键),而是直接保存想要的数据信息。这样,在查询数据的时候,一张表可以直接提供数据,就不需要多表查询,会提高效率,但也会导致数据冗余增加
(2)范式是减少数据冗余,提高磁盘利用率的,但会降低效率。逆规范化是提高效率的,但会带来部分数据的冗余(和范式对抗)。在大型项目中,提高效率是非常重要的(增加磁盘冗余来提高效率)
(3)逆规范化是磁盘利用率与效率的对抗
9、总结
(1)三层范式
a). 1NF:字段设计必须符合原子性
b). 2NF:不存在部分依赖(没有复合主键)
c). 3NF:不存在传递依赖(实体单独建表)
(2)逆规范化:效率与磁盘空间的博弈