Live软件开发面面谈——数据库

第5章  数据库

数据库是为了存储和查询大量现实的或虚拟的数据而建立的软件系统。为此首先要将形形色色的数据对象抽象成统一的模型。使用最广泛的是实体-关系(Entity-Relationship)模型,实体对应的就是日常所说的物体、对象,关系则刻画它们之间的联系。数据库必须以某种形式表达实体和关系,并实现对其的存储和查询。选用不同的形式和相应的理念,就构成数据库不同的模型。长期以来,关系型数据库以其成熟的理论和实现、诸多优良的特性,几乎是数据库的代名词。然而从2000年代末开始,NoSQL成了数据库领域的热词。这个对关系型数据库一统江山的局势构成挑战的大家族,八仙过海,各显神通。按数据模型,主要可以分为以下几种:

  1. 文档型:MongoDB、Apache CouchDB、Couchbase、Lotus Notes
  2. 宽列型:Cassandra、HBase、BigTable
  3. 键值型:Redis、Couchbase【注:Couchbase的设计同时包含文档和键值】、MemcacheDB
  4. 图型:MarkLogic、Neo4J

以上列表当然没有穷尽NoSQL数据库,之所以选择它们,或是因为市场占有率较高,或是因为出自Google、Facebook这样的互联 巨头。这其中最成功的是文档型数据库MongoDB,根据DB-Engines按照数据库流行程度的排名,MongoDB自2014年来就稳居前五名(2017年伊始,又爬升到了第四名),而其他四名都是历史悠久的关系型数据库Oracle、MySQL、Microsoft SQL Server和PostgreSQL。MongoDB成功进入被关系型数据库垄断的第一阵营,在占有率上被它们远远甩在后面的其他竞争者中,若只比较NoSQL,另两种文档型数据库Apache CouchDB和Couchbase也名列前茅。

随着这股潮流出现的便是一系列关于文档型数据库的问题:文档型数据库有何优点和关系型数据库有哪些差别些差别会怎样影响到使用它们的应用程序系型数据库会式微吗章就将从数据库的根本出发,全面分析和比较两类数据库的理念和设计,通过这些分析不仅能回答以上问题,还可以对抽象的数据库理论有更透彻的理解。

5.1  多值与复合属性

关系型数据库用来代表实体和关系的形式之单元是记录,文档型数据库的单元是文档。记录依托的是关系代数中的关系概念,通常被描述成表格中的行那样的一维结构。【注:为了更具体和有针对性,以后的讨论都使用关系型数据库的术语(如表、记录),而不是用关系代数的对应术语(如关系、元组)。】文档则可以容纳集合的和层次的数据,就像通用的文档格式XML和JSON做的那样。将一个实体保存到关系型数据库中时,常常要将它拆成多条记录,记录之间以外键联系。反观用文档型数据库保存实体时,经常用一个文档就能对应一个实体。探究造成此差别的因素,结构上的原因正是关系型数据库中字段值一般是简单的、单值的,而能够容纳多值和复合属性是文档型数据库的标志之一(冗余和效率等其他影响设计的因素以后也会被论及)。关系型数据库真的不能采用多值和复合数据类型吗果不是,为什么长久以来遵循这样的原则种数据库模型在处理属性上的差异值得详细讨论。

实体被映射成记录,用于描述实体的属性对应记录的字段(列)。实体之间的关系依照其间的映射基数(Mapping cardinalities)即一对一、一对多和多对多的种类分别用实体记录的字段或专门的记录来表达。源于其背后的关系代数,关系型数据库在建模刻画数据时,表现出数学的严格性——所有要被建模的数据都被包含,并且尽量减少数据的冗余——一分不多,一分不少。前者很好理解,后者则是为了两个目的。一是减少冗余数据所导致的存储空间浪费。二是避免重复可能带来的数据不一致。冗余意味着同样的数据出现在两个或更多的地方,当这些数据被更新时就必须在它们所在的每一处进行,这就导致复杂性和成本增加,并且可能因为某一处更新失败令数据处于不一致的状态。为了实现上述建模的目标,主要是减少冗余,关系型数据库的设计引入了一系列的范式。改变表的模式以使其符合某个范式的过程称为正规化(Normalization)。我们以常用的前两个范式为例来分析它们的意涵和影响。

5.1.1  关系型数据库模式的第一和第二范式

函数依赖(Functional dependency)是用来分析关系型数据冗余和约束的理论工具。函数依赖的思想很简单,为了简便,下面不采用其严格的定义,而只是用普通的语言讨论其内涵。我们常常会看到一个表中若干字段的数据像凝固成一个整体一样,以可操作的语言描述,就是某些字段的值决定了另一些字段的值。这里决定的意思是对于任意一条记录,前者取一定值时,后者必然取一个确定的值,也就是说不可能出现两条记录,其中前者字段的值相同时,后者字段的值却不同。用数学的语言可以说后者字段的取值是前者字段取值的单值函数。我们不妨把前者字段称为被依赖字段,后者字段称为依赖字段。被依赖字段可以是单个,也可以是一个集合;单个时函数依赖现象很明显,集合时就不那么直观。例如下面的表5.1由a、b、c、d四个字段组成,d字段的值依赖于a、c字段的集合;b字段则不然。

