索引与散列

在数据库中,当数据量很小的时候,直接查询是没有任何问题的,但是如果当数据库中有很多数据的时候,直接查询就不那么有效了,为了提高查询速度,数据库支持了索引以提高数据库的查询速度。

索引有两种基本类型,有序索引和散列索引。有序索引是基于值的排序顺序建立;散列索引是将值平均分布到若干个桶中,某个值属于哪一个桶由一个散列函数决定,该函数称为散列函数。

对于使用哪一种索引技术更好并没有一定之规,对于要使用哪一种技术根据具体的场合而定,主要要考虑这些因素:访问时间、插入时间、删除时间和空间开销。

有序索引

有序索引即是将搜索码按照一定的顺序存储索引码的值,并将搜索码与搜索码对应的记录关联起来。

索引记录(索引项):由一个搜索码值和指向具有该搜索码值的一个或者多个记录的指针构成。

有序索引按索引记录的顺序与记录本身的顺序关系可以分为主索引(也称聚集索引)和辅助索引(也称非聚集索引)。索引记录的顺序与记录本身的顺序一致时称为主索引,索引记录的顺序与记录本身的顺序不一致时称为辅助索引。

有序索引按每个搜索码是否有都有索引记录可以分为稠密索引稀疏索引。如果每个搜索码都有一个索引记录,则索引为稠密索引。如果只为其中一部分搜索码建立索引,则索引为稀疏索引。对于主索引来说,没有必要使用稠密索引,使用稀疏索引就可以了。

使用稠密索引可以比使用稀疏索引更快的定位记录,但是稀疏索引却比稠密索引节省了很多空间,所以在设计时需要在时间和空间之间进行权衡再做出选择。

多级索引

即使在使用索引的情况下,当数据库中的数据太多的时候,索引表也是相当大的,在索引表中搜索索引记录也是需要很多时间的。当索引表很大的时候,则无法将索引表全部加载到内存中,所以需要在磁盘中去搜索索引表。这样在时间上的开销还是很大的。所以需要引入多级索引的技术,对于多级索引学过数据结构的应该能够理解,类似于数据结构中的树形结构,这里就不再过多阐述。

对于多级索引的建立需要考虑深度和广度。如果不能多级索引的深度和广度进行限制,则多级索引达不到预期的效果。

B+树索引文件

B+树索引文件是多级索引的一种,是使用最广泛的在数据插入和删除的情况下仍能保持其执行效率的几种索引结构之一。B+树索引文件采用平衡树结构,其中树根到树叶的每条路径的长度相同。树中每个非叶节点至少有n/2个子女,最多有n个子女,n是创建结构时规定的一个整数,对于特定的结构来说是固定的。

对于B+树索引文件来说,每一个非叶子节点都是一个稀疏索引,要使B+树索引文件成为一个稠密索引,每一个搜索码值都必须出现在一个叶节点中。每一个非叶子节点都包含了数量为子树数目减1的索引记录。例如一个非节点包含m个指针,则该节点则包含m-1个索引记录。其中第一个索引指针指向的子树中的所有记录的搜索码都小于第一个索引记录的搜索码,最后一个索引指针指向的子树中的所有记录都大于或等于最后一个索引记录的搜索码。

B+树上的查询

知道了B+树的结构,想要在B+树上进行查询就不难了,这里也就不过多的阐述。

B+树上的更新

B+树的更新操作包括插入和删除两种操作。

插入时先通过查询找到要插入的搜索码将要属于哪一个叶结点,然后再进行插入。当插入时需要考虑一种情况,即对应的叶节点的指针个数大于n的话,则需要将对应的叶节点分裂为两个叶节点,分裂后可能导致其父节点的指针个数增加而使其分裂,所以分裂可能会级联进行。如果根节点分裂了,则树的深度就增加了1。

删除时先通过查询找到删除的搜索码所属的叶结点,然后将其从对应的叶结点中删除。当删除时需要考虑一种情况,即对应的叶节点的指针个数据小于n/2的话,由需要将对应的叶节点与相邻的叶节点进行合并。但合并全可能会合并后的结果的指针个数据太多,这时候需要对两个节点进行重新分布,使两个节点的指针个数都不会过多或过少。两个节点的合并可能会导致父节点合并或重新分布,而两个节点重新分布则会导致父节点的搜索码改变。

静态散列

使用有序索引的必须使用索引结构来定位数据,这就必须使用到搜索,将导致很多I/O操作。

静态散列将一条或多种记录放入一个叫“”的存储单位中。通过一个散列函数可以根据搜索码直接计算出对应的记录所属的桶的地址。

选择的散列函数对效率的影响是很大的。最坏的情况就是所有的记录都在同一个桶里,在这种情况下散列表就失去了它应有的价值。最好的情况就是所有的记录平均分布到所有的桶中。一个好的散列函数应该具备这两个性质:分布是均匀的。也就是说,散列函数为每个桶分配所有可能的搜索码值集合中的同样数量的搜索码值。分布是随机的。也就是说,不管搜索码值怎样分布,每个桶应该分配到的搜索码值的数目几乎相同。

桶溢出

如果桶没有足够的空间,就会发生桶溢出。桶溢出可能是桶不足造成,也可能是桶偏斜造成。桶偏斜可能是因为某些记录具有相同的搜索码造成,也可能是因为所选的散列函数造成搜索码分布不均匀造成。为了减少桶溢出的可能性,一般会分配比实际所需要的桶的数目多的桶。即使是这样,也还是会有桶溢出的情况发生。

当发生桶溢出时,可以有两种处理方式,一是增加一个溢出桶,将记录插入到溢出桶中,如果溢出桶也满了,则再增加一个,一个给定的桶的所有的桶通过一个链表链接在一起,就形成了溢出链。第二种方法就是将记录插入到其他桶中。使用溢出链的散列结构称为闭散列,不使用溢出链的散列称为开散列

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值