考虑一个大学组织的某一部分,该部分记录关于所有教员、学生、院系、课程设置等信息。
在计算机上保存信息的方法之一是在操作系统文件中存储信息。
为了支持用户操作信息,系统有若干个操作文件的应用程序,比如:
- 增加新的学生、教员以及课程的程序;
- 为学生注册课程并生成班级名册的程序;
- 为学生分配乘积,计算GPA,生成成绩单的程序;
程序员开发这些应用程序来满足大学的需求。
根据需要将新的应用程序添加到系统中。比如,假设该大学决定要创建一个新的专业。因此,该大学创建了一个新的院系,并创建新的永久性文件(或者将信息添加到现有文件中)来记录有关在这个系里的所有教员、在这个专业的所有学生、课程设置、学位要求等信息。该大学可能必须要编写新的应用程序来处理新专业的具体规定以及该大学的新规则。因此,随着时间的推移,系统需要更多的文件和更多的应用程序。
这类典型的文件处理系统是由操作系统支持的。文件处理系统在各种文件里存储永久性记录,需要不同的应用程序来从对应的文件中提取记录、向对应的文件里添加记录。
在文件处理系统中保存组织信息有若干个缺点:
- 数据冗余和不一致
数据冗余指的是相同的数据在不同的文件中存在多份拷贝。比如,有一个学生修了音乐和数学的双学位,这个学生的地址和电话号码可能出现在由音乐系的所有学生记录组成的文件和由数学系的所有学生记录组成的文件中。数据不一致指的是当出现数据冗余时,对其中一份拷贝更新时,没有对所有的拷贝也更新。比如,当对音乐系的该学生的地址进行修改,可能并没有对数学系的该学生的地址进行同步修改。 - 访问数据较难
文件处理系统不支持方便且高效的方式来检索数据。比如,现有一个大学职员要找出住在特定邮政编码区域内的所有学生的姓名,请求数据处理部门生成这样一份列表。由于原始系统的设计者没有预料到这样的请求,所以没有现成的应用程序来满足它。但是,有一个应用程序可以生成所有学生的列表。该职员有两种选择:要么获取所有学生的列表并手动提取所需的信息,要么让程序员编写必要的应用程序。这两种选择显然都不令人满意。假设编写了这样一个程序,几天后,同一个职员又需要缩减名单,只包括那些至少修了60个学分的学生。正如预期的那样,不存在生成这样一个列表的程序。同样,该职员又面临上述两种选择,但都不令人满意。
不够灵活,需求变动了,要修改程序。 - 数据孤立
因为数据是分散在不同文件中的,且不同文件可能有不同的文件格式,所以编写新的应用程序来检索合适的数据是困难的。 - 完整性问题
在数据库系统中存储的数据必须满足某种类型的一致性约束。
假设一个大学为每个系维护一个账户,记录每个账户的余额。
假设该大学要求每个系的账户余额必须大于等于0。
虽然开发者可以通过在各种应用程序中添加合适的代码来实现前述约束,但是当有新的约束增加时,很难通过修改程序来实现这些新的约束。
当约束涉及来自不同文件的多个数据项时,问题会变得更加复杂。 - 原子性问题
在传统的文件系统中很难保证原子性。
跟其他设备一样,计算机系统也可能会发生故障。在许多应用中,如果有故障发生,数据要恢复到跟故障发生前保持一致的状态。
比如,在银行系统中有个程序要将500美元从账户A转移到账户B。如果在程序执行期间系统发生了故障,则有可能出现500美元已从账户A的余额中扣除了,但是没有加到账户B的余额中,导致数据出现不一致的状态。显然,必须要有数据库一致性:借和贷要么同时发生,要都不发生。即,资金的转移必须是原子的:要么都发生,要么一个也不发生。 - 并发访问异常
在文件处理系统中很难避免并发访问异常。
比如,有个余额为10000美元的账户A,有两个银行职员几乎同时从账户A中扣除500美元和100美元。这样的并发执行可能导致账户A的余额处于不正确的状态。假设扣款程序是这样执行的:读取旧余额,扣除借记的数量,写回结果。如果两个程序并发执行,则它们可能都读取的余额是10000美元,依次写回9500美元和9900美元。看谁最后一个写回,账户A的余额要么是9500美元,要么是9900美元,而不是正确的9400美元。
再比如,为了对一门课的注册学生数做限制,注册程序对这门课维护了一个注册学生的计数器。当有学生注册时,该程序读取课程的当前计数器,验证计数是否达到上限,给计数器加1,将结果写回数据库。假设这门课的注册上限是40。假设有两个学生并发注册,计数器的值是39。两个程序执行可能都读取到的计数器值是39,都写回40,导致一种不一致的状态:计数器只增加了1,且这两个学生都成功注册了这门课。 - 安全问题
因为应用程序是以特殊的方式添加到文件处理系统中的,所以在文件系统中实现安全性约束是困难的。
不是每个数据库的用户都能访问所有数据的。比如,在一个大学里,薪酬职员需要看到的仅是数据库中有财务信息的那部分数据,他们不需要访问学术记录。
回到20世纪60年代和70年代,正是以上这些困难,加上其他困难,不仅推动了数据库系统的初始发展,而且推动了从基于文件的应用向基于数据库的应用的转换。
接下来,我们将看到那些数据库系统克服文件处理系统存储数据缺点所使用的的概念和算法。在本书的大部分内容里,我们使用一个大学组织作为典型的数据处理应用的运行实例。