第3章 散列

在第2章中,我们介绍过如何使用多个字符串键去存储相关联的一组数据。比如在字符串键实现的文章存储程序中,程序会为每篇文章创建4个字符串键,并把文章的标题、内容、作者和创建时间分别存储到这4个字符串键里面,图3-1就展示了一个使用字符串键存储文章数据的例子。

图3-1 使用多个字符串键存储文章

使用多个字符串键存储相关联数据虽然在技术上是可行的,但是在实际应用中并不是最有效的方法,这种存储方法至少存在以下3个问题:

首先,程序每存储一组相关联的数据,就必须在数据库中同时创建多个字符串键,这样的数据越多,数据库包含的键数量也会越多。数量庞大的键会对数据库某些操作的执行速度产生影响,维护这些键也会产生大量的资源消耗。

其次,为了在数据库中标识出相关联的字符串键,程序需要为它们加上相同的前缀。但键名实际上也是一种数据,存储键名也需要耗费内存空间,因此重复出现的键名前缀实际上导致很多内存空间被白白浪费了。此外,带前缀的键名降低了键名的可读性,让人无法一眼看清键的真正用途,比如键名article::10086::author就远不如键名author简洁,键名article::10086::title也不如键名title简洁。

最后,虽然程序在逻辑上会把带有相同前缀的字符串键看作相关联的一组数据,但是在Redis看来,它们只不过是存储在同一个数据库中的不同字符串键而已,因此当程序需要处理一组相关联的数据时,就必须对所有有关的字符串键都执行相同的操作。比如,如果程序想要删除ID为10086的文章,那么它就必须把article::10086::title、article::10086::content等4个字符串键都删掉才行,这给文章的删除操作带来了额外的麻烦,并且还可能会因为漏删或者错删了某个键而出现错误。

为了解决以上问题,我们需要一种能够真正地把相关联的数据打包起来存储的数据结构,而这种数据结构就是本章要介绍的散列(hash)键。