我过去几年一直在使用数据库,我想我已经相当有能力使用它们了.然而,我最近在阅读Joel的Leaky Abstractions法则,我意识到即使我可以编写一个查询来获取我想要的任何数据库,我也不知道数据库是如何实际解释查询的.有没有人知道任何解释数据库如何在内部工作的好文章或书籍?
我感兴趣的一些具体事情是:
数据库实际上做了什么来找出与select语句匹配的内容?
数据库如何解释连接与具有多个"where key1 = key2"语句的查询不同?
数据库如何存储其所有内存?
索引是如何存储的?
Will Hartung.. 81
数据库实际上做了什么来找出与select语句匹配的内容?
说实话,这是一个蛮力的问题.简单地说,它读取数据库中的每个候选记录并将表达式与字段匹配.因此,如果你有"select*from table where name ='fred'",它会逐字遍历每条记录,抓取"name"字段,并将其与'fred'进行比较.
现在,如果"table.name"字段被索引,那么数据库将(可能但不一定)首先使用索引来定位候选记录以应用实际过滤器.
这减少了应用表达式的候选记录的数量,否则它将执行我们称之为"表扫描"的操作,即读取每一行.
但从根本上说,它定位候选记录与它应用实际过滤器表达式的方式是分开的,显然,可以做一些聪明的优化.
数据库如何解释连接与具有多个"where key1 = key2"语句的查询不同?
好吧,连接用于创建一个新的"伪表",应用过滤器.因此,您有过滤条件和连接条件.连接标准用于构建此"伪表",然后对其应用过滤器.现在,在解释连接时,它再次与过滤器相同 - 强制比较和索引读取以构建"伪表"的子集.
数据库如何存储其所有内存?
良好数据库的关键之一是它如何管理其I/O缓冲区.但它基本上将RAM块与磁盘块匹配.使用现代虚拟内存管理器,更简单的数据库几乎可以依赖VM作为其内存缓冲管理器.高端DB'自己做这一切.
索引是如何存储的?
通常B +树,你应该查找它.这是一种已经存在多年的直接技术.它的好处是与大多数平衡树共享:对节点的一致访问以及所有叶节点都是链接的,因此您可以按键顺序轻松地从一个节点遍历到另一个节点.因此,使用索引,可以将行视为对数据库中的特定字段进行"排序",并且数据库可以利用该信息使其有利于优化.这与使用索引的哈希表不同,后者只允许您快速访问特定记录.在B树中,您不仅可以快速获取特定记录,还可以快速获取排序列表中的某个点.
在数据库中存储和索引行的实际机制非常简单且易于理解.游戏正在管理缓冲区,并将SQL转换为高效的查询路径以利用这些基本的存储习惯用法.
然后,在存储习语之上存在整个多用户,锁定,日志记录和事务复杂性.
数据库实际上做了什么来找出与select语句匹配的内容?
说实话,这是一个蛮力的问题.简单地说,它读取数据库中的每个候选记录并将表达式与字段匹配.因此,如果你有"select*from table where name ='fred'",它会逐字遍历每条记录,抓取"name"字段,并将其与'fred'进行比较.
现在,如果"table.name"字段被索引,那么数据库将(可能但不一定)首先使用索引来定位候选记录以应用实际过滤器.
这减少了应用表达式的候选记录的数量,否则它将执行我们称之为"表扫描"的操作,即读取每一行.
但从根本上说,它定位候选记录与它应用实际过滤器表达式的方式是分开的,显然,可以做一些聪明的优化.
数据库如何解释连接与具有多个"where key1 = key2"语句的查询不同?
好吧,连接用于创建一个新的"伪表",应用过滤器.因此,您有过滤条件和连接条件.连接标准用于构建此"伪表",然后对其应用过滤器.现在,在解释连接时,它再次与过滤器相同 - 强制比较和索引读取以构建"伪表"的子集.
数据库如何存储其所有内存?
良好数据库的关键之一是它如何管理其I/O缓冲区.但它基本上将RAM块与磁盘块匹配.使用现代虚拟内存管理器,更简单的数据库几乎可以依赖VM作为其内存缓冲管理器.高端DB'自己做这一切.
索引是如何存储的?
通常B +树,你应该查找它.这是一种已经存在多年的直接技术.它的好处是与大多数平衡树共享:对节点的一致访问以及所有叶节点都是链接的,因此您可以按键顺序轻松地从一个节点遍历到另一个节点.因此,使用索引,可以将行视为对数据库中的特定字段进行"排序",并且数据库可以利用该信息使其有利于优化.这与使用索引的哈希表不同,后者只允许您快速访问特定记录.在B树中,您不仅可以快速获取特定记录,还可以快速获取排序列表中的某个点.
在数据库中存储和索引行的实际机制非常简单且易于理解.游戏正在管理缓冲区,并将SQL转换为高效的查询路径以利用这些基本的存储习惯用法.
然后,在存储习语之上存在整个多用户,锁定,日志记录和事务复杂性.