存储结构

312 阅读6分钟

坏程序员担心代码,好程序员会担心数据结构及其关系。——莱纳斯·托瓦尔兹(Linus Torvalds)

数据结构重要,程序员皆知。程序员要关心数据结构,但只关心数据结构,远远不够。要成为好程序员,你要关心数据结构的逻辑结构,还要关心数据结构的存储结构。

位置即逻辑

什么是逻辑结构?数据元素之间的逻辑关系。比如数组结构,其中元素前后相连,其逻辑关系是前后关系。又比如树结构,其中元素上下相连,其逻辑关系是父子关系。逻辑结构有很多种,比如常见的数组、链表、树,不常见的双向循环链表、基数树、前缀树。逻辑结构只关心逻辑关系,而不用关心如何实现逻辑关系。逻辑结构虽然有无数种,但基本逻辑结构只有三种:顺序表、树、图。

什么是存储结构?数据元素在存储器上的位置关系。比如数组元素,左右相邻,存储于一块连续内存空间。又如,树结构中的元素,分散于不同内存区域,通过指针相接。存储结构有两种:顺序结构、链式结构。顺序结构指通过相对位置表示逻辑关系,典型代表是数组。链式结构指通过指针表示逻辑关系,典型代表是链表。顺序结构和链式结构,就像物理学中的原子。两种原子,构成许多种分子;两种存储结构,构成许多种复杂存储结构。

存储器有很多种,但存储结构相同,只有两种。大的磁盘、光盘,小的U盘、SD卡;可随时插拔的移动硬盘,嵌入中央处理器的高速缓存;老一辈的磁带,新一代的固态硬盘。虽然大小、年代相差巨大,但是物理结构是一致的。因此这些不同种类的存储器,其存储结构是相同的。其存储结构,要么是顺序结构,要么是链式结构。

同一逻辑结构,能通过不同存储结构存储。线性表能通过顺序结构存储,也能通过链式结构存储。前者通过前后位置表示线性关系,后者通过指针表示线性关系。线性表的逻辑结构简单,两种存储结构都可以存储。逻辑结构复杂一点,比如树结构、图结构,则无法使用顺序结构存储,只能使用链式结构、或者复杂的复合存储结构。

数据结构是逻辑结构,也是存储结构。逻辑结构和存储结构是什么关系呢?映射关系。也就是说,逻辑结构映射存储结构,逻辑关系映射位置关系。位置即逻辑。

扇区、块、文件

谈论存储结构,不得不谈存储结构的物理基础——存储器。内存和磁盘是典型的存储器。如何在内存上放置存储结构,对有经验的程序员来说,知表知里。然而,如何在磁盘上存放存储结构,对有经验的程序员来说,同样空白。

磁盘是如何存放存储结构?想要知道,先看看内存如何存放存储结构。你会很快想到数组、链表、树等数据结构,并能很快回答:通过数组或者指针方式。磁盘与内存遵循同样的原理。不同的是,内存的最小格子是字节,磁盘的最小格子是扇区;内存通过内存指针,而磁盘通过磁盘指针。内存指针和磁盘指针本质相同,都是存储器中小格子地址而已。

扇区是磁盘的最小格子,也是供操作系统读写的最小单位。操作系统能读取一个扇区的数据,抹掉一个扇区的数据。也能从一个扇区,索引到另一个扇区。虽然磁盘给操作系统提供每一片扇区,但是,扇区还是太零碎了,并不利于操作系统管理磁盘空间。更好的方式,将多个连续扇区组织成一个块。

在 Windows 操作系统中,8个连续扇区组成一个块。每个块大小 4096字节,换算为 4KB。在 Linux 操作系统中,同样也是8个连续扇区组成一个「块」。块大小并非固定不变,而是可以设置的。只不过,默认大小是 4KB。

你可能从未接触过块,只接触过文件。在操作系统中,一切都是文件。在操作系统中,磁盘中的一切都是块。文件存储在磁盘上,文件与块是什么关系呢?文件由多个块组成。

文件可以分成两类:一类是普通文件,另一类是数据库文件。普通文件与数据库文件的区别在于,普通文件是顺序结构存储,数据库文件是链式结构存储。普通文件是顺序存储,一个块接一个块的存储,从1,2,3....到最后一个号块。顺序存储也是顺序访问,也从1,2,3....到最后一个块,依次访问。

数据库文件并不一个块一个块的存储与访问,而是按块编号直接访问。比如,数据位于98号块上,数据库会直接检索98号块的数据。数据库文件的存储结构,通常是 B Tree 结构。 B Tree 结构中的元素,通过链式指针相连,是链式结构。

典型代表

数据库文件是文件系统的典型代表, B Tree 则是存储结构的典型代表。

B Tree 转为数据库文件而设计,被各种数据库广泛采用。比如,Mysql、MongoDB、Oracle、SqlServer 均采用 B Tree,或其变种 B- Tree、B+ Bree。Mysql 采用 B+ Tree,存储数据和索引。Mysql 的索引文件是典型 B+ Tree 结构。B+ Tree 检索元素的复杂度是 O(logn),对数级时间复杂度,其检索效率极高。而且,随着元素总数增多,其检索时间稳定而可预期。

B+ Tree 是谁发明的呢?通过现有资料,并没有发现明确来源。只知道,计算机科学家 Rudolf Bayer 和 Edward M. McCreight 在1972年的一篇论文中提及 B 树。美国普渡大学计算机科学家 Douglas Comer 在1979年发表了一篇名为《The Ubiquitous B-Tree》(无处不在的B Tree)的调查论文,指出 IBM 公司于 1973年发表的文章中,介绍了使用 B+ Tree 的 IBM's VSAM 存储技术。

虽然没有明确起源,但 B Tree 家族,被广泛研究,广泛应用。正如 Douglas Comer 所言:无处不在的 B Tree。

小结

有人说,逻辑结构决定数据结构的设计,存储结构决定数据结构实现。好程序员,必然心中有逻辑结构,手上有存储结构。在编写程序时,才能心到手到。