索引

简介

索引相当于目录。通过索引,可以在大量数据库记录中快速检索到目标记录。

索引中也需要存储大量记录,这些记录可能存储在磁盘上,但是仍然需要支持高效率的新增、删除和检索。

索引可以解决哪些问题

要想根据关键字查询数据库记录,首先应将记录根据关键字排序,然后对有序线性表进行二分查找。

但是用户可能会根据多个关键字对数据库中的一条记录进行查询,比如用户表,可能根据用户名查询、身份证号查询等等。无法根据多个关键字对同一批记录进行排序。

索引如何解决上述问题

在数据库主文件之外,新建索引文件

索引文件由关键码值和指向具有该关键码值的数据库完整记录的指针组成

可以对索引文件的关键码进行排序后查找,然后根据关键码值对应的指针,即可找到数据库完整记录。

主码索引和辅码索引

数据库每条记录的唯一标识,称为主码(primary_key)。

对于记录中的其它属性,可能多条记录有相同的属性值,称为辅码(secondary key)。

辅码索引由辅码值和和具有该辅码值的多条记录的主码值组成。

根据辅码值找到主码值后,可以根据主码值直接检索整个数据库,找到完整记录;也可以根据主码值在主码索引找到指针,通过指针找到完整记录。

如果使用主码索引,则只有主码索引存储数据库完整记录位置,其它索引都只存储主码值或指向主码索引的指针。

实现索引的数据结构

散列表:只支持“找到关键码值为K的记录”的查找,不支持范围查找和按顺序访问。

按关键码排序的简单线性表:新增、删除操作的开销大。

树形索引


线性索引

线性索引由关键码值/指针对组成:

key:关键码值

value:指向数据库完整记录的指针

线性索引按关键码值排序,根据关键码值二分查找后找到指针,根据指针找到数据库完整记录。

支持随机访问。

问题:如果线性索引太大,无法存储在内存,就只能存储到磁盘,此时二分查找需要多次访问磁盘,开销太大。

二级线性索引

线性索引存储在多个磁盘块中

二级线性索引是一个数组,在内存中,存储线性索引每个磁盘块中第一个关键码值

比如线性索引占用4个磁盘块,则内存中的二级线性索引是一个长度为4的数组

二级线性索引

由于线性索引关键码值是有序的,只需在内存的二级线性索引中,找到小于目标关键码值的最大值,即找到了线性索引所在的磁盘块,此时,将该磁盘块内容读取到内存,再在内存中二分查找内容找到目标关键码对应的指针,近而找到数据库完整记录。

解决了多次访问磁盘的问题。整个过程只需读取两次磁盘:一次将线性索引磁盘块内容读取到内存,一次根据指针在磁盘中读取数据库完整记录。

问题:1、新增、删除数据库记录时,都要更新线性索引,而线性数组新增、删除开销太大;2、如果多条记录有相同的关键码值,会在索引文件中占用多个存储空间,造成浪费。

二维数组

第一列存为有序数组,存储关键码值

每一行存储具有该关键码值记录的主码值

二维数组

解决了新增、删除记录开销太大问题。在辅码值范围不变的情况下,新增、删除数据库记录,只需修改其中一行数据即可。

解决了重复关键码值浪费存储空间问题。

问题:1、新增一个辅码值时,由于第一列是有序的,可能会导致移动多行记录。2、二维数组的每一行都是固定长度,有些辅码值的记录可能很少(比如上图中第3行),导致存储空间浪费。

有序数组+链表

有序数组中存储关键码值

数组中每个关键码值关联一个链表,存储具有该关键码值记录的主码值

有序数组+链表

解决了新增、删除记录开销太大问题。新增、删除记录时,只需修改链表中的记录,而修改链表是很容易的。

解决了重复关键码值浪费存储空间问题。

问题:如果索引存储在内存中,没有问题。但是如果存储在磁盘中,则可能出现链表存储在多个磁盘块的情况。

有序数组+单个链表

主码表(链表)

key:主码值

value:指向链表中下一个跟主码值记录拥有相同关键码值记录的主码值指针

主码表

辅码表

key:关键码值(有序)

value:指向主码表中,第一个具有该关键码值记录的主码值指针。

辅码表

通过辅码表指针在主码表中找到的所有记录

可见,虽然所有主码值都存储在一个链表中,但找到结果还是与多个链表是等价的。

而且在链表中新增、删除元素都很容易的。

通过指针在主码表中找到所有记录

解决了链表可能存储在多个磁盘块的问题。数组关联的是链表元素指针,而不是一整个链表,不管链表元素存储在哪,都可以通过指针找到。

但是对于有序数组的新增、删除操作,开销仍然很大。


ISAM

ISAM(Indexed Sequential Access Method)本质上是二级线性索引。

数据结构如图所示:


ISAM

磁盘中的数据结构是多个柱面,每个柱面由柱面索引、数据库完整记录、溢出区组成。

    - 数据库完整记录按主码值顺序存储在多个磁盘块中

    - 柱面索引存储当前柱面中,存储记录的每个磁盘块的最小主码值。

    - 新增记录时,新增在每个柱面的溢出区,如果溢出区满了,就存储到系统溢出区。

内存中有一个主码表,存储每个柱面索引中的最小值。

检索时,根据二级线性索引原理

1、在内存主码表检索到目标主码值所在的柱面,将磁盘柱面中的柱面索引读取到内存

2、在内存柱面索引中检索到目标主码值所在的磁盘块,将磁盘块读取到内存

3、在内存磁盘块内容中检索,根据目标主码值检索到数据库完整记录

4、如果没有找到记录,就检索溢出区

在情况好时(即不需要访问溢出区的时候),只需访问两次磁盘

但是在情况不好且溢出区很大甚至被填满时,检索速度就会越来越慢

这时候就需要重组数据库:将溢出区的数据按顺序整理到磁盘块

当插入或删除记录的情况很少或者没有时,线性索引是很有效的。在20世纪60年代,IBM使用这种数据结构存储数据库数据,当时这种数据库重组很普遍,一般在夜间完成。


树形索引

二叉查找树(BST,binary search tree),可以存储重复关键码值,可以高效的插入、删除和检索(平均情况下运行时间都是O(logn))。

如果索引以BST结构存储在内存中,即使BST的平衡性很差,也不会对性能产生较大影响。

但是如果索引太大,无法存储在内存,只能存储到磁盘,这时就会遇到两个问题:

1、如何保持BST的平衡性

如果BST的平衡性很差,会导致叶结点的深度增加,查询次数增加,即相应的增加磁盘访问次数

2、如何在磁盘中安排结点,使得从根结点到任何叶结点的路径所经过的磁盘页最少。

即磁盘I/O最少

解决第一个问题,可以让BST保持完全二叉树形状。

解决第二个问题,可以让每个子树的根节点和所有叶结点都存储在同一个磁盘页中,每个磁盘页有三个结点的存储空间,如图所示

完全二叉查找树

如果一个叶结点和它的父结点在同一个磁盘页中,如果父结点被读取到内存中,那么这个叶结点也会同时被读取到内存中,访问该结点时,就不需要再次访问磁盘,而是可以直接在内存中访问了。

问题:为了让BST始终保持完全二叉树形状和上述的磁盘存储结构,每次新增、删除时,都可能需要大量的重组操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354