关系型数据库是怎么工作的3:合并排序

作者:51ak

2.合并排序

当需要排序一个集合时,你该怎么做? 什么? 你调用 sort()方法…. 好吧,好答案…但是对一个数据库来说,你需要弄明白这个sort()方法是怎么工作的.

这里有几种不错的排序算法,所以我这里重点说说这个最重要的算法:合并排序 你可能现在还不明白为啥对数据进行排序这么重要,在这篇文章后面的章节<查询优化>中会交待。 此外,了解合并排序将有助于我们理解后面的一个常用数据库操作:join ,因为它调用了合并排序

2.1合并

像许多有用的算法一样,合并排序基于一个技巧:将2个大小为N/2的已排序数组合并为N个元素的排序数组仅需要N次操作。 此操作称为合并。

让我们通过一个简单的例子来说明:

合并排序

从上图上你可以看到,要想得到最终的已经排好序的8元素数组,你只需要迭代一次在两个有序的4元素数组中.

  1. 比较两个数组的第一个元素(这里要想象一下两个数组都有个游标)
  2. 然后把最小的那个数放到8元素数组的第一个位置上
  3. 接着把游标顺着移走的数移到下一个位置上 重复1,2,3 动作,直到到达两个数组其中一个的终点。 然后把另一个数组里剩下的元素都放到8元素结果集中 这个排序的前题是原始的4元素数组是已经排序过的,所以你不需要在数组中做”go back” 操作

现在我们已经明白了合并排序的技巧了,这是我写的合并排序的伪码

array mergeSort(array a)
   if(length(a)==1)
      return a[0];
   end if
 
   //recursive calls
   [left_array right_array] := split_into_2_equally_sized_arrays(a);
   array new_left_array := mergeSort(left_array);
   array new_right_array := mergeSort(right_array);
 
   //merging the 2 small ordered arrays into a big one
   array result := merge(new_left_array,new_right_array);
   return result;

合并排序把问题分解成更小的问题,然后这些通过解决小问题,得到初始问题的结果。(这种算法被称为:分而治之). 如果你不明白这种算法,不要着急,我一开始也不太明白,我们来尝试把这个算法拆成两阶段算法:

  1. 分隔阶段 把数组分隔成更小的数组
  2. 排序阶段 把小的数组合并到一起(用合并)成一个大数组

2.2分隔阶段

分隔阶段

在上图的例子中,整个分隔阶段,一共用了3个步骤把数组分隔了单一数组 ,计算步骤的公式是 log(N) (这里N=8,long(N)=3)

我是怎么知道这个公式的?

~~我是个天才! ~~ 认真的说,用一个词来概括: 数学. 每一步都将数组的大小除以2. 步骤数就是可以将初始数组除以2的次数.这是个很准确的定义(基于2分法).

2.3排序阶段

排序阶段

在排序阶段, 我们从单一数组开始. 在每一步, 你应用了多次合并,总的花费是N=8次操作:

这里共有log(N)个步骤,这个算法总共需要N*log(N)次操作

合并排序的能力

为什么合并排序如此给力

因为: - 你可以改进它以减少内存占用,通过某种方法,你不需要创建一个新数组而是直接修改原数组。

note:这种算法被称为:in-place(原位操作)

note:这种算法被称为:external sorting(外部排序)

合并算法被大多数(即使不是全部)数据库,但不是唯一的一个。如果你想了解更多,可以去读这篇讨论数据库各种排序算法优缺点的研究论文(http://wwwlgis.informatik.uni-kl.de/archiv/wwwdvs.informatik.uni-kl.de/courses/DBSREAL/SS2005/Vorlesungsunterlagen/Implementing_Sorting.pdf)

本节完成,下一章节我们将讨论:数组.树.哈希表

本篇文章完整分为7节,当前第3节。以下完整章节:

  1. 引言
  2. 时间复杂度
  3. 合并排序
  4. 数组.树.哈希表
  5. 客户端管理
  6. SQL查询
  7. 数据管理

发布日期:2017/09/11

Categories: 数据库理论 翻译 关系型数据库 mysql 排序 Tags: 转译 精品