数据库如何在内部工作?

时间:2008-10-06 00:47:22

标签: database reference internals

我过去几年一直在使用数据库,我想我已经相当有能力使用它们了。然而我最近在阅读Joel的 Law of Leaky Abstractions并且我意识到即使我可以编写一个查询来获取我想要的任何数据库,我也不知道数据库如何实际解释查询。有没有人知道任何解释数据库如何在内部工作的好文章或书籍?

我感兴趣的一些具体事情是:

  • 数据库实际上做了什么来找出与select语句匹配的内容?
  • 数据库如何解释连接与具有多个“where key1 = key2”语句的查询不同?
  • 数据库如何存储所有内存?
  • 如何存储索引?

5 个答案:

答案 0 :(得分:78)

  

数据库实际上做了什么   找出与选择匹配的内容   声明?

说实话,这是一个蛮力的问题。简单地说,它读取数据库中的每个候选记录并将表达式与字段匹配。所以,如果你有“select * from table where name ='fred'”,它会逐字遍历每条记录,抓住“name”字段,并将其与'fred'进行比较。

现在,如果“table.name”字段被编入索引,那么数据库将(可能但不一定)首先使用索引来定位候选记录以应用实际过滤器。

这减少了应用表达式的候选记录的数量,否则它将只执行我们称之为“表扫描”的操作,即读取每一行。

但从根本上说,它定位候选记录与它应用实际过滤器表达式的方式是分开的,显然,可以做一些聪明的优化。

  

数据库如何解释连接   与具有多个查询的查询不同   “其中key1 = key2”语句?

好吧,连接用于创建一个新的“伪表”,应用过滤器。因此,您有过滤条件和连接条件。连接标准用于构建此“伪表”,然后对其应用过滤器。现在,在解释连接时,它再次与过滤器相同 - 强制比较和索引读取以构建“伪表”的子集。

  

数据库如何存储它的全部内容   存储器?

良好数据库的关键之一是它如何管理其I / O缓冲区。但它基本上将RAM块与磁盘块匹配。使用现代虚拟内存管理器,更简单的数据库几乎可以依赖VM作为其内存缓冲管理器。高端DB'自己完成这一切。

  

如何存储索引?

B +树通常,您应该查找它。这是一种已经存在多年的直接技术。它的好处是与大多数平衡树共享:对节点的一致访问以及所有叶节点都是链接的,因此您可以按键顺序轻松地从一个节点遍历到另一个节点。因此,使用索引,可以将行视为对数据库中的特定字段进行“排序”,并且数据库可以利用该信息使其有利于优化。这与使用索引的哈希表不同,后者只允许您快速访问特定记录。在B树中,您不仅可以快速获取特定记录,还可以快速获取排序列表中的某个点。

在数据库中存储和索引行的实际机制非常简单且易于理解。游戏是管理缓冲区,并将SQL转换为有效的查询路径,以利用这些基本的存储习惯用法。

然后,在存储习惯用语之上存在整个多用户,锁定,日志记录和事务复杂性。

答案 1 :(得分:4)

  • 数据库实际上做了什么来找出与select语句匹配的内容?

    数据库正在使用索引(见下文)

  • 数据库如何解释连接与具有多个“where key1 = key2”语句的查询不同? 通过合并树,可以将Join Operations转换为二叉树操作。

  • 数据库如何存储所有内存?

    内存映射文件,以便更快地访问其数据

  • 如何存储索引?

    内部数据库正在使用 B-Trees 进行索引。

这应该在维基百科上更详细地解释..

http://en.wikipedia.org/wiki/B-tree

http://en.wikipedia.org/wiki/Database

答案 2 :(得分:1)

除了阅读之外,使用数据库工具检查数据库在查询中使用的执行计划也很有帮助。除了深入了解它是如何工作之外,您还可以尝试使用更好的反馈循环来优化查询的技术。

答案 3 :(得分:0)

赛义夫,优秀的链接。鸟瞰概述,涵盖大多数主题,并提供有关特定供应商实施的详细信息。

我在写一个解释时做了三次尝试,但这实在是太大了。查看Hellerstein文章(Saif链接到的berkeley服务器上的文章),然后询问具体细节。

值得注意的是,在任何给定的DBMS中只实现了“已知好主意”的一部分。例如,SQLite甚至不进行散列连接,它只进行嵌套循环(ack !!)。但是,它是一个易于嵌入的dbms,并且它的工作非常好,所以可以说缺乏复杂性。

了解DBMS如何收集统计信息以及如何使用它们构建查询计划,以及学习如何首先阅读查询计划,这是一项非常宝贵的技能 - 如果您必须选择一个“数据库内部” “学习的主题,了解这一点。它将创造一个与众不同的世界(你永远不会意外地再写一个笛卡尔积......; - ))。

答案 4 :(得分:0)

如果您想更详细地了解,我建议您获取sqlite源代码,并了解它是如何做到的。它是完整的,尽管不是大型开源和商业数据库的规模。如果你想更详细地了解我的建议The Definitive Guide to SQLite,这不仅是对sqlite的一个很好的解释,也是我所知道的最易读的技术书籍之一。在MySQL方面,您可以从MySQL Performance Blog以及书中了解O'Reilly High Performance MySQL(V2),其中博客是作者之一。