本文翻译自Coding-Geek文章:《 How does a relational database work》。

原文链接:http://coding-geek.com/how-databases-work/#Buffer-Replacement_strategies

本文翻译了如下章节:

一、Merge Sort – 归并排序

当你需要对集合排序时,你怎么做? 什么? 你直接调用Sort()函数,…好,这是一个不错的方案。但是,对于数据库,你必须理解Sort()函数内部是如何工作的。

有很多好的排序算法,我们聚焦到最重要的一种:the merge sort。

你当前可能不理解排序的重要性,但是后面在读到查询优化章节时会理解这一点。此外,理解归并排序,也将有助于理解后面将讲到的一种数据库常用连接操作—归并连接。

二、Merge

就像许多其它有用的算法,归并排序是基于这样一种假设:将2组已经排序,大小是N/2的数据合并成在一起, 形成大小为N, 排序好的数组, 需要执行N步操作。 这些操作被称为merge。

让我们用一个简单的样例演示一下merge的过程:



从图中可以看到,构建出最终排好序有8个元素的数组,只需要遍历一次2组有4个元素的数组。因为,这两组元素都是已排好序的:

  1. 比较两个数组中的数据。从第一个元素开始比较。
  2. 将较小的数据放到排序结果数组中。
  3. 比较刚拿走数据的数组中的下一个元素。
  4. 重复1~3步,直到某个数组中的数据已拿完。
  5. 将另一个数组中剩余的元素放到排序结果数组中。

以上排序流程能正常执行,是因为参与排序的两个数组是有序的。在遍历数组的时候不需要往前“go back”。

现在,大家已经理解 Merge Sort的原理了。下面是它的伪代码:

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. 排序阶段:使用合并的方法将小的数组合并成更大的数组。

(一)Division phase – 分割阶段

在分割阶段,数组将通过3个步骤分割为更小的数组单元。用数学公式表示操作步骤数量是 log(N), N是数组中的元素数量。例如N=8,那么 log(N) = 3。

我是怎么知道的呢?

我是一个天才!哦,不…。 一句话:算法决定。其思路是每一步分割操作将原始的数组拆分为两份,操作步骤的数量就是你能将数组分割为两组数据的次数。这也是这个算法的准确定义。

(二)Sorting phase – 排序阶段

在排序阶段,你先从最小的单个数组开始排序合并。每一步,你将使用多次合并操作,总共合并次数为N=8:

  1. 第一步合并,先得到4组合并后的数组。每组合并使用2次操作。
  2. 第二步合并,得到2组合并后的数组。每组合并使用4次操作。
  3. 第三步合并将得到一组合并后的数组,使用8次操作。

由于执行了log(N)步,所以总的操作数是 N*log(N)。

(三)The power of merge sort – 归并排序的威力

为什么该算法如此有用?因为:

  1. 你能对算法做修改以减少内存空间的占用。换句话说,你不需要创建新的数组,直接修改原数组就可以实现排序。

    备注:这种算法叫原地排序,通过调整数组中元素的位置,通过元素位置交换实现排序)。

  2. 你能对算法做修改以使用磁盘空间做数据排序,只使用很少量的内存,也不会给I/O带来大的负担。其思路是每次只加载正在排序比较的数据到内存,排序后的数据写到磁盘保存。这点非常重要,当你需要对1G数据的表做排序,而你的内存只有100M时。

    备注:这种算法叫外部排序。借助磁盘和内存数据交换,用有限的内存实现大数据的排序)。

  3. 你可以把算法修改为支持多线程、多进程、多服务器。

    例如:分布式的 merge sort是hadoop的关键组件(hadoop是一个大数据框架)。

  4. 这个算法能产生真金白银(绝对的实话)。

Merge sort在大多数数据库中使用(不是所有数据库),但还有一些其它的排序算法也在使用。 如果你想了解更多,可以阅读一下相关的研究论文,它们分析了不同数据库排序算法的优劣势。

已翻译的《How does a relational database work》其它章节链接:

