当前位置:Gxlcms > mysql > 【连载】关系型数据库是如何工作的?(4)

【连载】关系型数据库是如何工作的?(4)

时间:2021-07-01 10:21:17 帮助过:52人阅读

在我们理解了隐藏在时间复杂度和排序后面的思想之后,我必须再谈谈3种数据结构了。它们极其重要,因为它们是现代数据库的基石。我也会顺便介绍下索引的概念。 数组 二维数组是最简单的数据结构,一张数据库表就可以看做一个二维数组,例如: 二维数组就是一

在我们理解了隐藏在时间复杂度和排序后面的思想之后,我必须再谈谈3种数据结构了。它们极其重要,因为它们是现代数据库的基石。我也会顺便介绍下索引的概念。

数组

二维数组是最简单的数据结构,一张数据库表就可以看做一个二维数组,例如:

数组

二维数组就是一个既有行又有列的表:

  • 一行就表示一个主题(记录)
  • 一列就是描述主题(记录)的一个特性
  • 每一列存储同一个类型的数据(integer, string, date …)

虽然表能很好的存储并展示数据,但是当你需要搜索数据时,它的表现就很糟糕了。

例如,如果你要找到所有的英国朋友,你就必须查看每一行数据,然后判断他/她是否是英国人。这会耗用N个操作(N表示行的数量),虽然看起来也并没有多糟糕,可是让我们想想,有没有更好的方法呢?答案就是树。

注意,大部分现代数据库都会提供高级数组便于更高效的存储表,比如:基于堆、基于索引。但这样,也并没有解决在特定条件下快速搜索的难题。

树和数据库索引

一个二叉搜索树就是一个具有特定属性的二叉树,每个节点都满足下列属性:

  • 大于所有左侧子树的节点值
  • 小于所有右侧子树的节点值

让我们用图来更直观的说明二叉搜索树:

二叉搜索树

上图中的树包含15个节点,让我们来搜索值为208的节点:

  • 我从根节点136开始,发现126<208,因此我们查看根节点136右侧子树;
  • 398>208,因此继续查看398节点的左侧子树;
  • 250>208,因此继续查看250节点的左侧子树;
  • 200<208,因此继续查看200节点的左侧子树,但发现200节点没有左侧子树,因此说明值为208的节点不存在。

让我们换一个值来搜索,比如40:

  • 我从根节点136开始,发现136>40,因此我们查看根节点136左侧子树;
  • 80>40,因此继续查看80节点的左侧子树;
  • 40=40,节点存在。如果每个节点中包含了rowid,那么我们就可以查找表中指定的rowid;
  • 实际上,我们一旦知道rowid就可以精确的定位这一行数据在表中的位置,这样我就能立即获取这一行数据。

最终搜索耗费的操作就是树的高度。如果你认真的阅读了之前关于归并排序的章节,你应该能够推断实际操作数就是log(N),不错的效果咯!

回到问题

上边我们描述的都是节点值是整数的简单场景,那么如果我们的节点值不是整数怎么办呢?想想一下上表中的每个人的国籍,都是字符串类型。假设你有一个值为国籍的树:

  • 如果你想查找所有UK国籍的人;
  • 你可以查找树,找到值为UK的节点;
  • 在UK节点,然后你就可以在节点中获取国籍为UK的这一行的位置(rowid);

整个搜索过程耗费了log(N)次操作,而不是使用数组时的N次。上边的过程,实际就是通过数据库索引查找指定行的过程。

一旦拥有比较列值的函数,你就可以对任何类型的列进行排序,同时意味着你可以构造一棵索引树。(译者注:关键是能够比较列值,否则没法排序

下一章节我们继续介绍非常非常非常(译者注:重要的事情说三遍)重要的B+Tree索引。

人气教程排行