您可以在此处阅读本系列的上一篇文章。 在这篇文章中,我将介绍数据库索引。
所有数据库都实现索引。 索引是数据库中实现的附加抽象,以支持高读取吞吐量。 那么,为什么不索引数据库中的所有内容呢? 因为索引是附加的抽象,使写入速度变慢。 因此,应用程序开发人员的职责是根据应用程序的读/写工作量定义需要索引的列/键。
索引的最普遍方法是使用B树 。 B树将数据库划分为几Kb的页面或块。 每个页面都可以通过其在磁盘上的唯一地址来定位。 这样,页面可以相互引用。
例如,在上图中,如果要查找**10,请先查看根节点。 10位于7到16之间,因此跟随指针在7到16之间,您将到达第二行的中间节点。 10位于9到12之间,因此请跟随该指针指向磁盘指针在9到12之间所指向的下一页。继续进行搜索,直到到达包含键及其对应值的叶节点为止。 该值通常是实际存储记录的位置的字节偏移量。
在诸如Elastic Search,Hbase,Cassandra,Riak等新数据库中使用的另一种索引技术是基于Google的BigTable论文 。 这是其幕后工作的简短摘要:
- 新写入将添加到内存中排序的平衡树(如红黑树或AVL树)。 该内存树称为内存表。
- 当内存表变大时,它将作为SSTable文件刷新到磁盘。 将SSTable视为内存树的磁盘上已排序的键值存储,即已排序的memtable。 在将SSTable写入磁盘时,新写入可以在memtable中继续进行。
- 读取首先针对存储器。 如果在memtable中找不到键,则在最新的SSTable中搜索,然后在下一个最新的SSTable中搜索,依此类推。 SSTables已排序,因此很容易对其进行范围查询。
- 在后台,从SSTable中删除重复的键,并保留最新的键值。 此过程称为压实。
- 压缩的SSTable合并到新的SSTable中。 由于对SSTables进行了排序,因此使用像算法这样的归并排序将它们合并是非常快的。
该索引方案称为LSM树或日志结构合并树。
根据经验,LSM树可以处理更高的写入工作量,而B树则适合于较高的读取工作量。 这是因为与B树不同,SSTables中的写入始终是顺序的,而B树是在其中进行随机写的(B树页面不必在磁盘上顺序排列)
为了提高耐用性,在B树中进行写操作之前,还要写一个称为“预写日志(WAL)”的附加文件。 WAL仅是附加文件,有助于在崩溃时将B树恢复到一致状态。 这意味着写入B树意味着首先写入WAL,这又意味着额外的工作和较慢的写入。
通常,LSM树中的合并和压缩过程非常快,但有时会滞后于写入。 当数据库的书面电子工作量很高时,可能会发生这种情况。 慢速压缩和合并会对读取产生不利影响,因为现在需要读取更多SSTables。 这是LSM树的一大缺点,因为它在非常高的写吞吐量情况下,其性能可能变得不稳定,而B树则通常表现出稳定的性能。
最后,如果事务语义至关重要,那么B树是更可取的。 在LSM树中,相同的**可以存在于多个SSTable中。 在B树中,一个键仅存在于一个位置,其值就地更新。 结果,在Btrees中很容易实现事务隔离(我打算在以后的文章中介绍事务隔离)。
单击此处的链接,阅读“系统设计基础-第4部分” 。
From: https://hackernoon.com/fundamentals-of-system-design-part-3-8da61773a631