数据存储体会

很多人入行以后都接受了若干习惯性的、实践上的传承,比如使用数据库。不过,使用成品数据库的目的是什么?

第一个答案恐怕首先就是查询。查询当然非常重要,不过查询却未必是所有问题的核心。我们可以观察到的一个现实情况是,很多很小的项目,其查询实际上十分简单,如果不考虑数据持久,而是在内存中处理,用一些最简单的查找方式,比如for循环就可以轻松搞定。

很多更大的项目也是如此:即便数据量有一定规模,“实体”种类很多,但它们的关系其实并不复杂,只会使用非常有限的数据库功能。那么为什么要使用数据库产品,这里面就另有原因,这原因虽然很多人一时说不出来,但却相当的显而易见:以容易存取的方式存储小的数据片段。

为了达成这个目的,第一个可用的中间件按理说是文件系统,但大多数时候文件系统都不在考虑范围之内,这很大程度上是因为文件系统有三个问题:

首先是文件系统的分块机制,大多数操作系统所支持的文件系统默认一般是4K左右,最小的单位一般是512。可想而知,如果把比如“用户名”每个存入一个文件,由于每个文件会占用一个块,这会带来极大的浪费。我们可以直接用文件名保存信息,但文件系统并不保证空文件不占用磁盘。

第二个问题是并不是所有的文件系统都保证文件名按一定规则排序,这从根本上依赖文件系统内部的索引方式。而大多数文件系统仅支持某种预先设定的索引方式;而且这种方式即便是有序的,也没有承诺文件系统升级的时候不会改变;同时,操作系统也没有义务承诺不更换其它文件系统。

第三个问题是,即便我们的业务无需依赖于数据排序,我们在一个文件系统中定位某一数据的方式也只有文件名,而对文件名的格式却也不存在任何可靠的保证。比如长度限制、非法字符,有可能一个文件系统、在一个时期内是这样的,换一个文件系统或者换一个版本又变成了那样的。

这三个问题,除了第一个部分的含有从经济性上的一种考虑,其它问题说穿了就是文件系统不提供任何稳定的协议可以可靠支撑除了文件管理本身之外的业务数据管理。正是由于文件系统的这种从人类约定上的不可依赖性,导致我们对其它解决方案产生了需求。

让我们看看数据存储的需求都是些什么:从经济性上讲要致密,就是说,无论多小的数据,它们基本上应该是一个挨着一个的;从易用性上来讲它们应该容易定位,就是说,应该在几个成本较低的操作之内就找到一个数据;从很多普遍性的业务需求上来讲应支持排序,就是说,找到了2就能马上找到1和3。

这是最基本的需求,而诸如链接(Join)一类的特性,实质上是伪需求。这么说的原因是,它们是因为某类数据库产品预先设定了数据存储的模式(或schema),对于这些模式产生的新问题的一种弥补手段。比如,Join的存在是因为我们把相关的一组数据放进了两个不同的关系集合(表格)。

实现上述需求,和随之而来如一致性一类的要求,很显然要付出一些成本,考虑到自己实现的成本,若眼前的任务能够存在至少一个到现有产品之间的同构,自然就可以使用它们。

为什么要白活这些?掌握了基本事实、考虑自己的需求,就可以在自造、拿来,拿那种等问题上得到最准确的答案。

----------

一个不做保证的预告:

我最近在实现最基本的数据存储这一块,它在某些方面和大多数广泛使用的产品采取了不同的选择。比如取消了教科书上介绍的惯用方法中基于块级别的一些管理手段;比如大多数数据库产品无论是SQL还是NoSQL都采取了C/S结构,而我的设计是每个进程都自己通过库存取文件。

在这个过程中产生了一些经验,有空想写点文章记录一下。

这些不同的做法(包括我从书上不同方案做出的选择)并不是绝对的谁对谁错,而是存在着诸多考虑:比如可变长数据所导致的空间回收方式、碎片、利用率问题;比如删除、更新数据所产生的问题;如何有效利用各种硬件扩展方式提高效率等等。

说实话这块真没什么大学问,不过却还是对技巧有点要求。

posted on 2011-06-21 16:24  怪怪  阅读(598)  评论(2编辑  收藏  举报

导航