范式理论
何为范式,何为建模
函数依赖
1. 完全函数依赖
2. 部分函数依赖
3. 传递函数依赖
第一范式
第二范式
第三范式
何为范式,何为建模
范式理论和谁有关?和关系建模有关,通常我们说的三范式是啥东西,啥叫范式。
所谓的范式,就是我们在关系建模的时候所遵从的一些规范。
所谓的建模,就是意思是,你要建哪些表,每张表与每张表的关系是什么样的。每张表里大概又哪些字段,这就是所谓的数据库建模。
而关系型数据库设计时,遵照一定的规范要求,目的在于降低数据的冗余性。
为什么要降低数据冗余性?
优点:
?
(1)十几年前,磁盘很贵,为了减少磁盘存储。
(2)以前没有分布式系统,都是单机,只能增加磁盘,磁盘个数也是有限的
(3)一次修改,需要修改多个表,很难保证数据一致性
缺点:
?
范式的缺点是获取数据时,需要通过Join拼接出最后的数据。
分类:
目前业界范式有:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF)。
我们通常说的遵循三范式,就是遵循第一范式,第二范式,第三范式。
遵循三范式优缺点是什么?
可以降低数据冗余,但是表结构变的比较复杂,表会被拆成比较细碎的小表,查询数据的时候会涉及到多表Join,这样一来,我们肯定要走Shuffle。然后效率会变低。因为比较损耗性能。
现在条件好了,很多公司也并没有严格的遵循三范式。现在关系型数据库也遵循分库分表等操作,也支持类似集群的搭建了。扩展能力增强,不讲究什么冗余不冗余。冗余了,就不用拆表了,就可以减少一部分的Join。查询性能得到很大的提高。所以允许部分冗余的存在。
函数依赖
函数依赖,三范式中用到的,非常重要的理论。这里的函数,就是数学当中函数的概念。关系型模型,里面是有数学理论基础的,来,补个课吧,啥叫函数。废话不多,直接上图。
这叫正常函数,一个X只能映射到一个Y。
这就不叫我们熟知的函数了,可能叫丑函数。长的那么丑,三里屯门都不让进。这一个X对应了多个Y。
看表,我们来简单理解下以下的概论。
学号
姓名
系名
系主任
课名
分数
202099999
小李
公关
张三
喝酒
90
202088888
小王
DJ
李四
打碟
95
1. 完全函数依赖
通过学号,课程,就可以推出分数,但是,分数反向获取,获取不到对应的值,我知道分数,我也不知道谁得的这个分数,这个分数是哪个课程的分数,但是我通过学号就知道,我们就说分数,完全依赖于学号和课程。
2. 部分函数依赖
通过学号和课程,可以推出姓名,啥意思?通过学号和课程,我可以找到是谁。其实我直接通过学号也可以找到姓名,用不着再知道课程,这时,我们就说姓名,部份依赖于学号、课程。
3. 传递函数依赖
通过学号推出系名,通过系名推出系主任。但是通过系主任推不出学号,系主任主要依赖的是系名,这种情况,系主任传递依赖于学号。
为什么会给大家说这个函数依赖关系。
如果在我们的表中,出现了部份函数依赖,或者是传递函数依赖,那么我们的数据就会冗余。只有我们的表中是完全依赖关系的时候,我们的数据才不会冗余。
第一范式
第一范式1NF核心原则就是:属性不可切。
第一范式,没有用到我们上面的函数依赖关系。这里所谓的属性,就是我们表中的字段,字段内容是不可切的,字段必须是原子性的,我们举个例子。
上图这张表明显不符合第一范式的标准,为什么呢,因为我们有的字段还可以拆啊,商品字段底下,它将商品的数量和种类放在了一起。这很显然就不是原子性的了,想变成原子性怎么办?拆开就好了。看下图
在Mysql还有Oracle、SQL Server中如果数据库的表不符合这个最基本的要求,那么,操作时一定不能成功的,也就是说,在RDBMS中存在的表,一定符合1NF的。
第二范式
第二范式2NF核心原则就是:不能存在部分函数依赖
在我们的表中,我们的X和我们的Y分别指的时谁呢?X指的时我们这张表的主键,Y指的就是非主键字段,那么我们刚才的那句核心的话,我们翻译过来就是,不能存在非主键字段不能出现部份函数依赖于主键字段。
我们看下面这张表。
我们寻找以下非主键字段与主键字段依赖关系,我们得先明确谁时主键,想到学号的,都太年轻,为啥不能是学号,学号要是主键是不是不能重复啊。那么是什么呢?答案是联合主键,学号和课名一起作为联合主键,学号和课名加一起能够唯一标识我们的一行数据,比如:学号和课名加一起,可以找到分数。
我们找一下依赖关系,我们的学号和课名应该作为X,剩下的字段都可以作为Y,那么,我们学号和课名加一起,可不可以找到姓名?可以的,可不可以找到系主任,也是可以的。那么这个是部份函数依赖,我通过学号一个就可以找到姓名。那么我们呢第二范式要求是不能存在部份函数依赖的。所以,我们要变成下面这张表。把它切了。
我之所以这么切,是不是因为我通过学号就可以推出系主任、姓名啥的。那么这个是不是就不是部份函数依赖了。而且我同样的信息只出现了一次。但是我们还是没有消除彻底,但是我们达到了第二范式的要求。
第三范式
第三范式3NF核心原则:不能存在传递函数依赖
我们的表,经过了第一范式、第二范式、第三范式之后只剩下了完全函数依赖,最终,我们的表中只能剩下完全函数依赖,不能有传递,不能有部份。
不能传递函数依赖,我们给他补充完整就是,表里面不能存在非主键字段传递依赖于主键字段,X还是主键,Y还是非主键。看下面这张表。
这张表中,很鲜明还是有数据冗余现象,但是我们已经满足第二范式了,那肯定不是第二范式的事了,是第三范式,我们现在就看一看,把它变成第三范式,那么我们怎么从一张表中去找,所谓的传递函数依赖,照这个要麻烦一些,涉及到传递了,我们应该把表中的所有的函数依赖全部找到,才能发现传递的关系,所以我们得找到他们,我们这里说的并不仅仅是我们的联合主键或者主键,其他字段也要找。
我们看一下,学号能推出姓名,系名,系主任,下一步,我们以姓名为自变量。
我们拿到姓名,能拿到它的学号么?这个其实是不能的,我们要考虑到重名的现象,好比给我们好几个叫关羽的,那么会不会返回多个学号?这是不是相当于一个X对应多个Y了,连函数都不是,更别提函数依赖这回事,姓名同样也推不出来系名,系主任。
那我们再看一下,我们的系名能不能推出系主任,假定我们一个系只有一个系主任的情况下,这种情况下是能推出的,给我们一个系名,我们就可以完全的确定一个系主任,所以这个是存在函数依赖关系的。
那我们再看一下以系主任作为X自变量,那么系主任有重名,有重名就不能作为X。
那么我们寻找一下依赖关系,学号和系名,系名和系主任,很显然是一个传递依赖关系。我们的要求是不能存在这种关系,怎么办?拆!
最终拆成上面的这种情况,我们由一张表,最后拆成了三张表,我们如果像查询数据,就得三张表进行Join,但是我们的数据冗余确实没有了。