前言
针对大数据数仓项目基础知识小记—数据库ER建模
一、数据库建模基本概念
数据建模实质为为数据构建组织和存储方法。存储方式根据不同数据库有所不同,mysql关系型数据库采取二维表的方式。大数据框架的hdfs则是分布式文件存储方式,当然,其通过hive也能将文件映射成关系型数据库。本文探讨的主要是数据的组织方式,即怎么用二维表存储数据。
目前的数据库两种模型:ER建模、维度建模。
前者更倾向于对企业数据进行存储而不考虑计算统计等场景,即通过多级范式拆分表格,减少数据冗余并且提高数据的一致性。(数据一致性:不同表格都存储有一个名字字段,当某个表格的名字变化后,其他的数据可能没有发生变化,造成数据不一致的问题)。
后者倾向于数据的计算处理,以业务逻辑为事务,当前环境为维度进行建模,在存储性能上略差于前者,但是进行查询等操作时的时间和操作数都会显著降低。
二、ER建模
1.构建模型
ER(Entity Relationship)模型的构建方式:
将一个复杂对象抽象为实体和关系,并用规范化的方式表示出来。如一个年级独立出学生个体和班级号。此时,学生以及其属性可以独立一张表,班级独立一张表。再将其‘内在关系’关系起来。由于学生和班级是一对多的关系,在学生表后加上班级外键即可实现两表的join操作。若两个实体为任课老师和学生,此时两者为多对多的关系,多对多的关系使用外部表格辅助构建,因为如果还是在后面加入外键的话,外键的个数无法确定。外部表:学生+对应教师。
2.遵守范式
上述是表格的构建思路。表格的设计还应满足范式关系来减少数据冗余和提高数据一致性。满足范式的本质其实就是表格的拆分,因此也不是满足范式越多越好(理论上,满足范式越高,表格数据冗余越少),因为这样会存在很多的小表格和较为复杂的映射关系。
在实际应用中一般满足前三范式即可:
1、第一范式:满足数据的原子性,即不可拆分性。如:电脑,人,名字都是在业务意义上不可拆分。但是如‘一头孙辉’,可以明显拆为一和非人。
2、第二范式:不存在部分函数依赖。严格来说:因此是不存在部分依赖于主键的字段。对于部分依赖于主键的字段,可以拆分出去和主键列作为一张表。
依赖的解释:
1)完全函数依赖
“学生id+课程号”能得到课程成绩,两者缺一不可。则称后者完全依赖于前者。在单字段的对应下可视为函数映射只能进行一对一的映射。
2)部分函数依赖
“学生id+课程号”能得到课程成绩,那么“学生id+课程号+学生名字”也可以得到课程成绩。但是丢掉学生名字,一样可以得到课程成绩。则称“课程成绩”部分依赖于“学生id+课程号+学生名字”。
3)传递函数依赖
X->Y,Y->Z则可以得到X->Z关系,其中,Y!->X,如果Y也同样能得到X,则两者互为一对一的关系,则X->Z也直接是对应关系,都不用通过Y关联。
3、第三范式;不存在传递函数依赖,若存在,则把Y->Z这一部分单独拆分出去。
如图所示:学号和后三列都是完全依赖关系,因此满足第二范式,第二范式通常用在多主键的情况。而对于第三范式:我们只需要找出后三列是否存在依赖关系。姓名和系主任首先排除,因为可能多个人会对应一个名字,则会出现X的多对一的形式,不满足第二范式。所以只有系名能作为X,以一对一的关系,对应系主任这一字段。则可再划分一个表,存储系名和系主任这俩字段。
三、总结
对于上述问题的总结:
1、为什么只能进行一对一的映射,首先,多对一不行,因为主键的唯一性。而一对多拿出去构建表会发现,表格字段长度不统一。
2、范式怎么帮助我们减少冗余和提高一致性:
对于一致性而言,把某些重复的数据拿出去,新建一个表来对应,在修改时,只要修改后边的数据,则可保证数据的一致性和操作的简便性。而其他需要改字段的表,都直接来和该表join即可。
对于减少冗余而言:如上图,若表很大,而只有两个系,则要多存n个系主任的名字,而把系和系主任拆解出来,右边只有一张很小的表(2行2列),而减少了左表的一个包括n个数据的字段。