赛迪网 宋文明、杜建蔚
VFP数据库文件的备份形式一般有两种,一种是以记录格式,即以VFP表格(.dbf)进行存储,这种方法的优点是表的数据被按照原样进行备份,备注字段、通用字段等特殊字段不必进行特殊处理即可很容易地实现数据备份和数据恢复,缺点是记录格式一旦丢失,将造成记录无法恢复;另一种是将记录以文本格式进行备份,优点是文本数据比较稳定,不容易被损坏,缺点是备注字段、通用字段等特殊字段需要进行特殊处理,不容易实现自动备份和恢复。
小型数据库备份与恢复的原理
本文所说的小型数据库是指库文件容量不超过一张磁盘的数据库,对这种数据库,我们常用的备份方法是用: Copy to < 路径\backup1> 命令直接拷贝库记录,并生成backup1.dbf的表文件,如果原数据表有备注字段还会同时生成一个名为 backup1.fpt的备注文件,我们再用 Copy index indexfilename to <目标路径\filename1> 命令备份索引文件即可。
第二种方法是用 Copy to <路径\backup1.txt> 命令将原数据表备份成为一个文本文件 backup1.txt ,并用 Copy structure to <路径\backup1> 命令将原数据表的结构备份为backup1.dbf, 如果原数据表有备注字段的话也会生成备注文件backup1.fpt。注意在存储成文本文件时,如原数据表有备注字段时,拷贝命令不要用 Copy to <路径\backup1.txt> sdf,因为这样无法生成备注文件backup.fpt。恢复的办法是用 Copy structure to 命令恢复库结构,再用 Append from <路径\backup1.txt> 命令,即可将数据记录包括备注字段一并恢复。注意这种情况下一定要保证备份时生成的备注文件backup1.fpt是完好的。
大型数据库备份与恢复的原理
1.问题的提出
在一个系统中,当一个库文件大于1.44Mb时,无法用一张软盘进行备份时,本文称之为大型数据库的备份与恢复问题,这恰恰是最常见的情况。
2.分析
用 Copy to 〈路径\filename〉[〈scope〉] 命令可以将目前工作区中数据库的记录全部或部分拷贝到目标数据库文件中去。〈file〉是目标文件名,如果不给目标文件指定扩展名的话,系统默认扩展名为.dbf;用〈scope〉关键字控制记录拷贝操作,将适当的记录数备份到软盘上,这样就可以解决一张磁盘装不下的问题。而恢复的动作正好相反,只要利用命令将备份到各个磁盘的数据记录合并就可以了。
3.具体实现步骤
(1)对容量进行计算
设定默认路径为软盘所在驱动器,用diskspace()函数计算备份软盘的剩余空间,用recsize()函数对需要备份的数据库中的每条记录长度进行计算,然后用测试得的磁盘可用空间除以记录的长度,确定该软盘剩余空间能够备份数据库中多少条记录,当然这是最理想的情况即没有备注字段等特殊字段,否则还得考虑每条备注字段的大小。
(2) 将指定的数据记录备份到软盘
如果磁盘空间所能备份的记录数目大于数据库现有的实际记录数目时,直接用 Copy to 〈file〉备份。否则先移动记录指针到开始备份的记录号上,然后用 Copy to 〈file〉 Next 〈备份记录数〉备份,下一张盘备份时,让指针后移到需备份的记录处。
(3) 作好备份盘号、记录数等标记
为了备份盘管理和以后恢复时能够按正确的顺序进行,我们在拷贝完后,要将每一张盘的备份情况存入备份设置文件Bak.dbf中,以便恢复程序能够识别备份盘。
(4)恢复过程
恢复时读取备份设置文件以确认插入正确的备份磁盘,将原库中的记录全部删除,直接用Append命令将备份盘上的数据加入到数据库中,当考虑库结构损坏时,先恢复库结构再恢复数据。
备份与恢复示例
1.以数据表的形式进行备份
建立一个Bak.dbf文件(程序中需要用到),其数据库结构如下:
字段名 字段类型 宽度
diskinfo 字符 10
diskno 整型 4
(1)备份程序
以数据表的形式进行备份的程序如下:
set talk off
set safe off
clea
NUMOFDISK=0
sele 1
use <备份的数据库的路径+名称>
RECSIZE=RECSIZE()+2800
RECOUNT=RECCOUNT()
sele 2
use <路径\Bak.dbf>
zap
sele 1
GO TOP
do whil .not. eof()
?'请插入第'+STR(NUMOFDISK+1,3,0)+'张备份盘,然后按任意键继续'
wait''
SET DEFA TO A:
DISKSP=DISKSPACE()
RECNUM=DISKSP/RESIZE
FILE=SYS(3)
FILENAME='A:\'+FILE
COPY TO &&FILENAME NEXT RECNUM
SET DEFA TO
NUMOFDISK=NUMOFDISK+1
SELE 2
APPEND BLANK
REPL DISKINFO WITH FILE
REPL DISKNO WITH NUMOFDISK
SELE 1
enddo
?'备份完毕,共'+str(NUMOFDISK,3,0)+'张磁盘'
close all
return
(2)恢复程序
以数据表的形式进行数据恢复的程序如下:
set talk off
set safe off
clea
sele 1
use <欲恢复的目标数据库的路径+名称>
zap
sele 2
use <路径\Bak.dbf>
do while .not. eof()
?'请插入第'+STR(DISKNO,3,0)+'张恢复盘,然后按任意键继续'
wait''
BACKUP='A:\'+DISKINFO
IF .NOT. FILE(BACKUP)
?'磁盘不对'
LOOP
ENDIF
SELE 1
APPE FROM &&BACKUP
SELE 2
SKIP
enddo
?'恢复完毕,共'+str(diskNO,3,0)+'张磁盘'
close all
return
这个程序只是一个理想化程序,即源数据表没有备注字段(该字段直接影响到磁盘空间的计算),也不考虑被备份的数据表的索引字段,以及在该表库结构损坏时的情况。
在有备注字段的情况下,备注文件(backup1.fpt)预留出512字节的空间用于存放格式描述等再加上每条记录备注字段的大小,即lenth( 备注字段名)。如考虑每条记录备注字段的实际长度, 我们可在备注字段的验证规则中加入“len(备注字段名)<最大值”的判断语句,这样既便于计算磁盘空间又便于数据维护。当考虑数据库结构损坏的情况时,要先恢复库结构,接着恢复索引,最后再恢复数据。
2.以文本的形式进行备份(考虑了存在备注字段与库结构损坏的情况)
除了输出语句外,其余语句基本与以数据表形式进行备份的情况相同。
(1)备份程序
以文本的形式进行备份的程序如下:
set talk off
set safe off
clea
NUMOFDISK=0
sele 1
?'请插入库结构备份盘,然后按任意键继续'
wait ' '
use <备份的数据库的路径+名称>
copy stru to a:\backup1 with cdx
RECSIZE=RECSIZE()
RECOUNT=RECCOUNT()
sele 2
use <路径\Bak.dbf>
zap
sele 1
GO TOP
RECNUM =1
SIZOFMEM=LEN(备注字段)
do whil .not. eof()
?'请插入第'+STR(NUMOFDISK+1,3,0)+'张备份盘,然后按任意键继续'
wait''
SET DEFA TO A:
DISKSP=DISKSPACE()-(512+1)
&&&& 512为预留的备注文件的头文件大小,且有1间隔符
do whil .not. eof() and (DISKSP<(RECNUM* (RECSIZE()+1)+ SIZOFMEM))
RECNUM = RECNUM +1 &&&& "RECSIZE()+1"为记录长度+间隔符
SIZOFMEM= SIZOFMEM+len(备注字段)
skip
enddo
skip -RECNUM
FILE=SYS(3)
FILENAME='A:\'+FILE+'.txt'
&&&&备份的文件名的后缀为 .txt
COPY TO &&FILENAME NEXT RECNUM
SKIP RECNUM
SET DEFA TO
NUMOFDISK=NUMOFDISK+1
SELE 2
APPEND BLANK
REPL DISKINFO WITH FILE
REPL DISKNO WITH NUMOFDISK
SELE 1
RECNUM =0
&&&&完成一次备份后清空计数器
If .not.eof()
SIZOFMEM=LEN(备注字段)
&&&&取上次备份后的最后一条记录的下一条记录
endif
enddo
?'备份完毕,共'+str(NUMOFDISK,3,0)+'张磁盘'
close all
return
(2)恢复程序
以文本的形式进行数据恢复的程序如下:
set talk off
set safe off
clea
sele 1
?'请插入库机构恢复盘,然后按任意键继续'
wait ' '
use a:\backup1.dbf
recindex=sys(14,1)
&&&&获取文件索引
copy to <被恢复的目标数据库路径+文件名>
&&&&恢复库结构
index on recindex to indexfilename &&&&建立索引
sele 2
use <路径\Bak.dbf>
do while .not. eof()
?'请插入第'+STR(DISKNO,3,0)+'张恢复盘,然后按任意键继续'
wait''
BACKUP='A:\'+DISKINFO
IF .NOT. FILE(BACKUP)
?'磁盘不对'
LOOP
ENDIF
SELE 1
APPE FROM &&BACKUP
SELE 2
SKIP
enddo
?'恢复完毕,共'+str(diskNO,3,0)+'张磁盘'
close all
return
利用以上程序,我们可以实现VFP数据库的备份与恢复。
关键词:VFP数据库:Howto 备份与恢复