数据库模型概述 | 青训营笔记

124 阅读9分钟

这是我参与「第四届青训营 」笔记创作活动的第3天,在今天中午,我阅读hbase的时候发现自己对数据库模型了解不足,所以重温了一下关于数据库模型的相关知识。

层次结构模型

1.1 基础概念

在现实世界中,有很多数据都是具有层次的特征的,由数据结构我们自然想到可以用来表达现实世界,层次数据模型就是基于这种想法提出来的。 ​ 层次数据模型的提出,首先是为了模拟这种按层次组织起来的事物。 ​ 在下面,我们会提到几个概念:记录型,字段,记录。我们用一张图来清楚地表示:

数据模型1.png

在这个表格中,黄色部分表示记录的型;蓝色部分表示记录。而记录的型里面某个属性叫做字段

1.2 结构

层次模型中有着PCR关系,这里的PCR并非高中生物课本的PCR,而是指双亲子女关系(Parent-Chlid-Relationship,PCR),他是层次模型中最基本的数据关系,他代表了两个记录型之间一对多的关系。例如学生和课程,一个学生可以选修多个课程。 ​ 也就是说,我们的层次数据模型就是基于PCR的一种模型,其应该为一颗倒立的树,除了根,每个记录型都应该有他自己对应且唯一的父母,但是每个父母可以有多个子女。

数据模型2.png

其实抛开这个问题不讲,在现实世界中,不是说所有的关系都是一对多的,也有可能是多对一,或者多对多,这就是所谓的多元关系。假设我们有这么一个例子,一个学生可以选择多门课,一门课可以被多个学生选择。假设学生是父,那么课就是子,多门课只能对应一个父,也就是说想要一门课要想能被多个学生选择,那么根据PCR关系,他必须复制多份一模一样的课出来,如图所示:

数据模型3.png

用PCR处理后:

数据模型4.png

这样的话导致了数据冗余,原本一个人工智能的课在数据库中拷贝了三份。

1.3 虚拟记录

由上面简单的例子可以知道PCR会导致数据冗余,不但浪费存储空间,还导致数据不一致。由此我们引出了虚(拟)记录的概念。 虚记录(Virtual Record): ​ 其实就是如果遇见上述的关系,我们无须复制一份,只需要在引用的地方用其指针来代替即可,用指针替代的记录叫做虚记录,虚记录通常用下标V表示,指针用虚线箭头表示。 举一个例子来说:

数据模型5.png

由图可知,学生指向课程,但是指过去无法指回来;所以我们指向他的虚记录,虚记录指回本体;课程本体如果指向学生,那学生无法指回课程;所以课程本体指向学生的虚记录,学生虚记录指向学生本体。


网状数据模型

2.1 基本概念

与层次数据模型类似,在网状数据模型中,也是以记录作为数据的存储单位。但是不同的是,在网状数据模型中,字段这个名词变成了数据项,并且在层次数据模型中,字段是最小单位不可再分的,可是数据项是可以再分的,我们把可以再分的数据项叫做多值数据项,如例子所示:

学生名学号班级年龄生日地址
baka爱159年一班152000.1.25{(酒店),(饭店)}

在地址这个数据项中,其对应了一个多值集合。这也侧面说明了多值数据项可以用有序的集合表示,简单的多值数据项我们也叫做向量。 ​ 作为记录,其在数据结构中还有对应的地址;如果想要查找某一条记录,只需要查对应地址即可,每个记录有一个唯一地标识他的数据库码(DataBase Key,DBK)。DBK可以看成记录的逻辑地址,可做记录的替身或用来寻找记录。 那么如何表达两团数据之间的联系呢?比如两团数据一个是班级的数据一个是学生的数据,那么两团数据的联系由什么表示呢?这就要提到系(set)的概念了。 ​ 假如在班和学生两团数据中,一个班对应多个学生,那么我们叫把班级-学生的系叫做它们之间的联系。在这里例子中,班为1而学生为n,则我们把1的一方叫做首记录,把N的一方叫做属记录。 ​ 需要注意的是,在一个系的属记录中,有时会包含多种类型的属记录,例如班级-学生这个系中,学生可以再分,分为男学生和女学生,那么此时我们把拥有多种类型属记录的系,叫做多属系。 ​ 或者再举一个例子:一个银行账户可以作为首记录,而属记录是这个账户的一笔笔的账,这些账可以是存款的、提款的或转账的,他们分属于不同的记录型。 ​ 实际上,多属性可以拆分为多个系,比如班级-学生这个系可以拆分为班级-男学生班级-女学生,但是分开多个系你要来回在不同的系找人不方便,所以对于多属系来说,其优点是查找方便。

