数据库如何在内部工作? [关闭]

Posted

技术标签:

【中文标题】数据库如何在内部工作? [关闭]【英文标题】:How do databases work internally? [closed] 【发布时间】:2010-09-15 10:25:25 【问题描述】:

过去几年我一直在使用数据库,我想我已经相当有能力使用它们了。但是,我最近在阅读有关 Joel 的 Law of Leaky Abstractions 的信息,我意识到即使我可以编写查询来从数据库中获取几乎任何我想要的东西,但我不知道数据库实际上是如何解释查询的。有谁知道任何解释数据库内部工作原理的好文章或书籍?

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

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

【问题讨论】:

如果是 SQL 服务器,我强烈推荐 Inside Microsoft SQL Server 2005 系列(微软出版社),尤其​​是存储引擎和查询。它回答了你所有的问题等等。您可能对其中一些博客感兴趣:Craig FreedmanKalen Delaney 也值得订阅SQLServerCentral.. 试试这个db.cs.berkeley.edu/papers/fntdb07-architecture.pdf 和***。这是一个有点庞大的主题和模型,如 RDBMS、FLATFILE 等。解析器确实是最重要的组件之一。谢谢 截至 2015 年,有一个 this article 看起来不错。 数据库内部架构复杂THIS ARTICLE详细解释mysql服务器和存储引擎的工作原理。 【参考方案1】:

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

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

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

这会减少应用表达式的候选记录的数量,否则它只会执行我们所说的“表扫描”,即读取每一行。

但从根本上说,它定位候选记录的方式与其应用实际过滤器表达式的方式是分开的,而且显然可以进行一些巧妙的优化。

数据库如何解释连接 与多个查询不同 "where key1 = key2" 语句?

好吧,连接用于创建一个新的“伪表”,并在其上应用过滤器。因此,您有过滤条件和连接条件。连接条件用于构建此“伪表”,然后对其应用过滤器。现在,在解释连接时,这又是与过滤器相同的问题——暴力比较和索引读取以构建“伪表”的子集。

数据库如何存储它所有的 内存?

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

索引是如何存储的?

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

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

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

【讨论】:

我只想说这是一个非常有趣和有用的答案。你有没有在任何地方写过关于这个主题的更详细的文章? 这是帮助我弄清楚数据库的实际工作原理 “那么数据库将(可能但不一定)首先使用索引来定位候选记录以应用实际过滤器”在什么情况下,如果可用,则不使用索引,为什么? @SatyendraKumar 它取决于各种各样的事情,但最终如果优化器(基于统计数据等)决定从索引查询的结果将是行的很大一部分对于表,忽略索引和表扫描会更便宜。索引涉及大量随机 I/O,这是有代价的。最终,这个成本比仅仅扫描表格要高。管理这样的事情只是数据库调整和查询优化过程的一个方面。【参考方案2】:

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

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

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

数据库如何存储它所有的内存?

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

索引是如何存储的?

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

这应该在***上更详细地解释..

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

Saif,很好的链接。涵盖大多数主题的鸟瞰概览,并提供有关特定供应商实施的详细信息。

我尝试写了三遍解释,但这确实是一个太大的话题。查看 Hellerstein 文章(Saif 链接到的伯克利服务器上的文章),然后询问具体情况。

值得注意的是,在任何给定的 DBMS 中都只实现了“已知的好想法”的一个子集。例如,SQLite 甚至不做散列连接,它只做嵌套循环(ack!!)。但是,它是一个易于嵌入的 dbms,而且它的工作非常好,所以它不那么复杂也有话要说。

了解 DBMS 如何收集统计信息以及它如何使用它们来构建查询计划,以及首先学习如何阅读查询计划,是一项非常宝贵的技能——如果您必须选择一个“数据库内部结构” “学习的话题,学习这个。它会带来不同的世界(而且你永远不会再不小心写出笛卡尔积...... ;-))。

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于数据库如何在内部工作? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Android 推送通知关闭:它是如何在内部工作的?

数据库提交如何在内部工作

SignalR 如何在内部工作?

如何在内部保存数据?

如何在内部保存我的数据?

PHP PDO 如何在内部工作?