This commit is contained in:
keming 2020-10-18 23:54:54 +08:00
parent 03cdebe141
commit 726784be63
3 changed files with 19 additions and 19 deletions

6
ch2.md
View File

@ -531,7 +531,7 @@ db.observations.aggregate([
可以将那些众所周知的算法运用到这些图上例如汽车导航系统搜索道路网络中两点之间的最短路径PageRank可以用在网络图上来确定网页的流行程度从而确定该网页在搜索结果中的排名。
在刚刚给出的例子中图中的所有顶点代表了相同类型的事物网页或交叉路口。不过图并不局限于这样的同类数据同样强大地是图提供了一种一致的方式用来在单个数据存储中存储完全不同类型的对象。例如Facebook维护一个包含许多不同类型的顶点和边的单个图顶点表示人地点事件签到和用户的评论;边缘表示哪些人是彼此的朋友哪个签到发生在何处谁评论了哪条消息谁参与了哪个事件等等【35】。
在刚刚给出的例子中图中的所有顶点代表了相同类型的事物网页或交叉路口。不过图并不局限于这样的同类数据同样强大地是图提供了一种一致的方式用来在单个数据存储中存储完全不同类型的对象。例如Facebook维护一个包含许多不同类型的顶点和边的单个图顶点表示人地点事件签到和用户的评论边缘表示哪些人是彼此的朋友哪个签到发生在何处谁评论了哪条消息谁参与了哪个事件等等【35】。
在本节中,我们将使用[图2-5](img/fig2-5.png)所示的示例。它可以从社交网络或系谱数据库中获得它显示了两个人来自爱达荷州的Lucy和来自法国Beaune的Alain。他们已婚住在伦敦。
@ -558,7 +558,7 @@ db.observations.aggregate([
* 描述两个顶点之间关系类型的标签
* 一组属性(键值对)
可以将图存储看作由两个关系表组成:一个存储顶点,另一个存储边,如[例2-2]()所示该模式使用PostgreSQL json数据类型来存储每个顶点或每条边的属性)。头部和尾部顶点用来存储每条边;如果你想要一组顶点的输入或输出边,你可以分别通过`head_vertex`或`tail_vertex`来查询`edges`表。
可以将图存储看作由两个关系表组成:一个存储顶点,另一个存储边,如[例2-2]()所示该模式使用PostgreSQL JSON数据类型来存储每个顶点或每条边的属性)。头部和尾部顶点用来存储每条边;如果你想要一组顶点的输入或输出边,你可以分别通过`head_vertex`或`tail_vertex`来查询`edges`表。
**例2-2 使用关系模式来表示属性图**
@ -926,7 +926,7 @@ Cypher和SPARQL使用SELECT立即跳转但是Datalog一次只进行一小步
虽然我们已经覆盖了很多层面,但仍然有许多数据模型没有提到。举几个简单的例子:
* 使用基因组数据的研究人员通常需要执行**序列相似性搜索**这意味着需要一个很长的字符串代表一个DNA分子并在一个拥有类似但不完全相同的字符串的大型数据库中寻找匹配。这里所描述的数据库都不能处理这种用法这就是为什么研究人员编写了像GenBank这样的专门的基因组数据库软件的原因【48】。
* 粒子物理学家数十年来一直在进行大数据类型的大规模数据分析像大型强子对撞机LHC这样的项目现在可以工作在数百亿兆字节的范围内在这样的规模下需要定制解决方案来阻硬件成本的失控【49】。
* 粒子物理学家数十年来一直在进行大数据类型的大规模数据分析像大型强子对撞机LHC这样的项目现在可以工作在数百亿兆字节的范围内在这样的规模下需要定制解决方案来阻硬件成本的失控【49】。
* **全文搜索**可以说是一种经常与数据库一起使用的数据模型。信息检索是一个很大的专业课题,我们不会在本书中详细介绍,但是我们将在第三章和第三章中介绍搜索索引。
让我们暂时将其放在一边。在[下一章](ch3.md)中,我们将讨论在**实现**本章描述的数据模型时会遇到的一些权衡。

10
ch3.md
View File

@ -105,7 +105,7 @@ $ cat database
**图3-3 同时执行压缩和分段合并**
每个段现在都有自己的内存散列表,将键映射到文件偏移量。为了找到一个键的值,我们首先检查最近段的哈希映射;如果键不存在,我们检查第二个最近的段,依此类推。合并过程保持细分的数量,所以查找不需要检查许多哈希映射。
每个段现在都有自己的内存散列表,将键映射到文件偏移量。为了找到一个键的值,我们首先检查最近段的哈希映射如果键不存在,我们检查第二个最近的段,依此类推。合并过程保持细分的数量,所以查找不需要检查许多哈希映射。
大量的细节进入实践这个简单的想法工作。简而言之,一些真正实施中重要的问题是:
***文件格式***
@ -201,7 +201,7 @@ Lucene是Elasticsearch和Solr使用的一种全文搜索的索引引擎它使
#### 性能优化
与往常一样大量的细节使得存储引擎在实践中表现良好。例如当查找数据库中不存在的键时LSM树算法可能会很慢您必须检查内存表然后将这些段一直回到最老的可能必须从磁盘读取每一个然后才能确定键不存在。为了优化这种访问存储引擎通常使用额外的Bloom过滤器【15】。 (布隆过滤器是用于近似集合内容的内存高效数据结构,它可以告诉您数据库中是否出现键,从而为不存在的键节省许多不必要的磁盘读取操作。
与往常一样大量的细节使得存储引擎在实践中表现良好。例如当查找数据库中不存在的键时LSM树算法可能会很慢您必须检查内存表然后将这些段一直回到最老的可能必须从磁盘读取每一个然后才能确定键不存在。为了优化这种访问存储引擎通常使用额外的Bloom过滤器【15】。 (布隆过滤器是用于近似集合内容的内存高效数据结构,它可以告诉您数据库中是否出现键,从而为不存在的键节省许多不必要的磁盘读取操作。)
还有不同的策略来确定SSTables如何被压缩和合并的顺序和时间。最常见的选择是大小分层压实。 LevelDB和RocksDB使用平坦压缩LevelDB因此得名HBase使用大小分层Cassandra同时支持【16】。在规模级别的调整中更新和更小的SSTables先后被合并到更老的和更大的SSTable中。在水平压实中关键范围被拆分成更小的SSTables而较旧的数据被移动到单独的“水平”这使得压缩能够更加递增地进行并且使用更少的磁盘空间。
@ -243,7 +243,7 @@ Lucene是Elasticsearch和Solr使用的一种全文搜索的索引引擎它使
#### 让B树更可靠
B树的基本底层写操作是用新数据覆盖磁盘上的页面。假定覆盖不改变页面的位置;当页面被覆盖时对该页面的所有引用保持完整。这与日志结构索引如LSM树形成鲜明对比后者只附加到文件并最终删除过时的文件但从不修改文件。
B树的基本底层写操作是用新数据覆盖磁盘上的页面。假定覆盖不改变页面的位置当页面被覆盖时对该页面的所有引用保持完整。这与日志结构索引如LSM树形成鲜明对比后者只附加到文件并最终删除过时的文件但从不修改文件。
您可以考虑将硬盘上的页面覆盖为实际的硬件操作。在磁性硬盘驱动器上这意味着将磁头移动到正确的位置等待旋转盘上的正确位置出现然后用新的数据覆盖适当的扇区。在固态硬盘上由于SSD必须一次擦除和重写相当大的存储芯片块所以会发生更复杂的事情【19】。
@ -259,7 +259,7 @@ B树的基本底层写操作是用新数据覆盖磁盘上的页面。假定覆
* 一些数据库如LMDB使用写时复制方案【21】而不是覆盖页面并维护WAL进行崩溃恢复。修改的页面被写入到不同的位置并且树中的父页面的新版本被创建指向新的位置。这种方法对于并发控制也很有用我们将在“[快照隔离和可重复读](ch7.md#快照隔离和可重复读)”中看到。
* 我们可以通过不存储整个键来节省页面空间,但可以缩小它的大小。特别是在树内部的页面上,键只需要提供足够的信息来充当键范围之间的边界。在页面中包含更多的键允许树具有更高的分支因子,因此更少的层次
* 通常,页面可以放置在磁盘上的任何位置;没有什么要求附近的键范围页面附近的磁盘上。如果查询需要按照排序顺序扫描大部分关键字范围那么每个页面的布局可能会非常不方便因为每个读取的页面都可能需要磁盘查找。因此许多B树实现尝试布局树使得叶子页面按顺序出现在磁盘上。但是随着树的增长维持这个顺序是很困难的。相比之下由于LSM树在合并过程中一次又一次地重写存储的大部分所以它们更容易使顺序键在磁盘上彼此靠近。
* 通常,页面可以放置在磁盘上的任何位置;没有什么要求附近的键放在页面附近的磁盘上。如果查询需要按照排序顺序扫描大部分关键字范围那么每个页面的布局可能会非常不方便因为每个读取的页面都可能需要磁盘查找。因此许多B树实现尝试布局树使得叶子页面按顺序出现在磁盘上。但是随着树的增长维持这个顺序是很困难的。相比之下由于LSM树在合并过程中一次又一次地重写存储的大部分所以它们更容易使顺序键在磁盘上彼此靠近。
* 额外的指针已添加到树中。例如,每个叶子页面可以在左边和右边具有对其兄弟页面的引用,这允许不跳回父页面就能顺序扫描。
* B树的变体如分形树【22】借用一些日志结构的思想来减少磁盘寻道而且它们与分形无关
@ -267,7 +267,7 @@ B树的基本底层写操作是用新数据覆盖磁盘上的页面。假定覆
尽管B树实现通常比LSM树实现更成熟但LSM树由于其性能特点也非常有趣。根据经验通常LSM树的写入速度更快而B树的读取速度更快【23】。 LSM树上的读取通常比较慢因为它们必须在压缩的不同阶段检查几个不同的数据结构和SSTables。
然而,基准通常对工作量的细节不确定敏感。 您需要测试具有特定工作负载的系统,以便进行有效的比较。 在本节中,我们将简要讨论一些在衡量存储引擎性能时值得考虑的事情。
然而,基准通常对工作量的细节不确定敏感。 您需要测试具有特定工作负载的系统,以便进行有效的比较。 在本节中,我们将简要讨论一些在衡量存储引擎性能时值得考虑的事情。
#### LSM树的优点