database system conception(二)
B+树(书274)
静态散列
在静态散列中,我们将术语桶来表示能够存储一条或者多条记录的一个存储单位。
一般来说,用K来表示搜索码值的集合,用B来表示桶地址的集合,散列函数h就是从K到B的函数。
1.当插入一条搜索码为K的记录的时候,先计算h(K),然后给出了存放该记录的桶的地址,当有容纳空间的时候,就把这条记录存储到桶中。
2.当查询的时候,查询搜索码值为K,只需要计算h(K),然后搜索具有该地址的桶。如果出现了具有相同散列值的搜索码,就需要检查记录。
散列的用处一般是:
1.散列文件组织:通过计算所需搜索码值上的一个函数直接获得包含该记录的磁盘块地址。
2.散列索引组织:把搜索码以及它们相关联的指针组织成一个散列文件结构。
1.散列函数
一个理想的散列函数应当具有以下的条件:
1. 分布均匀。也就是散列函数从所有可能的搜索码值集合中为每一个桶分配同样数量的搜索码值
2. 分布随机。没个桶分布到的搜索码值的数目应几乎相同,即不与外部因素有关,比如按照字母顺序。
所以一个散列函数的设计要认真仔细,书289有关于某一个散列函数设计的例子。
2.桶溢出处理
如果同没有足够的空间,当插入时就会发生桶溢出。
一般发生有两个原因:
·桶不足。x>y/z,其中x表示桶数目,y表示记录总数,z表示一个桶能放入的记录总数。
·偏斜。某些桶分配到的记录比其它桶的记录要多,所以即使其它桶有空间,也有可能发生溢出
1.多条记录具有相同的搜索码
2.所选的散列函数可能造成搜索码的分布不均
所以为了不造成桶溢出,桶的数目一般选为(x+y)*(1+d),d为避让因子,虽然有可能造成一些空间浪费,但是减少了溢出的可能性。
1.闭地址
当发生桶溢出的时候,可以用溢出桶来解决溢出的问题。如果一条记录插入到桶b中,桶b已满,系统就会为桶b提供一个溢出桶。然后一个给定桶的所有溢出桶会用一个链接列表链接在一起,称为溢出链。当查询的时候,如果有溢出桶,也要查询所有溢出桶中的记录。
2.开地址
桶的集合是固定的,与闭地址不同,当它的一个桶满了之后,系统会把记录插入到初始桶集合B的其它桶中,或者直接使用下一个有空间的桶,这个策略叫做线性探查法。
散列方式的一个很大的缺点就是,在实现系统的时候必须选择确定的散列函数,之后如果被索引的文件变大或者缩小,要改变就不容易了。
3.散列索引
散列不仅可以用于文件组织,还可以用于索引的创建。散列索引将相应的指针和搜索码组织成散列文件结构。将散列函数作用于搜索码以确定对应的桶。然后将搜索码和相应指针存入该桶。
一般来说,散列索引只是一种辅助索引结构。
动态散列
如果准备使用静态散列,会有三种选择:
1.根据当前文件大小选择函数。但是当数据库变大,性能会下降
2.根据未来某个时刻文件大小的预计选择散列函数。尽管会避免性能下降,但是初始会造成相当大的空间浪费。
3.随着文件增大,周期性的对文件进行重组。
而动态散列允许散列函数动态改变,代表的就是可扩充散列。
1.数据结构
当数据库增大或者缩小的时候,可扩充散列可以通过桶的分裂来适应变化。并且每次重组仅限于一个桶,带来的开销也会比较低。
当使用可扩充散列时,会选择一个具有均匀性和随机性的散列函数h。一般是b位二进制数,典型的b值为32。但是不会为每一个散列值创建一个桶,那样会有40亿个桶,相反,我们是在把记录插入文件时按需建桶的。开始的时候我们不会使用全部的b位,任意时刻使用的位数 i 都满足大于等于0,小于等于b。
如上图所示,桶地址表上方的i表明散列值h(K)中有 i 位需要用来正确地定位对应于K的桶
2.查询和更新(书293)
查询:为了确定含有搜索码值K的桶的位置,系统取得h(K)的前 i 个高位,然后为这个位串查找对应的表项,然后根据表项中的指针得到桶的位置。
插入:先通过上述的查找,定位到桶,假设为桶j,如果该桶有剩余空间,那么久直接放进去就可以了。如果满了,就要对桶进行分裂。
· 如果I = Ij,那么久将 i 的值加一,从而使得桶地址表的大小翻倍。这样元彪中的每个表项都被两个表项替代,那么指针也会翻
倍,即,两个表项都包含和原始表项一样的指针,现在桶地址表中就有两个表项指向桶j。这个时候系统分配一个新的桶z,让第
二个表项指向该新桶,然后将Ij和Iz置为i。接下来桶j中的各条记录重新散列,根据前i位来确定记录是放在桶j还是新桶中。
· 如果I>Ij,这样系统不用增加i就可以分裂桶j,系统分配一个新桶z,然后把Ij和Iz置为原来的Ij加一后得到的值。然后就和上面的
情况一样了。
· 当插入的值具有相同的散列值并且桶空间满了的时候,就要使用溢出桶来处理。
删除:先定位到桶的位置,然后不仅要把搜索码从桶中删除,还要把记录从文件中删除。如果这时桶变成空的,那么痛也要删除,这个时候桶的地址有可能合并,桶地址表的大小也要减半。
3.静态散列和动态散列的比较
· 可扩充散列优点是可以随着文件的增长而不降低性能,并且空间开销小。
· 尽管桶地址表带来额外的开销,但是它只存放一个指针。
· 桶的分配是动态的。
但是缺点就是在查找的时候设计到了一个附加的间接层,因为在系统访问桶本身之前必须要先访问一个桶地址表
4.顺序索引和散列的比较
B+数组织将记录文件组织成顺序文件,也可以使用散列来组织文件,或者记录成堆文件(没有任何顺序)
各种方法各有优点,大多数数据库支持B+树索引