在过去的几年中,我一直在使用数据库,我想我在使用它们方面已经相当胜任。但是,我最近在阅读有关乔尔泄漏抽象定律的信息,我意识到,即使我可以编写查询从数据库中获取几乎所有我想要的东西,但我也不知道数据库实际上是如何解释查询的。有谁知道解释数据库内部工作方式的好文章或书籍?
我感兴趣的一些特定事物是:
- 数据库实际上要做什么才能找出与select语句匹配的内容?
- 数据库如何用几个“ where key1 = key2”语句对查询的联接进行不同的解释?
- 数据库如何存储其所有内存?
- 索引如何存储?
在过去的几年中,我一直在使用数据库,我想我在使用它们方面已经相当胜任。但是,我最近在阅读有关乔尔泄漏抽象定律的信息,我意识到,即使我可以编写查询从数据库中获取几乎所有我想要的东西,但我也不知道数据库实际上是如何解释查询的。有谁知道解释数据库内部工作方式的好文章或书籍?
我感兴趣的一些特定事物是:
Answers:
数据库实际上要做什么才能找出与select语句匹配的内容?
直言不讳,这只是蛮力问题。简单来说,它会读取数据库中的每个候选记录,并将表达式与字段进行匹配。因此,如果您具有“从name ='fred'的表中选择*”,它将逐字遍历每条记录,获取“ name”字段,然后将其与“ fred”进行比较。
现在,如果对“ table.name”字段建立了索引,则数据库将(可能但不一定)首先使用索引来定位候选记录以将实际过滤器应用于该记录。
这减少了将表达式应用到的候选记录的数量,否则它将执行我们所谓的“表扫描”,即读取每一行。
但是从根本上讲,无论如何,它定位候选记录的方式都与应用实际过滤器表达式的方式不同,并且显然可以进行一些巧妙的优化。
数据库如何用几个“ where key1 = key2”语句对查询的联接进行不同的解释?
好吧,联接用于创建新的“伪表”,并在该伪表上应用过滤器。因此,您具有过滤条件和联接条件。连接条件用于构建此“伪表”,然后对此应用过滤器。现在,在解释联接时,它又是与过滤器相同的问题-蛮力比较和索引读取以构建“伪表”的子集。
数据库如何存储其所有内存?
好的数据库的关键之一是如何管理其I / O缓冲区。但是它基本上将RAM块与磁盘块匹配。使用现代的虚拟内存管理器,更简单的数据库几乎可以依赖VM作为其内存缓冲区管理器。高端数据库管理员自行完成所有这些操作。
索引如何存储?
通常B +树,您应该查找它。这是一种已经存在多年的简单技术。大多数平衡树都共享它的好处:对节点的一致访问以及所有叶节点都被链接在一起,因此您可以轻松地按键顺序在节点之间遍历。因此,有了索引,就可以将行视为数据库中特定字段的“排序”,并且数据库可以利用该信息来使其受益于优化。例如,这与为索引使用哈希表不同,后者仅使您可以快速访问特定记录。在B树中,您不仅可以快速获取特定记录,还可以快速获取已排序列表中的某个点。
在数据库中存储和索引行的实际机制非常简单明了,并且很容易理解。游戏正在管理缓冲区,并将SQL转换为有效的查询路径,以利用这些基本存储习惯。
然后,在存储习惯之外,整个多用户,锁定,日志记录和事务变得复杂。
数据库实际上要做什么才能找出与select语句匹配的内容?
数据库正在使用索引(请参见下文)
数据库如何用几个“ where key1 = key2”语句对查询的联接进行不同的解释?通过合并树,可以将Join Operations转换为二叉树操作。
数据库如何存储其所有内存?
内存映射文件可更快地访问其数据
索引如何存储?
在内部,DB正在使用B树进行索引。
这应该在维基百科上有更详细的解释。
Saif,绝佳链接。概览概述,涵盖了大多数主题,并提供了有关特定供应商实施的详细信息。
我做了三遍尝试写一个解释,但这确实是一个太大的话题。查看Hellerstein的文章(Saif链接到的berkeley服务器上的文章),然后询问细节。
值得注意的是,在任何给定的DBMS中仅实现了一部分“已知的好主意”。例如,SQLite甚至不执行哈希联接,而仅执行嵌套循环(ack !!)。但是,这是一个易于嵌入的dbms,并且运行良好,因此,由于缺乏复杂性而不得不说。
了解DBMS如何收集统计信息以及如何使用它来构建查询计划,以及首先学习如何阅读查询计划,是一项非常宝贵的技能-如果您必须选择一个“数据库内部”主题来学习,学习这个。这将带来巨大的变化(并且您将永远不会再无意间写出笛卡尔积... ;-))。
如果您想了解更多详细信息,我建议您获取sqlite来源并查看其工作方式。它是完整的,尽管还没有更大的开源和商业数据库的规模。如果您想了解更多详细信息,我建议您使用《 SQLite权威指南》,它不仅对sqlite做出了很好的解释,而且还是我所知道的最易读的技术书籍之一。在MySQL方面,您可以从MySQL Performance Blog以及书本中学习O'Reilly高性能MySQL(V2),该博客是其中的作者之一。