表5.1  一个含有函数依赖字段的表

a

b

c

d

0

0

0

0

1

0

0

2

0

0

1

1

1

1

0

2

很显然被依赖字段集合本身及其任何子集都依赖于该集合。假如一个表的所有字段组成的集合依赖于其某个子集,该子集就能被用于唯一确定(Identify)表中任何一条记录(当然前提是,表中的记录组成一个集合,不存在两条完全相同的记录),即任意两条记录在该字段子集上的值都不完全相同。这样的字段子集依照其作用就被称为表的超键(Superkey,或译为超码)。之所以称为超键,是沿用集合论的术语,集合a是集合b的子集,则称集合b是集合a的超集,显然任何包括一个超键的更大的字段子集也能唯一确定表中任何一条记录。一个超键,如果再也不能减少字段,就被称为表的候选键(Candidate key)。候选键中被表的设计者选来区分记录的键被称为主键(Primary key)。一个表中包含的其他表的主键称为外键(Foreign key),主要用来维持表之间的关系。以后示例表中主键所在的列名称用大写字母标示。

假如一个字段集合只决定所属表的另一个字段子集,而不是所有字段,也就是说不是表的超键,那些依赖字段集合的数据就形成冗余,因为两条记录的被依赖字段值如果相同,依赖字段的值就必然重复。如表5.2所示,a字段是表的主键,c、d字段依赖于b,但b不是表的超键,c、d字段的数据就有冗余。

表5.2  一个由函数依赖导致数据冗余的表

A

b

c

d

1

0

橘子

黄色

2

1

苹果

红色

3

0

橘子

黄色

4

1

苹果

红色

为了消除这种冗余,关系型数据库有第二范式(Boyce–Codd范式),它要求对于表中的所有函数依赖,要么被依赖字段是表的主键,要么依赖字段是被依赖字段的子集。容易看出,类似上面例子中的那种函数依赖不符合这两点要求,因而要被排除掉。排除的方法就是把表的字段拆为两部分,一部分是被依赖字段和依赖字段的并集,另一部分则是表的字段全集除去依赖字段对被依赖字段的差集。这种方法对具体的例子很直观,上面的表就会被拆成以下两个表5.3和5.4:

表5.3  由表5.2的字段全集除去依赖字段对被依赖字段的差集得到的表

A

b

1

0

2

1

3

0

4

1

表5.4  表5.2被依赖字段和依赖字段的并集组成的表

B

c

d

0

橘子

黄色

1

苹果

红色

现在我们再回头看关系型数据库模式的第一范式。实体的某个属性所能取的值的集合称为该属性的域(Domain),如果该域中的元素都是不可分的,我们就说这个域是原子的【注:Atomic原子这个术语作为不可分的代名词,自从古希腊哲学家德谟克里特提出原子概念后,不仅在现代物理中被用来指称如今我们都知道的组成物质的粒子,而且在其他诸多科学领域中都被使用,例如这里的原子域以及后面将讨论的数据库交易的原子性。】第一范式要求表所有字段的域都是原子的。属性值之不可分,用其反面的可分能更好地界定。一个属性值可分,有两种情况。第一种是属性值由多个值组成,这种属性称为多值属性,与其相对的称为单值属性。第二种是属性值像实体一样由若干成分属性组成,这种属性称为复合属性,每个成分属性本身又可能是复合属性,从而形成多层次的结构;与其相对的则是简单属性。

将实体映射为符合第一范式的表时,简单的单值属性直接对应一个字段;复合属性被拆分直至简单属性,这些成分属性如果是单值的就用一个字段表示;多值属性被映射为一个新的表,每个值转化为一条记录,字段除了容纳值本身所需的以外,还包括一个或多个字段容纳该属性所属实体对应的记录的主键。我们分别来看这两种额外工作的意义。

5.1.2  范式与复合、多值属性
5.1.3  关系型数据库中的多值和复杂数据类型
5.2  数据库模式
5.3  数据建模
5.3.1  抽象的数据建模
5.3.2  针对具体数据库的建模
5.4  视图
5.4.1  索引
5.4.2  关系型数据库中的视图
5.4.3  文档型数据库中的视图
5.5  可伸缩性
5.6  可得性与BASE
5.7  编程接口
5.8  总结

更多内容,请参看拙著:

《Live软件开发面面谈》(京东)

《Live软件开发面面谈》(当当)

《Live软件开发面面谈》(天猫)

文章知识点与官方知识档案匹配,可进一步学习相关知识MySQL入门技能树数据库组成视图31416 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年8月4日
下一篇 2018年8月5日

相关推荐