VSAM文件结构及管理
VSAM(Virtual Storage Access Method)文件是IBM 公司在虚拟存储器和树型数据结构的基础上,为了满足数据量大,存取速度快和维护方便的要求而发展起来的一种文件组织形式。
VSAM文件可分为以下几种组织形式:
1) 键顺序文件KSDS:这种文件与索引文件相似,由索引部分和数据部分组成。索引部分包含树型结构的多级索引。数据部分内的记录按键值顺序排列。因此,这种文件及可以按键值进行顺序存取,也可利用索引,根据键值进行直接存取。
2) 输入顺序文件ESDS:文件内的记录按输入顺序排列。因此,可以按照排列顺序进行存取,也可以指定记录的相对字节地址,对特定记录进行存取。
3) 相对记录文件RRDS:文件空间被划分为等长的SLOT,每个SLOT 只存放一个记录,从第一个SLOT 开始分别赋予连续的顺序号,这样的号码叫相对记录号。只要给出相对记录号,就可实现对特定记录的直接存取。
4) 线性文件LDS:只有数据组件,由应用去成组/分解逻辑记录。
1. VSAM 文件结构
VSAM 数据集中的数据除线性数据集外,都被组成记录(逻辑记录)。逻辑记录是用户访问数据集的单位。VSAM 的逻辑记录与非VSAM 数据集的存储方式不同。VSAM 将记录存于CI(Control Interval)。一个CI是直接访问存储设备的一片连续区域,用于存储数据记录及其控制信息。当从直接存储设备上读取一个记录时,包含要读的记录的整个CI都被读到虚存的VSAM I/O 缓冲中,然后用户要读的记录才从VSAM缓冲传输到用户定义的工作区。
一个VSAM 数据集在一个卷上可以占用最多119到123个Extent,或者占用4,294,967,296 个字节。
CI的大小在不同的VSAM 数据集中可以不同,但在一个数据集中必须相同。在创建数据集时,你可以用访问方法服务的DEFINE命令指定CI 的大小,也可以让系统自动选择CI的大小。
每一个CI 含有如下信息:
逻辑记录:每一个CI 中可能包含多个逻辑记录。
自由空间:每一个CI 中可能含有一定的自由空间,用于插入新的记录。
控制信息:主要为RDF 和CIDF,RDF 描述每一个记录的信息,而CIDF 则描述整个CI的信息。
注意:在线性数据集中,CI 全部是数据,无控制信息。
VSAM数据集中的多个CI成组为直接访问存储设备中的一片连续区域称之为CA(Control Area),一个VSAM数据集由一个以上的CA组成。CA 最大为一个柱面,最小必须是一个磁道。
有时一个记录的大小会大于一个CI的大小,在VSAM 中,你不必把这个记录劈开,也不必重新格式化这样的记录,因为在定义数据集时可以用SPANNED 参数指定记录可以跨多个CI。
VSAM 数据集有4 种类型:ESDS(Entry sequenced data set)、KSDS(Key Sequenced Data
Set)、LDS(Linear Data Set)、RRDS(Relative Record Data Set)。
ESDS:类似顺序文件。其记录长度可固定也可不固定,新记录只能加在数据集的末尾,已存在的记录不可被删除,如果你一定要删除一个记录,你只能把这个记录标记为不活跃,实际上并未被删除。记录的内容可以被修改但不能改变其长度。访问这样的数据通过其RBA(Relative Byte Address)来进行,RBA一般为双字整数,它表示逻辑记录从数据集起始位置的位移量。尽管ESDS 没有索引,但你可以建立一个次键索引,用以记录记录的RBA。
ESDS通过地址进行访问,因此可顺序访问也可随机访问。
KSDS:在KSDS中,每一个逻辑记录含有一个称之为KEY的字段,它唯一地标识一个记录,逻辑记录以KEY升序的顺序存放。KSDS 的记录大小可以固定也可以不固定。KEY必须唯一,必须在每个记录的同样位置,如果是跨CI的记录必须在记录的第一个CI中。记录可以被删除,新增加的记录按其KEY值的大小插入在合适的位置。定义KSDS后,未用的空间可以散布在整个数据集,以允许插入新的记录。当新的记录插入到一个CI中时,或已存在的记录大小改变时,其后的记录移动到后面的自由空间,以便于新的记录的插入。同样,当一个记录被删除或变小时,释放的空间可以回收,以便于以后使用。创建使你可以指定一个参数FREESPACE 指定每一个CI自由空间的比例。也可指定每个CA中自由空间的比例。
在KSDS 中,KEY可用于定位要插入的记录的位置,及读取已存在的记录。最有效地访问KSDS的方法是使用KEY。有以下几种方法:
用顺序的KEY 访问可用于读、修改、增加、删除记录。当你指定了顺序的访问方法时,VSAM 使用索引以升序或降序的顺序访问数据集。顺序处理可以从数据集的任何位置开始。
直接访问:同样也可用于读、修改、增加、删除记录。你可以指定一个KEY,以此KEY来访问数据集。这个KEY 可以是完整的KEY,也可以不完整。比如:你可以指定一个不完整的KEY AB,后面是任何字符。
跳跃的顺序访问: 同样也可用于读、修改、增加、删除记录。在这种方式下,VSAM 只读选中的记录,并以升序或降序的顺序。
地址访问:以记录的RBA 作为查找参数来访问。一般不建议这样访问。
LDS:LDS的CI大小总是4096字节,无控制信息。应用去成组/分解逻辑记录。用DIV MACRO访问。
固定长度的RRDS:有多个固定长度的SLOT 组成。每一个SLOT 有一个相对记录号,SLOT以相对记录号排列。每一记录占用一个SLOT。因此记录的位置是固定的,相对记录号也不能改变。无主索引和次索引。由于SLOT 可以为空,因此可以插入新记录,或删除已存在的旧记录,而不影响其它记录的位置。记录的RDF 指示出SLOT 是否为空。在RRDS中,每一个CI含有同样多的SLOT。SLOT的数目由CI的大小和记录的长度决定。
可变长度的RRDS: 可变长度的RRDS 与固定长度的RRDS 类似,每一个记录也有一个惟一的相对记录号,并且也以相对记录号的顺序存放。但没有SLOT。你可以为一个KSDS或ESDS 定义一个或多个次键索引。用它可以以与主键相同的方式访问数据集,次键可以不惟一,也就是说它可以指向多个数据记录。但是最多只能指向32767个记录。次键本身是一个KSDS,它包含索引组建和数据组件。数据组件中的记录含有次键,以及指向数据的指针。对ESDS 来说,指针是RBA;对KSDS 来说,指针是主键。在通过次键访问数据集之前,必须定义一个路径。可用DEFINE PATH 命令来定义路径。
2. VSAM数据集的定义、复制及删除
VSAM 数据集的定义
定义一个VSAM 数据集之前,应注意:
1) VSAM 数据集必须是编目的。
2) 可用TSO ALLOCATE命令、访问方法服务的ALLOCATE 或DEFINE CLUSTER 命令、动态分配或JCL。要用JCL 定义一个VSAM 数据集,SMS 必须活跃。
3) 如有必要可定义次键。
对一个KSDS来说,数据部件和索引部件合称为CLUSTER。 CLUSTER提供了把索引和数据部件统一处理的一种方式。数据部件用于存放数据。
索引部件由顺序集和索引集组成。
数据部件中的每一个CA在顺序集中都有一个对应的CI,它含有其对应的数据部件中的CA中的每一个CI的最大键值及其指针。所有顺序集中的CI又顺序地连接在一起。索引部件的其它部分构成了索引集。如图2.11所示,所有索引集和顺序集构成了一棵查询树。其中顺序集可用于顺序访问,而索引集和顺序集合起来可用于随机访问。
1)用访问方法服务命令定义VSAM 数据集
VSAM 数据集可以通过DEFINE CLUSTER 或ALLOCATE 命令来定义。当定义了CLUSTER后,VSAM 使用三个编目项描述一个CLUSTER:
-一个CLUSTER 项把CLUSTER 描述为一个部件。
-一个数据项描述CLUSTER 的数据部件。
-对KSDS 来说,一个索引项描述CLUSTER 的索引部件。
(1)关于VSAM 文件的属性
如果使用DEFINE CLUSTER 命令,数据和索引部件的属性可以与CLUSTER 的属性分别指定。
-如果你为CLUSTER 指定了属性,则CLUSTER 的属性同样适用于部件。
-如果你为CLUSTER 和部件都指定了属性,则部件的属性覆盖CLUSTER 的属性。
-如用ALLOCATE,则只能在CLUSTER 一级指定属性。定义VSAM 数据集时,要指定数据集的属性。如果SMS 活跃,你定义的数据集又是系统管理的数据集,你可以指定DATA CLASS,MANAGEMENT CLASS 和STORAGE CLASS。你也可以用系统默认的这些CONSTRUCT。CONSTRUCT 只能在CLUSTER 一级上指定。
以下是定义VSAM 数据集是有关的描述性信息:
INDEXED|NONINDEXED|NUMBERED|LINEAR:指定数据集的结构形式信息(KSDS、ESDS、RRDS、
LDS)。RECORDSIZE:指定记录的平均和最大长度。不适用于LDS。
注意:
1)可变长度的RRDS 用NUMBERED 和RECORDSIZE 定义,而平均记录长度和最大记录长度必须不同。
2)如果对于ESDS,KSDS 或可变长度的RRDS 数据集,记录长度小于最大记录长度,VSAM 把实际记录的长度记录在RDF 中。
KEYS:指示KSDS 中键的长度和位置。
CATALOG:指示CLUSTER 所在的编目的名字和口令。
VOLUMES:指示CLUSTER 所在的卷。
RECORDS|KILOBYTES|MEGABYTES|TRACKS|CYLINDERS:指示分配该数据集的空间的单位及大小。
BUFFERSPACE:指示在处理该数据集时,应分配的最小的缓冲.
以下是定义VSAM 数据集是有关的性能信息:
CONTROLINTERVALSIZE:指定CI 的大小。此参数必须大于记录的最大大小。对LDS 无效。
SPANNED:指示记录是否可以跨CI。不适用于RRDS 和LDS。
IMBED:指示是否将索引的顺序集放在相应的CA 中。如果是,则会提高数据集的性能,但会增加空间.对索引组件的VOLUMES:指示是否把索引组件放在另一个卷上。
FREESPACE:指示预留自由空间的大小。
以下是定义VSAM 数据集时有关的安全信息:
AUTHORIZATION:指定你自己的一个授权子程序,验证对此数据集的访问是否合法。
WRITECHECK:指示对此数据集写后是否要检查,以保证以后能读出。
ERASE:指示数据集被删除后,是否要彻底删除。
(2)VSAM 数据集的命名
定义CLUSTER 时,要指定CLUSTER 名。通常,CLUSTER 名就是JCL 中给出的DSNAME。也可以各自独立命名索引和数据部件。如果只指定了CLUSTER 名而未指定索引和数据部件的名字,VSAM 会自动产生索引和数据部件名字。VSAM 以下列方式产生索引和数据部件名字:
如果CLUSTER 的最后一个QUALIFIER 是CLUSTER,则数据部件和索引部件名字的最后一个QUALIFIER 分别替换为DATA 和INDEX。
例如:
Cluster 名: SALES.REGION2.CLUSTER
产生的数据部件名 = SALES.REGION2.DATA
产生的索引部件名 = SALES.REGION2.INDEX
如果CLUSTER 名的长度小于等于38 个字符,则分别在CLUSTER 名后加.DATA和.INDEX。
例如:
Cluster 名: DEPT64.ASSET.INFO
产生的数据部件名 = DEPT64.ASSET.INFO.DATA
产生的索引部件名 = DEPT64.ASSET.INFO.INDEX
如果CLUSTER 名长度在39 到42 之间,则在数据部件和索引部件名后分别加.D和.I。
例如:
Cluster 名: DEPTABCD.RESOURCE.REGION66.DATA1234.STUFF
产生的数据部件名 = DEPTABCD.RESOURCE.REGION66.DATA1234.STUFF.D
产生的索引部件名 = DEPTABCD.RESOURCE.REGION66.DATA1234.STUFF.I
产生索引和数据部件的名字后,VSAM 会查找编目,以保证产生的部件名字是唯一的。如国不一,则重新产生。
可以用访问方法服务ALLOCATE 或TSO ALLOCATE 命令定义一个暂时的VSAM 数据集。也用JCL 直接定义。系统管理的暂时的VSAM 数据集不需要指定数据集名,而由系统自动产生唯一的名字。如果一定要指定则必须以&或&&打头。
(3)为VSAM 数据集分配空间
定义数据集时,你或者SMS(通过指定DATA CLASS)必须指定数据集的空间分配。如果你自己指定则可以以记录数、千字节、兆字节、磁道数、柱面数为单位。为了保持设备的无关性,最好以记录数、千字节、兆字节为单位。你可以在CLUSTER 级,数据组件级或索引组件级指定空间大小,但最好在CLUSTER 或数据组件级指定。VSAM 分配空间的原则如下:
-如果指定了CLUSTER 和索引组件的大小,则数据组件的大小是CLUSTER 的大小减去索引组件的大小。
-如果只指定了数据组件的大小,则指定的大小全部分配给数据组件,索引组件再另外追加一部分空间。
-如果同时指定了数据组件和索引组件的大小,则按指定的大小建立数据集。如果你定义一个小于一个柱面的数据集,VSAM 以磁道为单位分配空间。此时,最好为数据组件指定首次分配的最大磁道数,并且不要指定数据或索引的第二次分配。分配时,VSAM检查指定的设备的柱面大小,如果要分配的数量大于等于设备的柱面大小,则CA 等于柱面大小,如果小于则CA 大小等于实际分配量。CA 最小为一个磁道。
用JCL 定义VSAM 数据集
除可变长度的RRDS 外,任何类型的VSAM 数据集都可以通过JCL 来定义。
例1.3:定义一个KSDS
//DDNAME DD DSNAME=KSDATA,DISP=(NEW,KEEP),
// SPACE=(80,(20,2)),AVGREC=U,RECORG=KS,
// KEYLEN=15,KEYOFF=0,LRECL=250
其中:
DSNAME:数据集的名字。
DISP:创建新的数据集,并保留。
SPACE:记录长80,首次分配20,追加分配5。
AVGREC:指示SPACE 中指定的分配量的比例因子是1。
RECORG:创建KSDS 。
KEYLEN:键长15。
KEYOFF:键在记录中的位置。
LRECL:逻辑记录长250 字节。
例1.4:创建一个系统管理的KSDS:
//DDNAME DD DSNAME=KSDATA,DISP=(NEW,KEEP),
// DATACLAS=STANDARD,STORCLAS=FAST,
// MGMTCLAS=STANDARD
例1.5:按照默认值创建一个VSAM 数据集。
//DDNAME DD DSNAME=DSVSAM,DISP=(NEW,CATLG)
装入数据到VSAM 数据集,数据集定义后,你可以装入数据到VSAM 数据集。
-装入ESDS 的记录可以是任何顺序。
-固定长度的RRDS 把记录装入到SLOT 中,其相对记录号不是逻辑记录的一部分。
-装入KSDS 的记录必须按键的升序排列,并且不得有重复键。
-装入可变长度的RRDS 的记录必须按键的升序排列,并且不得有重复键。
REPRO 命令可用于从顺序,索引顺序或VSAM 数据集装入数据。也可用于从一个LDS 装
入数据到另一个LDS。
装入数据到VSAM 数据集的示例可见例1.1。
复制数据集
你可用REPRO 作如下事情:
-复制或合并VSAM 数据集到另一个VSAM 数据集。
-复制或合并顺序数据集到另一个顺序数据集。
-把顺序或索引顺序的数据集转换为VSAM 数据集。
-把VSAM 数据集复制为顺序数据集。
-复制PDS 或PDSE 数据集的成员。PDS 或PDSE 数据集不能复制,但单个的成员可以复制。
例1.6:复制整个数据集:
//STEP1 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=A
//MASTER DD DSN=EXAMPLE.KSDS.MASTER,DISP=OLD
//BKUP DD DSN=EXAMPLE.SAM.BACKUP,UNIT=SYSDA,
// SPACE=(TRK,(2,1),RLSE),DISP=(NEW,CATLG)
// VOL=SER=PUB101,
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=6120)
//SYSIN DD *
REPRO INDATASET(MASTER) –
OUTDATASET(BKUP)
/*
你也可以只复制一部分记录。用FROMKEY 指定从哪一个关键字开始,用FROMADDRESS 指
定从哪一个记录开始; 用TOKEY 指定到哪一个关键字结束, 用TOADDRESS 指定到哪一个记
录结束。例1.7:
//STEP1 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=A
//SYSIN DD *
REPRO IDS(EXAMPLE.LASTNAME.INDEX) –
ODS(EXAMPLE.EXTRACT.ESDS) –
FROMKEY(DEAN) –
TOKEY (LLOYD)
/*
也可以归并两个数据集。例1.8:
REPRO IDS(INPUT) ODS(OUTPUT) REPLACE
定义次键
次键本身也是一个KSDS。它提供了另一种方法访问VSAM KSDS 和ESDS 数据集。
定义次键的步骤如下:
1) 定义CLUSTER。
2) 装入数据。
3) 用DEFINE ALTERNATEINDEX 命令定义次键。
4) 用DEFINE PATH 命令将次键与CLUSTER 相关联。
5) 用BLDINDEX 命令建立次键。也就是在索引中装入数据。
VSAM 用3 个编目项描述一个次键:
-一个次键项描述次键是一个KSDS。
-一个数据项描述次键的数据部件。
-一个索引项描述次键的索引部件。
定义次键需要指定的信息与定义一个KSDS 类似。如果次键允许许多不唯一的键,则RECORDSIZE 必须足够大。在定义次键时,如指定了UPGRADE 属性,则VSAM 数据集改变时,次键自动改变。
例1.9,假定你有一个数据集叫PAYROLL.MASTER,其主键是雇员名字,你想建立一个次键。则:
1) 定义次键:
DEFINE ALTERNATEINDEX (NAME(PAYROLL.DEPT.AIX) –
RELATE(PAYROLL.MASTER) –
VOLUMES(AIX001) –
UPGRADE) –
DATA (NAME(PAYROLL.DEPT.AIX.DATA) –
TRACK (5 5) –
RECORDSIZE(200 2096) –
KEY (7 65) –
NONUNIQUEKEY) –
INDEX (NAME(PAYROLL.DEPT.AIX.INDEX) –
IMBED)
2) 定义路径:
DEFINE PATH(NAME(RAYROLL.DEPT.PATH) –
PATHENTRY(PAYROLL.DEPT.AIX) –
UPDATE)
3) 在索引中装入数据:
BLDINDEX INDATASET(RAYROLL.MASTER) –
OUTDATASET(PAYROLL.DEPT.AIX)
以后你在使用这个数据集时,如果你在JCL 中的DD 语句如下:
//DD1 DD DSN=PAYROLL.MASTER,DISP=SHR
则表示你使用主键访问该数据集。如果你在JCL 中的DD 语句如下:
//DD1 DD DSN=PAYROLL.DEPT.AIX,DISP=SHR 则表示你使用次键访问该数据集。
删除数据集
使用访问控制服务的DELETE 命令可以删除数据集,你可以删除整个CLUSTER,也可以只删除次键或路径。在此我们不再详细给出命令的语法及实例,感兴趣的读者可参见有关参考资料。
好文章就应该CTRL+C,不是吗?:还是那只鱼-newcoin's blog[http://www.newcoin.info]
本文链接: http://www.newcoin.info/2009/12/15/27284.html/