| 域名空间 下载中心 社区论坛 信息公告 MY小屋 |
![]() |
联系我们 设为首页 加入收藏 |
|
首页 | 新闻资讯 | 编程开发 | 网页设计 | 图形图象 | 网络媒体 | 网站模板 | 数 据 库 | 投稿 论坛 | 操作系统 | 系统优化 | 网络安全 | 黑客技术 | 硬件学堂 | 硬件报价 | 服 务 器 | 地图 专题 | 应用软件 | 聊天通讯 | Q Q 专栏 | 建站经验 | 在线工具 | 站长Club | 注 册 表 | 旧版 社会 | 游戏娱乐 | 设计欣赏 | 疑难解答 | 社区论坛 | 韩国素材 | 素材图库 | 广告服务 | 服务 |
| 新版上线![旧版] | |||||
注:打开慢时请稍等
构造块概述http://www.iyit.net 日期:2006-5-23 12:04:59 来源:网络转载 点击: |
注释 我们要为本章中所有的示例使用Microsoft Access。并不是因为Access更好一些,而是因为它提供了大量的工具,可以使数据库设计过程更加容易。Access还是Microsoft Office专业版软件包的一部分,所以在阅读本书时,很可能你们中许多人的手头都有Access的拷贝。请记住,你应该会有所收获,并把它们应用到其它的DBMS产品中去。 图5.1概述了Visual C++、数据库管理器以及数据库是如何交互作用的。如果你现在实在不理解图中的一切是如何进行的,那也无须担心。我们将在随后的章节中讨论所有的元素。现在,这张图只是大体说明各种部件是如何连接到一起的。 可移植性 开始设计过程之前,一定要确保数据库和你选择的DBMS实际上可以和Visual C++相协作。使用ODBC之外的ADO,OLE-DB和DAO的能力应该能够极大地增加找到正确解决办法的机会。另外,如果决定从多个平台访问数据库的话,需要保证有办法以想为其编写应用程序的所有平台上使用数据库,并保证DBMS支持文件和记录锁定的标准方法。简言之,在最后决定使用哪一个DBMS之前,必须检查每一个可计算性问题,尤其是计划在多种机器上使用DBMS的情况下更应如此。 数据库 最好把数据库看成是一个容器(见图5.1)。数据库用来存储要用于存储和操纵数据的全部元素。大多数的数据库是单个的文件,比如Access用的MDB文件。也可以使用有分离文件的产品,文件都存储在一个像目录的地方。在这种情况下,目录就像数据库棗它是把所有其它元素保持在一起的容器。 注释:Ashton-Tate(dBASE的发明者)首次在单个Xbase表格(DBF文件)中使用了“数据库”这一术语。事实上,这个文件的扩展名DBF的意思就是“数据库文件”。这一销售策略带来的后果是,一些人仍然对什么是表以及什么是数据库感到迷惑。数据库是一个把所有其它数据元素保存在一起的容器,其中包括代码、窗体、表、查询、索引和报告。不管你现在在想什么,遍及全书的术语“数据库”总是指这样一个容器,它将一个数据集的所有数据元素都保存在一起。 数据库并不只是端坐在那里,看上去很可爱。一个被称为数据库管理器的特殊应用程序可以在文件内部查看并提取所需的一切。如果你正在建立数据库,可能想看看已经定义的查询或者窗体。另一方面,作为一个用户,你唯一的兴趣可能是包含在表内的一些难以理解的比特。不管你需要什么,数据库管理器正是这样的应用程序,它在数据库内查找并为你提取所需要的东西。本质上讲,数据库管理器像一个正在碗柜这个容器中找东西的人那样,寻找某个玻璃器具或者什么吃的东西。 注 和任何用户一样,Visual C++请求数据管理器从数据库获取它所需要的东西。 把数据库管理器和数据库放在一起,就形成了数据库管理系统(DBMS)。在Visual C++的情况下,用来处理数据的数据库管理器和你编写的程序共用数据管理器的规则。换言之,用户要提出请求,必须和应用程序交互作用。反过来,应用程序请求数据管理器提供用户所请求的数据。数据管理器会返回数据,应用程序将其显示出来。这听起来好像有很多工作要做,实际上并非如此。对C++程序员来说,大部分工作是自动完成的(至少用MFC AppWizard创建应用程序时是这样)。 表 表是数据库内唯一可以保存数据的结构。其它每种结构都被设计成以某种方式处理数据:窗体用于显示数据、索引用于排序数据、查询寻找特定的数据片。实际存储数据的唯一结构就是表。 那么,表是如何拼装起来的呢?图5.1已很好地说明了这一点。请回想一下你用笔和纸创建的其它表(或者是你在类似本书的书籍中看见过的表)。表通常包含行和列。同样,数据库中的表也包含行和列。 行就是记录。每个记录代表了要收集的所有数据的一次出现。例如,如果你在创建姓名和地址表,那么行(记录)应该包含一个人的所有信息(至少应该包含设计表时要求保存的信息棗我们会在后面看到,表是以节省数据库服务器空间的方式组合起来的,你仍然可以看到正在过目的任何数据的完整图片)。 注 行(记录)总是包含要存储在数据库中的数据实例。 每一个表列(或称做字段)都包含一类数据。例如,可能有名为Last_Name的表列(字段)。这个字段应包含你的姓名与地址数据库中所有人的姓名。字段只保存一类数据。你不能用单个字段在一个记录中保存地址信息,而在另一个记录中保存年龄信息。如果既要保持地址信息又要保持年龄信息,就必须构造两个字段。 注 列(字段)包含一类数据,如姓氏或者地址。 从表中获取特定的一段数据或者数据元素很容易。你所需要完成的任务就是请求特定的行(记录)和列(字段)。从数据库中获取数据的过程棗不管它是包括一个数据元素还是包括表提供的所有记录棗都称为查询。本质上讲,在你向数据库管理器提出一个问题后,它就提供与该问题相匹配的数据予以响应。Visual C++在提出问题时,很大程度上要依赖一种特殊的语言,这就是SQL(结构化查询语言)。但是你会发现,在使用ADO,OLE-DB或ADO时,也可以利用其它的机制。随着课程的进展,我们会越来越熟悉SQL,但是如果想设计复杂工程的话,就要花一些额外的时间来学习这门语言。 注 创建查询就像是询问数据库关于表内容的问题。 索引 如果再看一下图5.1,你就会注意到,表第一列中的项并没有按字母顺序排序。没错,数据库不存储你以特别的顺序发送给表的项棗事实上,如果数据库不排序的话,其效率可能会更高。如果每次某个人添加或删除记录时,数据库管理器都要重新排序表中所有的记录,你可能就做不了太多的工作了。不用说,你并非总是需要数据的顺序相同,所以两个人没有必要去争论数据的顺序是什么。一个人可能想要地址表以姓氏来排序,另一个人可能又需要表按ZIP代码排序。 注 数据库把数据放在表的末尾,不能保证会以什么样的顺序来查找未编索引的表中的数据。 那么,如何以某种顺序获得所需的信息呢?答案是索引。图5.1说明了每个记录都要考虑的两个原则。第一,索引不能包含整个表的所有项棗它只包含一个子集。在这里,它只包含第一个字段(列)内的项。第二,索引是有序的。索引包含了指向表中的记录的指针,不过图5.1没有显示出来。换言之,在选择记录时所看到的数据,和数据库管理器用来查找整个记录的指针是成对的。排序索引允许你快速地查找想要的那类数据。指针允许你查找表中的整个记录。使用索引还允许两个人以两种不同的顺序访问一个表中的数据。因为索引有序而表无序,所以可以为用户所需的每一种数据排序方式定义一个索引。 没必要把索引限制在单个表内使用。很多数据库管理器允许你创建跨越多个表的索引,只要那些表是相关的即可。例如,为了掌握客户的采购情况,可以创建两个表。第一个表包含客户列表,而第二个表包含每次采购的细节。索引可以用消费者ID字段加采购编号来排序两个表,首先是以客户为序,然后是以采购编号为序。 注 只要表以某种方式相关,索引就可以跨越多个表。 我们来看一看这个多表索引概念实际上是如何工作的。图5.2说明了多表索引的一个示例。请注意,Clients(客户)和Purchases(采购)表间是有关系的。两表中编号为0001的Client ID识别名叫Ann的客户。但是,Clients(客户)表只有Client ID的一个拷贝,因为一次只有一个客户可以使用Client ID。因为客户可以多次采购,所以Purchases(采购)表包含每个Client ID的多个拷贝。请注意,在Purchases(采购)表中记载Ann采购了$20。这次采购由编号为97001的Purchase ID识别。此外,每一个Purchase ID都是唯一的;否则,无法将一次采购与另一次采购区分开来。现在看一下索引。它包含两个值,Client ID和Purchase ID。它先由Client ID排序,然后由Purchase ID排序。虽然表是无序的,但是该索引却有序。索引中的指针允许你在两个表中查找信息。 不要认为索引也被限制在表内的直接项上。很多数据库程序员都发明了组合表项的方法,甚至可以用特殊等式产生非表的索引数据。很明显,数据库管理器制定的规则限制了把什么放入索引的选择。换言之,如果数据库管理器不允许,就不能把某种数字计算添加到索引中去。同时,如果以最初预想的顺序在屏幕上显示数据时有麻烦,可以先做一下试验。 注 一些DBMS不限制你在索引中使用哪些字段名;你也可以使用复杂的表达式。 可惜的是,Access没有提供在数据库设计视图中创建复杂索引的简明方式。可以创建包含多个字段的索引,可以分别控制那些字段排序的顺序,但是不能直接使用等式或者其它复杂的指令。在一些情况下,可以用SQL语句创建复杂的索引,但其本身就很复杂。幸运地是,你可以把复杂的索引作为查询的一部分来提供,我们会在本章的后面讨论这一点。 技巧 DBMS不允许直接向索引中添加等式或者计算值,但是,你可以通过向表中添加特殊的计算字段来实现这一点。该字段可以包含计算值,而索引又包含这个特殊的字段。例如,可以用Access完成这个工作。它允许用Expression Builder(表达式生成器)给一个字段赋缺省值。如果用户从来没有见过这个字段,那么结果就是你可以为了编索引而使用的特殊字段。如你所见,结果是一样的,只不过完成的方法稍稍复杂了一点。 查询 再看一下图5.1。我用来定义查询项的图标表示这是一个大概的看法棗查询是向数据库提出的有关它所包含数据的提问。可能会有人向你展示难以理解的复杂的SQL语句,试图让你相信,查询并不是一个简单的过程。一个简单的事实是,查询就是一个提问。 注 始终要记住,查询就是向数据库提出的有关它所包含数据的提问。 每个查询都有特定的部件,但这个信息只是帮助你以DBMS可以理解的方式来简述这个提问(请记住,DBMS实际上对操纵数据库的内容负责)。记住这一点,我们来看一看比较简单的SQL语句,它允许你查看两个相关表中的所有记录。 SELECT Foods.*, Orders.* FROM Foods INNER JOIN Orders ON Foods.Food_ID = Orders.Food_ID WHERE ((("Food_ID")<>"VEG-00001-SPL")) ORDER BY Foods.Food_ID; 首先我要指出,在使用Access时,没有必要使用像这样的SQL语句,除非你实在想用。Access会用Select Query(选择查询)对话框帮助你创建SQL语句。现在让我们看一看这条查询语句。 我们要做的第一件事是,选择两个表以及这两个表内的所有字段。SELECT语句要DBMS选择一些数据。Foods(食品)和Orders(订货)是两张表。出现在表名后的星号(*)要DBMS选择两张表中所有的字段。如果想选择特定的字段,应该以<table name>.<field name>格式输入字段名。 SQL语句的下一行看起来确实很复杂,但它所要做的,只是要DBMS建立两张表的关系。FROM关键字告诉DBMS主表是Foods(食品)。INNER JOIN说明如何创建与从表Orders(订货)的关系。ON关键字说明我们准备建立关系的字段。在这里,两张表都有一个同名的字段,我们就用它来创建关系。创建关系的标准是,有两个包含相同类型信息的字段,就像我在图5.2中说明的那样。在这种情况下,两个相关的字段都是ClientID。对主表中的每一个项来说,从表通常都包含多个项,虽然这并不是绝对要求的(对主表中的每一个记录,从表不是非得有一个项与之对应)。 可以用SQL来限制实际获取的记录数。在这里,我们告诉DBMS,不想看到Food_ID字段等于VEG-00001-SPL的任何记录。很明显,可以用任何标准来限制取回的记录数,选择标准可能变得非常复杂。 最后,ORDER BY关键字告诉DBMS你想如何排序记录。在这里,我们想基于Food_ID字段的内容以升序次序来排序记录。因为SQL允许完全利用表达式,所以你可以使ORDER BY子句要多复杂、就多复杂。可以用等式或其它任何所需的标准,以正好需要的顺序获取想要的数据。 Web链接 如果你确实想熟练掌握SQL,请看http://www.opengroup.org./ot/search.htm处的Open Group Web站点(Open Group是OSF和X/Open的组合)。输入SQL,然后在询问想要寻找的内容时单击Search(搜索)按钮。你会发现一系列的SQL规范。 与Access不同,Visual C++在大多数情况下会要求你手工创建这些SQL语句。时间不长你就会发现,在Access(或你正在使用的任何DBMS)中创建所需要的查询是提高开发速度的一种方式,尤其在你对编写SQL语句了解不多的时候更是如此。 注 窗体在屏幕上表示用查询从数据库收集到的数据。 窗体和报告 到现在为止,我们谈论了很多管理和存储问题。不错,在可以使用数据库之前,它要求内部管理结构全都正确,但是,如果不能以某种方式使用收集到的信息,那么确实没有任何理由说工作已经完成了。窗体和报告是实际使用数据库信息的两种最普通的方法。 注 报告通过打印表示用查询从数据库收集到的数据。 通常,窗体表示在屏幕上看到的数据,而报告表示发送到打印机的相同数据。窗体常常显示为已请求的所有记录的网格,或者一次只显示一条记录。报告总是显示已收集到的一系列完整的数据,但它通常不使用网格格式。典型情况下,报告提供已请求数据的某种结构化视图。 深入窗体 我们再来谈一谈窗体。如前所述,通常用两种方式来表现窗体中的数据:网格中的所有记录或者一次显示一条记录。图5.3显示了典型的网格视图,图5.4则显示了典型的单记录细节视图。网格法的主要优点是可以得到数据的整体印象。使用这种视图时,正确地排序数据一定会有好处棗当记录数超出一屏信息时,可以容易地看到记录之间的关系。例如,在以网格显示之前,可以用产品类型来排序库存数据库,这样就可以看到库存中有多少相似项。 使用数据网格视图的缺点也十分明显。不但所有的字段都挤在一起,而且如果不水平滚动的话,很可能看不到表(或表集)中全部的字段。当然,可以很快地获得许多记录的概述,但是看不到个别记录的完整情况。一些数据库应用程序克服了这种限制,允许从网格视图的一组记录中选择单个记录,然后再转换到单记录细节视图方式。 技巧 一定要放置你认为用户在设计网格视图窗体时最需要的字段。这样,才能极大地减少用户查找重要数据时必须做的水平移动次数。一旦根据重要性对数据进行了排序后,就可以实现第二步,把相似的数据聚集到一起。例如,把所有的电话号码保存在一个地址数据库中是非常有用的。这样,试图查找特定人的住址时,只要逐个调用号码就可以了。可以通过事件监视用户的使用,或者用应用程序实际地观察它们,以此来测试网格的排列。用户查找数据时所必须做的移动越少越好。 单记录视图有精确表示一个记录的优点。你可以看到记录所提供的一切。当然,一看到图5.4,这种表示的缺点立刻就明显了。不像网格视图,单记录视图不提供任何种类的概述。不能用它来分析趋势,或者得到整个表内容的更完整的情况。由于这个原因,单记录视图通常被保留作表数据的详细视图。一旦用网格视图找到了想要的东西,就可以用它来编辑或者验证要删除的记录。 注 用网格视图向用户提供可以用来选择记录的概述,然后用单记录视图让用户一眼就看到记录的全部细节。 第三种窗体视图你可能也会经常使用。它由添加了网格的单记录视图窗体组成。单个记录显示主表的内容。例如,它可能显示如姓名、地址和电话号码这样的客户信息。网格包含与主记录相匹配的从表内的记录。例如,网格可能包含一年中某客户进行的所有采购。 注 始终要避免数据过多而使得窗体杂乱无章。如果有必要的话,可使用多重窗体来避免屏幕杂乱。 可惜的是,要做出一个出色的组合型窗体是十分困难的。除非严格限制网格显示的字段数,否则网格会占据很多的屏幕资源。结果,很多组合窗体看起来都很拥挤,而且就是因为有太多的东西要看,反而很难看得见数据了。问题是,你想使查找数据很容易,而这限制了用户在任一给定窗体上的位移量。 单记录视图的另一种窗体使用多重窗体来避免屏幕杂乱的问题。假定实际上需要50个字段来描述才能了解库存中的一个项目。视图在一个屏幕上显示那么多的字段,就会产生极大的杂乱,没有人可以找到所需要的东西。在这里,应该创建一个概述记录中的数据的主窗体,然后由辅窗体提供详细的资料。例如,可以在一个辅窗体上放入库存注释,因为注释往往要占据很多的空间。还可以在分离的窗体上放入特定项目的厂商数据,因为在很多情况下,一般来说你不会再排序新的项目了。当然,添加辅窗体就是向主窗体中添加细节按钮,这会进一步减少可用的屏幕空间量。要权衡屏幕杂乱和一个窗体上按钮过多的混乱因素。在一些情况下,最好的答案是,除非确实需要某条信息,否则不要显示它。 深入报告 最初,人们设想计算机可以产生无纸办公室。现在好像并没有实现这一点。用计算机产生的报告比任何用打字机的办公室产生的报告还要多。事实上,创建报告是很容易的,以至于还没有真正地去思考时,报告纸就已经开始产生了。 传统的报告赋予你这样的能力,将信息存储在数据库中,并以纸的形式输出。但是,报告不必要再出现在纸上了。例如,如果你有一个Web站点,需要使雇员及时了解公司当前的状况,就可以发表能在Internet浏览器中阅读的形式的报告。电子邮件也在通信中发挥了更大的作用;你可能会发现,报告必须是电子格式,这样才能把它邮寄给别人。 不论报告采取哪一种形式,它都具有一些确定的特性,需要在创建过程中加以考虑,这些特性是:组织、目的和接受对象。下面各段就讨论要着重考虑的这些问题。 组织 在可以组织报告之前需要考虑,想在报告中看到哪种信息,该信息有多少是重复的。除去不需要的数据,为你想要查看的数据腾出空间棗当使用已打印的媒体时,这种考虑非常重要,因为在使用数据的时候就不能再用上它了。腾出空间的另一种方式是,使所有重复数据都在报告的同一行上。这个过程称为分组。创建分组不但节省了空间,还可以帮助报告的阅读者更快地查找到所需的信息。 目的 报告的目的确定,应该包括多少信息、摘要是否会替代详细的资料清单。既要给读者提供所需的全部信息,又不能让无用的信息使报告显得杂乱,这一点很重要。例如,没有必要把客户数据库的每一个细节都告诉经理;他们真正感兴趣的是最后一行:每个客户采购了多少,或者是每次采购的金额有多大? 我们再来看一看我在图5.2中介绍过的Clients和Purchases表。如果你为此表创建了采购报告,那么肯定想包括Purchases(采购)表中的全部摘要信息。但是,为了节省空间,最好把所有像Client ID和Name字段这样的客户信息用作标题,分组采购信息。在像这样的报告中,可能不需要所有的客户信息。例如,如果这个报告的目的是产生一个电话号码表,就可能无须添加地址信息。 如果想创建一个关于客户的一般报告该怎么办呢?在这种情况下,可能要包括Clients(客户)表中的所有客户信息,而排除Purchases(采购)表中像PurchaseID这样的信息。另外,可能只要简单地合计每个客户的采购值,并在报告中列入单个数字,而不是创建每次采购的详细清单。 接受对象(观众) 观众会影响编制报告的类型。例如,你可能会发现,给同事看的报告可以采用非常简单易读的格式。你可能需要这样的格式,因为这样的报告包括了很多详细的信息。另一方面,从管理角度讲,又要使报告更精致一些才行。 技巧 不要低估你作为程序员对报告的需求。当然,可以试着用屏幕上的窗体排除所遇到的数据库设置问题。但是,报告可以帮助你查找隐藏更深的错误。例如,你可能会发现,数据库有微妙的数学错误,你只有在打印数据库内容时才会看到它。如果只是在屏幕上看数据库内容,这个错误可能不是很明显。一定要把你设计的报告实际打印出来,才能看到它们在显示数据库的内容方面同样非常有效。虽然你是在用C++设计应用程序,但是了解DBMS本身能干些什么,会对在Visual C++环境内设计更好的报告有所帮助。 |
| 相关文章 | ||||
| 友情链接 | ||||||
| 设置首 页 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接 |
| |||||||