数据库导论

数据库管理系统在日常生活中的应用非常广泛,用于管理计算机数据。随着当今时代数据爆炸性增长,数据库系统也日益成为计算机应用的核心部分。

数据库是由一组模拟生活中某些方面的数据组织成的集合,例如,模拟学生或者歌曲库。数据库管理系统就是用于管理数据库的软件。

为什么引入数据库管理系统呢?

简易设计

假设我们用文件来管理数据库中的数据,以歌手和他们发布的专辑信息为例,我们将分别为歌手和专辑建立CSV文件。

歌手.csv文件信息为

1
2
3
"Wu Tang Clan",1992,"USA"
"Notorious BIG",1992,"USA"
"Ice Cube",1989,"USA"

每行的信息分别为歌手名、出道年份、国家。

专辑.csv文件信息为

1
2
3
"Enter the Wu Tang","Wu Tang Clan",1993
"St.Ides Mix Tape","Wu Tang Clan",1994
"AmeriKKKa's Most Wanted","Ice Cube",1990

每行的信息分别为专辑名、歌手名、发布年份。

查询Ice Cube出道年份可用如下代码实现:

1
2
3
4
5
for line in file: 
record = parse(line)
if “Ice Cube” == record[0]:
print int(record[1])

但是这种通过文件来存储数据的方式存在不少问题

  • 数据完整性

    如何存储多个歌手的专辑信息?

    如何防止无效信息的写入?

  • 查询/更新实现

    如何查询特定的记录?

    如何实现基于同一数据库的应用?

    如何控制线程并发写入数据库?

  • 持久性

    如何在机器更新时确保信息正确?

    如何在多个设备之间同步?

基于以上考虑,我们引入了数据库管理系统,通过数据库管理系统来定义、创建、查询、更新数据库。

数据模型

接下来我们将通过数据模型来描述数据库中的数据。数据模型是数据库结构的基础。给定数据模型后,对特定数据集合的描述称为模式。

数据模型分为以下几类

  • 关系模型 用表的集合来表示数据和数据建的联系

  • 实体-联系模型 现实世界由一组称为实体的基本对象和这些对象之间的联系构成,实体-联系模型即用于描述这些数据。

  • 半结构数据模型

  • 网状数据模型

  • 层次数据模型

    其中网状数据模型和层次数据模型和底层实现很紧密,实现复杂,所以现在很少使用。数据库设计基本围绕关系模型展开。

关系模型

关系模型的核心在于

  1. 以简单的数据结构来存储数据(关系)
  2. 通过高级语言来操作数据
  3. 物理层存储取决于具体实现

关系模型主要由以下部分组成

  • 结构:关系的定义和结构内容,即关系对应的属性和这些属性中的值
  • 完整性:确保数据库内容满足约束,例如,所有的年份属性都应该是数字
  • 操作:如何访问和修改数据库的内容

一个关系即是一组代表实体的属性的无序序列。正因为关系无序,所以数据库管理系统可以任何方式存储关系。一个有$n$个属性的关系被称为$n$列关系。

一个元组是关系中一组属性的值,也就是关系中某一行。元组中的值通常是原子的,即不可再拆分。特殊的空值NULL是每个域的成员。

一个关系的主键区别了不同的元组。某些数据库管理系统在用户未定义主键时自行创建主键。

数据库操纵语言

数据库系统提供数据定义语言来定义数据库模式,以及数据库操纵语言来表达数据库的管理和更新。实际上,数据定义和数据操作语言并不是分离的,而是简单地构成了单一的数据库语言的不同部分。

数据库操作语言分为两类

  • 过程化数据库操纵语言 指明用户需要什么数据,以及怎么获取这些数据
  • 声明化数据库操纵语言 只要求用户指定需要什么数据,而不指明如何获取这些数据

关系代数

关系代数是一个运算的集合,以一个或两个关系为输入,以一个新的关系为结果。可通过嵌套来实现更复杂的操作。

关系基本运算有:选择、投影、并、集合交、集合并、集合差、笛卡尔积和重命名。

选择运算

选择运算选出满足给定谓词的元组。

  • 谓词过滤不符合条件的元组,仅留下满足谓词条件的元组
  • 可通过连词将多个谓词连接

投影运算

投影运算以某个关系为输入,输出仅含特定属性的元组的关系。

  • 可重新排列属性顺序
  • 可对属性的值操作

集合交

集合交以两个关系为输入,输出仅含在两个关系中均出现的元组的关系。

集合并

集合并以两个关系为输入,输出在两个关系中至少出现一次的元组的关系。

集合差

集合并以两个关系为输入,输出在第一个关系中出现而第二个关系中不出现的元组的关系。

连接运算

以两个关系为输入,生成一个关系,该关系中的元组是两个元组(每个输入关系中各选一个)的组合,并且具有一个或多个属性的公共值。

笛卡尔积

以两个关系为输入,输出所有可能的组合。

关系代数为过程化语言,因为关系代数定义了计算查询的步骤。

例如,若想查询R和S连接后满足b_id等于102的元组,

关系代数可以是先连接R,S,再选择其中b_id等于102的元组,或者先选择S中b_id等于102的元组,再与R连接。

更好的方式是声明想让数据库管理系统返回的元组,类似查询R和S连接后满足b_id等于102的元组。

关系代数定义了数据库查询的原语。

关系模型仅描述了高层次的操作,与具体实现语言无关。