2.2 联系记录

在层次数据模型中,我们有说到虚记录,在网状数据模型中,我们不需要考虑虚记录,因为他并没有PCR关系,就拿下面这个例子来说:

数据模型6.png

班和学生构成一个系,运动队和学生构成一个系,学生既是“班-学生”的属记录,也是“运动队-学生”的属记录,无须用PCR复制,无须用指针创建虚记录。 结果上面的例子我们可以总结出以下的道理:

  • 一个记录型可以作为几个系的首记录,也可以作为几个系的属记录。
  • 一个记录型可以作为一个系的首记录,也可以作为另一个系的属记录。
  • 但是!一个记录型不能做一个系的首记录,又做这个系的属记录。

第一小点和第二小点可以用一个例子:“班级-学生”,“家庭-学生”和“学生-选课”这三个系中,学生作为中转站,他可以做多个系的属纪录,也可以做另外多个系的主记录。第三小点也不难理解:在“班级-学生”这个系中,你不能说学生又是属记录又是主记录。 ​ 上面的道理中,第三点显然不符合现实。为什么这么说?举个例子: ​ 职员和领导,职员是领导的下属,但是领导也是职员,也就是说在领导也在职员记录型里面,这显然是不符合要求的。但是现有的知 识中没能解决这个问题,所以网状数据模型引入了联系记录(link 记录)这个概念。 ​ 联系记录干了这么一件事情:拿职员和领导的关系来说,我们中间引入一个link变量,来接收职员的箭头,再把箭头指向领导。

数据模型7.png

上面这样表示的意思是:一个领导下管理多个职员,但是职员中也有领导。这样看可能看不出什么,但是这样看呢?

关系数据库语言8.png

在上面,我们谈论的班级-学生,其对应的是一团班级(可以理解为班级表)和一团学生(可以理解为学生表),所以实际上我们说的系是系型,而具体的某个学生,某个班级,就是系值,也就是我们说的记录,只是体现在系的层面上换了个名字。需要注意的是,一个记录值不能出现在同一类型的多个系值当中,打个比方就是学生表里面不能有两条一模一样的记录。

联系记录的另外一个用法是:由于一个记录值不能出现同一系型的多个系值中,所以比如说学生-课程这个系,课程里面有一门数据结构,它同时被两个人选,但是它的记录不能出现在这个系型里面两次,所以可以用联系记录做如下表示:

数据模型9.png

从看到上图我们可以知道,为了避免课4被两个学生用同一个记录,所以我们将每个课和link挂钩,用两个link来当课4的中转站。这样相当于是层次数据模型中的多元关系。

2.3 结构

谈完上面的知识,我们又要说说网状数据模型的结构。在层次结构中我们用来表示其结构,但是在网状数据模型中我们用的是链表来实现,如图所示:

在这里要提到一个,链表用指针串联也是有讲究的,我们一般分为三类:前向指针后向指针首记录指针,其中前向指针是必备的。

指针说明
前向指针就是依次从根开始,依次指向“下”一个记录
后向指针和前向指针相反
首记录指针属记录指向首记录
2.2.4 单值系和无首系

实际上,两个名词指的是同一个东西,这种系通常没有首记录,所以叫无首系,或者具体点说,一个单位里面有很多部门,但是单位只有一个,我们可以直接省略,所以无首系又叫做单值系。

再比如“班级-学生”,班级有很多个,我们不能说“班级-学生”是单值系,但是“学校-班级”中的学校只有一个,总而言之,单值系和无首系都是相对的,要视具体问题来看。