后台开发最常见的操作就是对服务器数据的增删改查。与本地文件读写不同,服务器通常借助结构化索引来管理和缓存数据,以满足互联网数据存取的高性能、易用性、稳定性、一致性和扩展性等方面的需求。
本文简要介绍实现这些结构化索引的经典底层数据结构。包括:
本着归纳总结抛砖引玉的目的,本文试图抓核心要点而非全面细节,读者可以按图索骥,研究和发现更多隐藏的细节。
以下分篇展开各数据结构具体内容的介绍。
哈希表
根据键直接进行访问的数据结构。
关键概念:哈希函数、冲突、装载因子、再哈希(rehashing)
哈希函数:计算键到哈希桶(存储位置)的映射关系。
冲突:不同键由哈希函数计算后映射到同一哈希桶。
装载因子:哈希表存储的键值与哈希桶个数的比值。
再哈希:当装载因子超过预设高值或者低于预设低值(可选)时,需要调整哈希桶的个数和相应键值存储地址,以控制键值查找次数或占用空间。
处理冲突的方式:
1.拉链法,用链表保存冲突值。
2.开放地址法,相邻桶存放冲突值。
图1:拉链法哈希表,来自网络
哈希表直观高效,是最常用的查找类数据结构,标配于主流语言标准库的关联容器、服务器负载均衡策略、各种缓存组件和键值数据库等。
多级哈希
基本概念与哈希表类似,区别在于哈希桶的数据结构。
重要实现细节如下:
-
使用二维数组存放哈希桶,每个哈希桶对应存储一个键值。
-
二维数组的每一行称为一阶,为减少冲突,每一阶的哈希桶个数都是素数。
-
查找时逐阶计算哈希桶地址,遇到冲突时,往下一阶继续查找。
-
由于冲突概率逐阶减小,每行哈希桶数量逐行减少。
-
当无法插入数据时,只需继续增加阶数。
图2:多级哈希结构,来自网络
多级哈希实现简单,查询快速,空间利用率高,容易实现并行(高并发)。常用于实现服务器内存缓存结构,尤其是基于共享内存的缓存数据的管理。