资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,3.4,索引文件及其应用,3.4.1,索引文件及分类,1.,索引文件,索引文件:它仅由两个字段组成,一个字段是排序的关键字值(也可以是一个表达式),另一个字段是每个关键字在原始数据表中对应的记录号。例,在,Rsda.dbf,数据表中,以编号为关键字段并按升序建立的索引文件的示意图如下图所示。,1.,索引文件,原数据表中的顺序是按输入的顺序存储在表中的,,在索引文件中,记录是按索引关键字值的顺序排列的,,当要查找某一编号的记录时,,VFP,先在索引文件中查找该编号,找到后再根据对应的记录号,在数据表中将记录指针快速移动到该记录上。,一个索引文件中可以只有一个索引,也可以有,多个索引,。可以包含多个索引的索引文件称该文件为复合索引文件。在复合索引文件中,需要为每个索引指定一个索引标识名,以便于通过索引标识相互区分各个索引。,3.4.1,索引文件及分类,2.,索引文件的分类,VFP,支持传统的,单入口索引文件,(扩展名为,.IDX,)和,复合索引文件,(扩展名,.CDX,),其中,.IDX,索引文件中只包含一个索引,而,.CDX,索引文件中可以包含有一个或多个索引,所以称为复合索引文件。,复合索引文件,又可分为,结构化复合索引文件,和,非结构化复合索引文件,两种,其区别在于:结构化复合索引的主文件名与数据表的主文件名相同,并随着数据表的打开而打开,在添加、更改或删除记录时会自动进行维护;而非结构化复合索引文件的主文件名与数据表文件不同,必须用命令打开。,3.4.1,索引文件及分类,3.,索引的类型,(1),主索引,主索引通常是,数据表的关键字索引,,作为主索引的字段称为主关键字。主索引不能用在自由表中,而只能用在数据库表中,可用于在永久关系中建立参照完整性。创建主索引的字段,不允许有重复值,,且一个表,只能有一个主索引,。,例如,在数据表中,常用学生证号、身份证号、工作证号等作为主索引,而姓名可能有同名的情况,一般不能作为主索引。,3.4.1,索引文件及分类,3.,索引的类型,(2),候选索引,候选索引类似于主索引,,其索引值就不能有重复,值。与主索引不同的是,,一个数据表中可以有多个候选索引,,而且侯选索引不能用来在永久关系中建立参照完整性。,(3),惟一索引,惟一索引表示索引值只能取一个,如果有两个或两个以上的索引值,则只能取其中一个,因此,惟一索引使用时可能会隐藏一些记录。例如,若有两个同名的人员,将姓名字段作为惟一索引,则只能找到一个记录,另一个记录将不会找到。,3.4.1,索引文件及分类,3.,索引的类型,(4),普通索引,普通索引没有上面各索引的限制,是,允许重复索引值的索引,。作为普通索引的字段,其字段值可以重复,,也可以作为排序的依据,,但因为可能有多个相同的索引值,因此查询时会找到多个符合条件的记录。一个数据表中可以有,多个,普通索引。,3.4.2,创建索引文件,1.,建立结构化复合索引文件,(1),在表设计器中创建索引文件,(2),命令方式创建索引,【,格式,】INDEX ON,表达式,TAG,索引标识名,FOR,条件表达式,ASCENDING|DESCENDINGUNIQUE|CANDIDATEADDITIVE,【,功能,】,建立结构化复合索引文件。,USE RSDA,INDEX ON,编号,TAG NBH CAND,INDEX ON,性别,+CTOD(,出生日期,)TAG XBCSRQ,2.,建立独立复合索引文件,独立复合索引文件的扩展名也是,.CDX,,但其主文件名与数据表文件名不相同,且使用时还需单独打开。独立复合索引文件主要用来创建那些使用不太频繁的索引。,独立复合索引文件不能在表设计器中创建,命令建立。,【,格式,】,INDEX ON,表达式,TAG,索引标识名,OF,独立复合索引文件名,FOR,条件表达式,ASCENDING|DESCENDING,UNIQUE|CANDIDATEADDITIVE,USE RSDA,INDEX ON,编号,TAG bh OF Rs.cdx,INDEX ON,姓名,+STR(,职务补贴,)TAG xbbt OF Rs.cdx,3.,重新建立索引文件,在数据表的使用过程中,当增删记录或数据表中被索引文件使用的关键字段改动时,,结构化复合索引会随着数据表的打开自动打开并能及时得到更新,,但如果在使用数据表时未打开相应的独立复合索引文件或传统的单入口,.IDX,索引文件,则索引文件会因为无法及时更新而产生错误索引。这时须打开索引文件,并对其重新索引。,重执行一遍,INDEX,命令即可重新索引,更简捷的方法是在浏览窗口中打开数据表,然后选择菜单,“,表,”,、,“,重建建立索引,”,命令,或打开数据表后用,REINDEX,命令重新建立索引。,【,格式,】,REINDEX,3.4.3,索引文件的使用,1.,指定主控索引,一个数据表可以建立,多个索引文件,,每个索引文件中又可能包含,多个索引,,而一种索引就是一种排序方式,所以,在使用索引时,必须指明哪一个索引是对数据表记录排序起作用的,即指定主控索引。在没有指定哪一个索引为主控索引之前,数据表的,访问顺序,仍然是原来的物理顺序,即按记录号的顺序访问。,主控索引和主索引是完全不同的概念。主索引是用来控制数据的完整性的,而主控索引是用来指定目前记录排列顺序的。,1.,指定主控索引,(1),指定结构化复合索引文件中的索引为主控索引,在浏览窗口中打开数据表(以表,Rsgz.dbf,为例),选择菜单,“,表,”,、,“,属性,”,命令,即弹出,“,工作区属性,”,对话框,单击,“,索引顺序,”,下拉列表,选择一个索引标识名,浏览窗口中记录的排列顺序会立即根据选择的主控索引发生变化,设定主控索引后,利用,LIST,、,DISPLAY,命令输出的记录顺序也是排序后的顺序。,需要特别强调的是,,主控索引只是改变了记录的输出顺序,,记录在数据库中的顺序并没有发生变化。,通过,VFP,的,USE,命令和,SET ORDER TO,命令也可以指定主控索引。,【,格式一,】,USE,数据表名,ORDER TAG,ASCENDING|DESCENDING,【,格式二,】,SET ORDER TO TAG ASCENDING|DESCENDING,【,功能,】,指定结构化复合索引文件的索引为主控索引。,(2),指定独立复合索引文件中的索引为主控索引,对于独立的复合索引文件或单入口的索引文件,需要用命令将其打开和关闭,只有打开要使用的独立复合索引文件后,才能指定其中的索引为主控索引。,【,格式一,】,USE ORDER TAG ,OF ASCENDING|DESCENDING,【,格式二,】,SET INDEX TO TAG OF,(4),关闭索引文件,【,格式一,】,SET INDEX TO,【,格式二,】,CLOSE INDEX,2.,控制重复值,人事档案,Rsda,表中的编号字段,是用来惟一标识一位职工的,所以该字段的值是不允许重复的。利用主索引可以解决这个问题,只要为编号字段建立索引,并将索引类型设置为主索引,3.,使用索引快速查找记录,FIND,命令和,SEEK,命令都可在指定主控索引的情况下进行记录的查找操作。,】,SEEK,表达式,USE Rsda ORDER TAG bh,&,打开,Rsda,同时指定,BH,为主控索引,SEEK 03001,SET ORDER TO rq,&,重新指定,rq,为主控索引,SEEK CTOD(1988.09.06),&,日期格式要与设置相同,否则会出错,DISPLAY,3.5,数据表的统计计算,3.5.1,累加求和及求平均值,对每个记录的,横向求和,和统计可以用前面介绍的操作或命令方便地给出,如,REPLACE,命令。对于每个记录的,纵向求和,统计可以用,累加求和,命令实现。,【,格式,】,SUM|AVERAGE,表达式表,范围,FOR,条件表达式,WHILE,条件表达式,TO,内存变量名表,|TO,数组变量名,【,例,】,求出,Rsgz.dbf,中计算机系所有职工的月基本工资平均值及全年实发工资之和并显示。,CLEAR,SET TALK OFF,USE Rsgz,AVERAGE,基本工资,TO pj_jbgz FOR SUBSTR(,编号,1,2)=03,SUM,实发工资*,12 TO qn_sfgz FOR SUBSTR(,编号,1,2)=03,?,计算机系职工的月平均工资为:,pj_jbgz,?,计算机职工的全年实发工资之和为:,qn_sfgz,USE,SET TALK ON,RETURN,3.5.2,统计记录个数,【,格式,】,COUNT,范围,FOR,条件表达式,WHILE,条件表达式,TO,内存变量名表,|TO,数组变量名,3.5.3,分类汇总,分类汇总对已经建立了索引并且指定了主控索引的数据表,可以按关键字进行分类求和,【,格式,】TOTAL ON,关键字表达式,TO,新表名,FIELDS,字段名表,范围,FOR,条件表达式,WHILE,条件表达式,2,当前数据表必须是按关键字表达式索引过,并指定该索引为主控索引,以保证具有相同关键字值的记录能连续访问。,FIELDS,短语给出了需分类求和的字段名,这些字段只能是数值型或货币型的,如果缺省,则对当前表中的所有数值型或货币型字段分类求和。不管选不选,FIELDS,短语,新表与当前表的结构是一样的。,对当前数据表中的若干个关键字表达式相同的记录,生成新表中的一条记录。这条记录的非数值型或非货币型字段取自关键字相同的一组记录中首记录的相应字段,参加求和的字段值取自求和结果。,3.6,数据交换,3.6.1,数组与数据表的数据交换,1.,将数据表中的记录数据保存到数组中,【,格式一,】SCATTER FIELDS,字段名表,MEMO TO,数组名,【,格式二,】COPY TO ARRAY,数组名,FIELDS,字段名表,范围,FOR,逻辑表达式,【,功能,】,将当前打开的数据表中的某些记录数据存储在数组中。,2.,将数组中的数据传递到当前数据表中,【,格式一,】GATHER FROM,数组名,FIELDS,字段名表,MEMO,【,格式二,】APPEND FROM ARRAY,数组名,FOR,逻辑表达式,FIELDS,字段名表,【,功能,】,将数组中各元素的数据传递给当前打开的数据表中。,注意:请读者将,COPY TO ARRAY,与,SCATTER,、,APPEND FROM ARRAY,与,GATHER FROM,的差别搞清楚。,3.6.2,文件复制,1.,复制部分记录或整个数据表,【,格式,】,COPY TO,表文件名,FOR|WHILE ,FIELDS,DATABASE NAME,WITH CDX|WITH PRODUCTION,|SDF|SYLK|WK1|WKS|WR1|WRK|XLS|XL5,|DELIMITED WITH|WITH BLANK|,2.,复制数据表的结构,【,格式,】,COPY STRUCTURE TO,表文件名,FIELDS,字段名表,WITH CDX|WITH PRODUCTION,说明:,若不选可选项,生成的表结构具有与原数据表相同的字段名、类型和宽度。,若选,FIELDS,子句,生成的表结构只有字段名表中的字段,字段名之间用逗号隔开。,CDX,和,PRODUCTION,的意义与复制记录时的意义一致。,3.7,多数据表操作,在一个数据库中,一般都有着许多个数据表。而在对这些表的使用中,也经常是多个表中的数据同时被用到。,VFP,提供了强有力的多数据表操作能力,引入了,工作区,和,表的别名,这两个概念。用户可以在不同的工作区中同时打开多个表,也可以在不同的工作区打开同一个表,通过表的别名,用户可以引用在不同工作区打开的表中的数据。,3.7.1,工作区的基本概念,所谓,“,打开,”,数据表,实际上就是,VFP,在内存中开辟了一个区域(亦称缓冲区)与磁盘上数据表之间建立起一种映射关系,使,VFP,通过缓冲区使用磁盘上数据表里的数据,这个内存中的缓冲区就称为工作区。,1.,工作区的性质,(,1,)在每,一个工作区中,只能打开一个表,,,VFP,最多可以开辟,32767,个工作区,打开,32767,个表。,允许一个表在,几个工作区,中同时打开,。,(2),在某一时刻,只能选择一个工作区为,“,当前工作区,”,,对其中的表进行操作。,系统初始状态默认,1,号工作区为,当前工作区,。,(,3,)每一工作区打开的数据表都有各自的记录指针。,在一般情况下,,对数据表的操作只能移动当前工作区的记录指针,。当使得数据表之间建立临时关系以后,另一工作区的记录指针才能根据要求伴随当前工作区的记录指针作相应的移动,。,(,4,),内存变量,对各工作区是公用的,,每一工作区的,字段变量,对其它各工作区也是公用的。,在任意工作区都可以对其它工作区的当前记录进行,读、写,操作,。,工作区的编号和别名,为了标识每一个工作区,系统给每一工作区编号,号码为,1,、,2,、,、,32767,。同时还为工作区规定了别名,其中,1,至,10,号工作区别名为,A,、,B,、,、,J,;,11,至,32767,号工作区别名为,W11,、,W12,、,、,W32767,。,给数据表命名时,,不要与工作区的别名冲突,,否则容易引起混乱。,数据表别名,在打开数据表的同时,可以为数据表起一个别名,这个别名也作为,打开该数据表的工作区别名,。,格式,USE,ALIAS,IN,|,AGAIN,说明:,若不指定工作区,则默认为在当前工作区上打开指定的数据表,并,同时关闭以前在当前工作区上打开的数据表,。,ALIAS,为可选项,不指定别名时,原数据表名就是它的别名。例如,当执行了命令,“,USE Rsda ALIAS da,”,后,表,Rsda,的别名就是,da,;而执行了命令,“,USE Rsda,”,后,则默认,Rsda,表的别名。,若选择了,IN 0,短语,表示在当前没有使用的编号最小工作区上打开数据表。,该命令只是在指定的工作区上打开数据表,,并不能改变当前工作区,。改变当前工作需要单独的命令。,一旦一个工作区上打开了一个数据表,,数据表就和该工作区建立起对应关系,,所以打开数据表后可以用数据表的别名来代替工作区别名。,3.7.2,工作区的选择和使用,1.,选择工作区,(1),利用,“,数据工作区,”,窗口选择工作区,选择,窗口,菜单中的,数据工作期,命令,或单击常用工具栏中的,数据工作期窗口,按钮,打开,数据工作期,窗口。,这时默认当前工作区为,1,。单击打开按钮选择一个数据表打开。若再次单击打开按钮,可以依次在其它工作区打开其它数据表,并且,可以用显示的,别名,选择工作区,。,在数据工作期窗口还可以浏览各工作区打开的数据表,还可以关闭他们。,(2),利用,SELECT,命令选择工作区,格式,SELECT|,说明:,选择当前工作区,,选择的工作区中可以是在前面已经打开了数据表,也可以是未曾打开表。,例:,USE Rsda,&,默认在,1,号工作区打开,Rsda.dbf,SELECT d,&,选择,4,号工作区为当前工作区,USE Rsgl,&,在当前(,4,号)工作区打开,Rsgl.dbf,USE Rsgz ALIAS gz,&,在当前,4,号工作区打开,Rsgz,,同时关闭,Rsgl,SELECT 1,&,选择,1,区为当前工作区,LIST,&,显示当前(,1,号)工作区数据表(,Rsda,)的记录,SELECT gz,&,或,SELE 4,SELE d,但不能,SELE Rsgz,LIST,&,显示,Rsgz,的记录,SELE Rsda,&,是否可以?为什幺?,LIST,?SELECT(),&,给出当前工作区号函数,返回当前工作区号,USE Rsgl IN 10,?SELECT(),USE,&,关闭当前工作区上的数据表,USE Rsgl IN 0,?SELECT(),2,在不同工作区打开同一个数据表,例,SELE 1,USE Rsda,USE Rsda ALIAS da IN 3 AGAIN,SELE 2,USE Rsda AGAIN,3.,使用非当前工作区中表的数据,方法是在非当前工作区的表的字段名前加注工作区别名或表的别名。格式为:,-,或,.,注意,这里的符号,“,-,”,是,“,-,”,和,“,”,两个(均为半角)符号复合而成。,例,SELE 2,USE Rsgl&,未指定主索引顺序,指向号记录,USE Rsda IN 3,SELE 3,LOCATE FOR,姓名,=b-,姓名,&,指向同个人,DISPLY,部门名,姓名,出生日期,,c.,工作日期,显示结果如下,:,记录号 部门名 姓名 出生日期,C-,工作日期,1,机关 韩伟东,1960.10.10 1985.09.04,在,VFP,中,表之间关联有,临时关系,和,永久关系,两种关联,1.,设置表的临时关系,(1),利用数据工作期窗口建立表的临时关系,3.7.3,数据表的关联,(2),利用命令建立表之间的临时关系,【,格式,】,SET RELATION TO,关键字表达式,|,数值表达式,1,INTO,工作区别名,1,|,子表别名,1,关键字表达式,2,|,数值表达式,2,INTO,工作区别名,2,|,表别名,2,ADDITIVE,说明:,必须选择父表所在工作区为当前工作区,然后再使用本命令与非当前工作区中的数据表(子表)建立关联。,选,ADDITIVE,项可使父数据表与子表建立关联时,原先已存在的关联仍然保留。如果不选用该项,则建立新关联时将取消原有关联。,子表必须按关键字表达式中的关键字段建立索引,且被指定为主控索引,。若选择数值表达式,则两个表是按照记录号相联系,此时子表不要求索引。通常情况下,用两个表都具有的相同字段作为建立临时关系的关键字表达式。,不选任何可选项则取消已与当前表建立的关联。父表可以与多个子表建立关联。,建立临时关系以后,父表和子表记录指针的移动的规则是:父表指针每移动到一个记录,子表则按关键字表达式的值进行索引查找,并将记录指针定位在相应记录上。若子表中没有记录和父表的当前记录相关联,子表的记录指针将指向,EOF,;若子表中有多个记录和父表的当前记录相关联,则子表的记录指针将指向第一个相匹配的记录。,【,例,】,某书店有一个图书库存数据表,Tskc.dbf,,存放有该书店所有的图书信息,另有一个图书调价数据表,tstj.dbf,,其中存放着图书调价后的新价格,现要求编制程序,用,Tstj.dbf,中的单价数据更新,Tskc.dbf,中的单价数据。假设,Tstj.dbf,数据表中的记录和,Tskc.dbf,中的记录是一一对应的,即凡是出现在,Tskc.dbf,中图书都调价了,则可用如下的程序:,SET TALK OFF,SET SAFETY OFF,USE TSKC,SELECT 2,USE TSGXTJ,INDEX ON,图书编号,TAG TSBH,SET ORDER TO TSGH,SELECT 1,SET RELATION TO,图书编号,INTO B,REPLACE ALL,单价,with TSTJ.,单价,CLOSE ALL,SET SAFETY ON,SET TALK ON,RETURN,2,设置表间的永久关系,永久关系,是存储在数据库文件(,.DBC,)中的数据表之间的关系,,它作为数据库的组成部分一直保留。它不像临时关系每次打开数据表时都要重新建立。,数据库中的数据表建立永久关系后,借助这种关系不仅仅从当前选定的表中访问数据,而且还可以访问相关数据表中的数据。,当在查询设计器,视图设计器、表单设计器中的数据环境中使用这些数据表时,这些永久关系将作为这些表之间的默认连接关系自动出现。而且以后使用查询文件,视图文件及表格文件时,这些永久关系也自动把相关数据表连接起来。,与永久关系的作用不同,临时关系是控制表之间,记录指针,的连动关系,。永久关系不具有这个功能,而是使,相关数据建立连接,关系,。,在永久关系中还可以建立参照完整性,对各数据表之间进行完整性约束。,表之间关系的类型,表与表之间的关系实际上就是,,按照某一关键字建立的几个数据表之间,相关记录,的关系,。,根据一个表中的记录与另一表中相关记录之间的对应数量关系,关系的类型可分为:,一对一关系,:是指一个表中的一个记录与另一表中的唯一记录相关联。,一对多关系,:是指一个表中的一个记录与另一表中的多个记录相关联,但另一表中的一个记录则只能与这个表中的唯一记录相对应。,在关系数据库设计时,应避免将表设计成,“,多对多关系,”,,通过数据规范化设计将,“,多对多关系,”,转换成,“,一对多关系,”,来建立数据库。也可以在两个表间建立一个连接表,两个表分别和连接表建立一对多关系,间接实现多对多关系,(,1,)建立表间的永久连接,建立,Rsbm,与,Rsgl,的关联、,Rsgl,与,Rsda,的关联。,Rsgl,与,Rsda,根据编号建立一对一的关联,;由于在,Rsbm,中一个部门可以在,Rsgl,中找到多条记录,所以两个数据表之间的关系为,一对多,的关系。两个表已根据共同字段,“,部门名,”,建立了索引,,“,一,”,方(,Rsbm,)建立了以,“,部门名,”,为索引标识的主索引,,“,多,”,方建立了以,“,部门名,”,为索引标识的普通索引。,在数据库设计器中建立永久关系,(2),编辑数据表之间的关联,3.8,管理数据库,3.8.1,使用多个数据库,1,在项目中新建或添加数据库,2,从项目中移去数据库,3,打开多个数据库,4,设置当前数据库,5,访问其它数据库中的表,OPEN DATABASE Rsgl.dbc,&,打开数据库,Rsgl,OPEN DATABASE Example.dbc,&,打开,Example,并自动将其设为当前数据库,?,DBC(),&,显示当前数据库名,SELECT 4,&,选择第,4,工作区为当前工作区,USE Rsgl!Rsda.dbf,&,在第,4,工作区上打开数据表,BROWSE,&,浏览当前工作区(第,4,工作区)上的数据,SELE 2,&,选择第,2,工作区为当前工作区,?,Rsda.,姓名,&,显示,Rsda,数据表的当前记录的姓名字段,6,关闭数据库,SET DATABASE TO Rsgl,CLOSE DATABASE,另外,用,CLOSE ALL,命令可以关闭所有打开着的数据库及其他文件。,3.8.2,向数据库中添加和删除表,1,向数据库中添加表,2,将数据表从数据库中移走,项目管理器中选择要移走的数据表,单击,“,移去,”,按钮,系统即弹出确认对话框,,单击,“,移去,”,命令,即可将选定的数据表从数据库中移走,成为自由表;若,单击,“,删除,”,按钮,则可将选定的数据表从磁盘上删除。,3.8.3,参照完整性,参照完整性是为确保数据库中表间关系不被破坏而设置的一组规则。在用户修改、增加或删除相关表中的记录时,参照完整性将起保护作用。怎样才算破坏了连接关系呢?如建立了,Rsbm,和,Rsgl,两表的一对多关联,在此关联下,如果进行了如下操作,:,(1),将,Rsbm,(父表)中一个父记录删除,而没删除,Rsgl,(子表)中所对应的一或多个记录,造成子记录无对应的父记录。,(2),修改了,Rsbm,(父表)中某个记录的部门名,而没有修改子表,Rsgl,的相对应的记录,从而造成,rsgl,(子表)中一个或多个记录没有对应的父记录。,(3),在,Rsgl,(子表)中增加了一个无父记录与其对应子记录。,解决不完整性的一般方法是编写触发器和存储过程代码来实现,但方法复杂。,VFP,中参照完整性生成器可帮助用户建立参照完整性。,1.,建立参照完整性,打开下图所示的参照完整性生成器的三种方法,:,级联:若选择该项,当更新某一父数据记录的关联字段时,,VFP,将自动更新与此数据记录对应的子数据记录的关联字段的值。这样,原来父记录与子记录间的对应关系仍存在。而当删除某一父记录时,系统将会自动删除所有与该父记录对应的子记录。,限制:若选此项,当对父表数据进行操作时,系统将先检查子表中是否有记录与之相关联,如果有则不允许更新该父数据表记录的关联字段,同样也不允许删除该父数据表记录,也不允许插入没有父表中的记录与之对应的子表中的记录。,忽略:选此项,系统将不进行任何参照完整性的检查工作。这是默认设置。,2.,修改参照完整性,修改参照完整性的步骤与建立参照完整性类似。,参照完整性常常通过一个程序代码函数过程来实现,这样的函数过程保存在数据库的,“,存储过程,”,中,与数据库一起存放。可以用命令,MODIFY PROCEDURE,查看存储过程的程序代码。,
展开阅读全文