1. 关系型数据库工作原理-时间复杂度:http://blog.csdn.net/ylforever/article/details/51205332

2. 关系型数据库工作原理-归并排序:http://blog.csdn.net/ylforever/article/details/51216916

3. 关系型数据库工作原理-数据结构:http://blog.csdn.net/ylforever/article/details/51278954

4. 关系型数据库工作原理-高速缓存:http://blog.csdn.net/ylforever/article/details/50990121

5. 关系型数据库工作原理-事务管理(一):http://blog.csdn.net/ylforever/article/details/51048945

6. 关系型数据库工作原理-事务管理(二):http://blog.csdn.net/ylforever/article/details/51082294

关系型数据库工作原理-归并排序(翻译自Coding-Geek文章)的更多相关文章

  1. 关系型数据库工作原理-时间复杂度(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  2. 关系型数据库工作原理-高速缓存(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  3. 关系型数据库工作原理-数据结构(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  4. 关系型数据库工作原理-事务管理(二)(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  5. 关系型数据库工作原理-事务管理(一)(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  6. 关系型数据库工作原理-快速缓存(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  7. 关系型数据库工作原理-查询优化器(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>.原文链接:http://coding-geek.com/how-data ...

  8. 关系型数据库工作原理-查询优化器之数据访问方式(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>.原文链接:http://coding-geek.com/how-data ...

  9. 关系型数据库工作原理-查询优化器之索引(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>.原文链接:http://coding-geek.com/how-data ...

随机推荐

  1. 字符串相似度-C#

    之前在做一个任务时, 需要比较字符串的相似度, 最终整理了一个出来, 以下: 1 /* 2 * Copyright (c) 2013 Thyiad 3 * Author: Thyiad 4 * Cre ...

  2. 手把手教你树莓派实现简易室内监控系统(A)

    第一次写博文,有很多疏漏之处,然后受逼乎影响较深,希望大家多多包涵! _______________________________________________分割线是这样画的吧_________ ...

  3. MySQL主从复制_复制过滤

    关于主从过滤,建议只在从服务器做设定,在Master 端为保证二进制日志的完整, 不建议使用二进制日志过滤. Master 可用参数: binlog-do-db= #定义白名单,仅将制定数据库的相关操 ...

  4. Shell脚本的基本流程控制

    if else read -p '请输入分数:' score if [ $score -lt 60 ]; then echo '60分以下' elif  [ $score -lt 70 ]; then ...

  5. 业余草分享100套精选1000G架构师资料课程(超1T的IT学习资料免费送)

    业余草分享100套精选1000G架构师资料课程(超1T的IT学习资料免费送). 超过1024G的IT学习资料免费领取,你值得拥有! 领取资源方式,关注“业余草”公众号,回复对应的关键字 01.回复”我 ...

  6. nyoj737 石子合并(一) 区间DP

    dp[x][y]表示合并[x, y]区间的石子的最小花费,将区间长度递增枚举即可. AC代码: #include<cstdio> #include<algorithm> usi ...

  7. poj1011 && uva307 DFS + 剪枝

    将木棒从大到小排列,保证每次的选择都是最长可选的木棒. 剪枝: 1 . 如果第 i 根木棒被选择却无法成功拼接,那么后面与其长度相同的也不能选择. 2 . 如果第 cnt + 1 根木棒无法成功拼接, ...

  8. 从零开始学习前端JAVASCRIPT — 12、JavaScript面向对象编程

    一.构造函数的使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  9. 影响JavaScript应用可扩展性因素

    引言:JavaScript 应用变得越来越庞大.这是因为使用JavaScript能做的事情远比我们大多数人所需求的要多得多.我们不能仅因为技术上可行,就去考虑软件系统的扩展问题.为一个不需要扩展的系统 ...

  10. FMECA分析

    FMECA是针对产品所有可能的故障,并根据对故障模式的分析,确定每种故障模式对产品工作的影响,找出单点故障,并按故障模式的严重度及其发生概率确定其危害性.所谓单点故障指的是引起产品故障的,且没有冗余或 ...