数据迁移挑战 - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

数据迁移挑战

除关系数据库外,大多数大型机环境还具有物理数据集的组合,例如,序列文件和虚拟存储访问方法(VSAM)文件。数据库迁移通常依靠工具来提取、转换数据并将其注入目标数据库。本节概述了物理数据集面临的挑战。

字符集转换

您必须使用转换表将数据文件从 EBCDIC 转换为 ASCII。转换表描述了应用于文件中每个字节的 byte-to-byte 转换。您可以使用转换表正确转换包含带有显式符号字符的字母数字和数字数据的 COBOL 文件。

下表显示了使用 EBCDIC 到 ASCII 转换表时,哪些数据类型会受到转换问题的影响。

无字符集转换问题的数据类型

有字符集转换问题的数据类型

PIC X(n)

PIC S9(n)

PIC A(n)

PIC S9 还是 9 BINARY/COMP

PIC 9(n)(无符号)

PIC S9 还是 9 COMP-3

PIC S9(n) SIGN SEPARATE

分区十进制格式

分区十进制格式的数据看起来就像普通的字符数字数据。区别在于符号的存储方式。除符号指示符外,分区十进制字段看起来就像普通的数值显示字段,如 PIC S9(n) 表示有符号的数字显示字段,PIC 9(n) 表示无符号的数字显示字段。在分区十进制字段中,符号存储在最后一个字节的高半字节。

下表显示了存储在数据中的值,在 EBCDIC 和 ASCII 值中表示为 "+/-" 1–9。

数字

EBCDIC 十六进制二进制

EBCDIC 显示

ASCII 十六进制二进制

ASCII 显示

+0

X"C0"–1100 0000

{

X"30"–0011 0000

0

+1

X"C1"–1100 0001

A

X"31"–0011 0001

1

2+

X"C2"–1100 0010

B

X"32"–0011 0010

2

+3

X"C3"–1100 0011

C

X"33"–0011 0011

3

+4

X"C4"–1100 0100

D

X"34"–0011 0100

4

5+

X"C5"–1100 0101

E

X"35"–0011 0101

5

+6

X"C6"–1100 0110

F

X"36"–0011 0110

6

+7

X"C7"–1100 0111

G

X"37"–0011 0111

7

+8

X"C8"–1100 1000

H

X"38"–0011 1000

8

+9

X"C9"–1100 1001

I

X"39"–0011 1001

9

-0

X"D0"–1101 0000

}

X"70"–0111 0000

p

–1

X"D1"–1101 0001

J

X"71"–0111 0001

q

-2

X"D2"–1101 0010

K

X"72"–0111 0010

r

-3

X"D3"–1101 0011

L

X"73"–0111 0011

s

-4

X"D4"–1101 0100

M

X"74"–0111 0100

t

-5

X"D5"–1101 0101

N

X"75"–0111 0101

u

-6

X"D6"–1101 0110

O

X"76"–0111 0110

v

-7

X"D7"–1101 0111

P

X"77"–0111 0111

w

-8

X"D8"–1101 0100

Q

X"78"–0111 1000

x

-9

X"D9"–1101 1001

R

X"79"–0111 1001

y

例如,如果 PIC S9(4) 包含值 "-1234",则其值在 EBCDIC 中存储为 X"F1F2F3D4"。在 EBCDIC 到 ASCII 转换表中查找每个字节,然后将其转换为相应的 ASCII 值。在此示例中,前三个字符从其 EBCDIC 数值正确转换为 ASCII 数值 X"313233"。但最后一个字符(包含过冲符号半字节 X"D4" "M")将转换为 "M" 的 ASCII 等效项,即 X"4D"。

此分区十进制字符的正确 ASCII 值为 X"74" "t"。如果您使用 EBCDIC 到 ASCII 转换表来转换此字段,则结果是 X"3132334Dv" "123M",而不是正确的 X"31323374" "123t"。如果您未正确处理这些数据,则可能会在应用程序中出现数据损坏和无效数字数据错误。

二进制(COMP 或 COMP-4)

二进制(COMP 或 COMP-4)数据以二进制格式存储。COMP 字段通常以两个字节的倍数形式存在,用于存储超出等效数字显示项的数字范围的数字数据值。例如,PIC 9(4) 是一个 2 字节数字显示项,可以包含值 "0000"–"9999"。值 "1234" 在 EBCDIC 中存储为 X"F1F2F3F4",转换为 ASCII 时存储为 X"31323334"。

PIC 9(4) COMP 是一个 2 字节二进制字段(与 C 语言中的 short int 相同),可包含值 "0"-"65535"。在显示数字字段中存储最大值需要一个 PIC 9(6),它会消耗两个额外的字节。下面的示例显示了以二进制表示的值 "1234"。

字节 1

字节 2

0

0

0

0

0

1

0

0

1

1

0

1

0

0

1

0

前面的示例以十六进制(hex)数据表示,包含值 X"04D2"。如果使用 EBCDIC 到 ASCII 转换表来转换此数据,则数据将转换为 X"1A4B"。当解释为数字时,值为 "6731",而不是预期的 "1234"。

COMP 数据不需要转换,因为它在 EBCDIC 和 ASCII 中的存储方式相同。如果不正确处理 COMP 数据,可能会导致数据损坏。因为 COMP 数据项中的每个值都是有效的数值,所以应用程序不会报告任何数值处理错误。这个值是不正确的。如前面的示例所示,"1234" 值变为 "6731"。

压缩十进制格式(COMP-3)

COMP-3 字段通过仅存储每个字节的低半字节,每个字节存储两位数。例如,值 "1" 在 EBCDIC 中以 X"F1" 表示,在 ASCII 中以 X"31" 表示。值 "2" 在 EBCDIC 中以 X"F2" 表示,在 ASCII 中以 X"32" 表示。在 COMP-3 字段中,每个字节的半字节存储在单个字节中。因此,ASCII 中的值 "12" X"F1F2" 或 X"3132" 在 COMP-3 中存储为 X"012C"。

COMP-3 字段包含一个 "C" 字符(表示最后一个字节的低半字节中无符号和正符号值)和一个 "D" 字符(表示负符号值)。COMP-3 数据不需要转换,因为它在 EBCDIC 和 ASCII 中的存储方式相同。如果使用 EBCDIC 到 ASCII 转换表来转换 COMP-3 数据,则数据会损坏,并且应用程序中会出现无效的数字数据错误。

复杂的记录布局

将数据文件从 EBCDIC 转换为 ASCII 时,包含分区十进制、COMP 或 COMP-3 字段的文件并不是唯一需要考虑的问题。文件本身可以包含不同的记录布局,甚至可以包含使用 REDEFINES 子句来引入需要特殊处理的数据区域组合的区域。在这种情况下,请使用 Micro Focus 数据文件编辑器创建一个用来定义文件结构的记录布局,以便将其从 EBCDIC 正确转换为 ASCII。在开始创建记录布局之前,必须先确定要使用的文件类型和结构。可能的类型如下:

  • 包含非文本数据的单一记录结构

  • REDEFINES 区域内包含非文本数据的单一记录结构

  • 包含非文本数据的多个 01 记录结构

包含非文本数据的单一记录结构

包含非文本数据的单一记录结构是指任何包含单个 01 记录区域且无 REDEFINES 的文件,其中数据区域包含 ZD、COMP 或 COMP-3 数据类型。包含非文本数据的单一记录结构需要使用 Micro Focus 数据文件编辑器构建的简单“默认记录布局”。以下示例显示了包含非文本数据的单一记录结构。

01 S-PARTS-RECORD. 05 S-PART-ID PIC 9(9) COMP. 05 S-PART-TYPE PIC X(2). 05 S-PART-NAME PIC X(40). 05 S-SUB-PART-DATA. 10 S-SUB-DESC PIC X(40). 10 S-SUB-COST PIC S9(4)V99 COMP. 10 S-SUB-WEIGHT PIC 9(4)V99 COMP-3. 10 FILLER PIC X(34).

REDEFINES 区域内包含非文本数据的单一记录结构

REDEFINES 区域内包含非文本数据的单一记录结构是指任何包含单个 01 记录区域且含 REDEFINES 的文件,其中数据区域包含 ZD、COMP 或 COMP-3 数据类型。以下示例显示了两个 REDEFINES,它们定义了包含文本和非文本数据组合的公共 PIC X(80) 区域。

01 PARTS-RECORD. 05 PART-ID PIC 9(9) COMP. 05 PART-TYPE PIC X(2). 05 PART-NAME PIC X(40). 05 PART-DATA PIC X(80). 05 MAIN-PART REDEFINES PART-DATA. 10 MAIN-DESC PIC X(40). 10 MAIN-SUB-COUNT PIC 9(2) COMP. 10 MAIN-ASSEMBLIES OCCURS 10. 15 MAIN-SUB-ID PIC 9(9) COMP. 05 SUB-PART REDEFINES PART-DATA. 10 SUB-DESC PIC X(40). 10 SUB-COST PIC S9(4)V99 COMP. 10 SUB-WEIGHT PIC 9(4)V99 COMP-3. 10 FILLER PIC X(34).

必须先对这种类型的记录结构进行分解,以删除 REDEFINES 语句,这些语句会创建记录结构的多个视图。如果不分解记录结构,则创建的结构文件将忽略 REDEFINES 下的区域,并将整个区域视为文本数据。前面的示例描述了 REDEFINES 子句下的两种不同的非文本结构。创建的结构文件必须将这些区域描述为数据转换器可以针对的唯一结构的一部分。以下示例显示了删除 REDEFINES 后的两个唯一布局。

01 M-PARTS-RECORD. 05 M-PART-ID PIC 9(9) COMP. 05 M-PART-TYPE PIC X(2). 05 M-PART-NAME PIC X(40). 05 M-PART-DATA. 10 M-MAIN-DESC PIC X(40). 10 M-MAIN-SUB-COUNT PIC 9(2) COMP. 10 M-MAIN-ASSEMBLIES OCCURS 10. 15 M-MAIN-SUB-ID PIC 9(9) COMP. 01 S-PARTS-RECORD. 05 S-PART-ID PIC 9(9) COMP. 05 S-PART-TYPE PIC X(2). 05 S-PART-NAME PIC X(40). 05 S-SUB-PART-DATA. 10 S-SUB-DESC PIC X(40). 10 S-SUB-COST PIC S9(4)V99 COMP. 10 S-SUB-WEIGHT PIC 9(4)V99 COMP-3. 10 FILLER PIC X(34).

下一步是确定可用于将一个记录布局与另一个记录布局隔离的条件语句。要确定条件语句,我们建议您咨询主题专家或检查源代码。以下示例显示了源代码。

MOVE "M" TO PART-TYPE MOVE "MAIN ASSEMBLY" TO PART-NAME MOVE "S" TO PART-TYPE MOVE "SUB ASSEMBLY 1" TO PART-NAME

在源代码中,您可以确定 "PART-TYPE" 字段用于确定记录类型。值 "M" 用于 "M-PART-RECORD",值 "S" 用于 "S-PART-RECORD"。现在,您可以创建一个包含两个条件记录的结构文件:分别使用 "M-PART-ID" 和 "S-PART-ID" 字段上标识的条件创建。或者,您可以创建一个默认布局和一个条件布局。

包含非文本数据的多个 01 记录结构

包含非文本数据的多个 01 记录结构是指包含多个 01 记录区域的任何文件,该区域包含 ZD、COMP 或 COMP-3 数据类型,如以下示例所示。

01 M-PARTS-RECORD. 05 M-PART-ID PIC 9(9) COMP. 05 M-PART-TYPE PIC X(2). 05 M-PART-NAME PIC X(40). 05 M-PART-DATA. 10 M-MAIN-DESC PIC X(40). 10 M-MAIN-SUB-COUNT PIC 9(2) COMP. 10 M-MAIN-ASSEMBLIES OCCURS 10. 15 M-MAIN-SUB-ID PIC 9(9) COMP. 01 S-PARTS-RECORD. 05 S-PART-ID PIC 9(9) COMP. 05 S-PART-TYPE PIC X(2). 05 S-PART-NAME PIC X(40). 05 S-SUB-PART-DATA. 10 S-SUB-DESC PIC X(40). 10 S-SUB-COST PIC S9(4)V99 COMP. 10 S-SUB-WEIGHT PIC 9(4)V99 COMP-3. 10 FILLER PIC X(34).

第一步是确定可用于将一个记录布局与另一个记录布局隔离的条件语句。要确定条件语句,我们建议您咨询主题专家或检查源代码。以下示例显示了源代码。

MOVE "M" TO PART-TYPE MOVE "MAIN ASSEMBLY" TO PART-NAME MOVE "S" TO PART-TYPE MOVE "SUB ASSEMBLY 1" TO PART-NAME

在源代码中,您可以确定 "PART-TYPE" 字段用于确定记录类型。值 "M" 用于 "M-PART-RECORD",值 "S" 用于 "S-PART-RECORD"。现在,您可以创建一个包含两个条件记录的结构文件:分别使用 "M-PART-ID" 和 "S-PART-ID" 字段上标识的条件创建。或者,您可以创建一个默认布局和一个条件布局。

使用部分记录描述的程序

虽然使用副本文件来描述文件的整个格式是一种很好的编程风格,但程序员有时在针对特定记录或数据结构时仅手动编写程序所需的结构。这可能包括文件中被大型 FILLER 项目屏蔽的部分,或者涉及多个程序,每个程序都描述了文件的一部分。在这些情况下,必须创建一个包含文件完整描述的程序,如下面的 PROGRAM1 和 PROGRAM2 示例所示。

PROGRAM1 示例:

01 M-PARTS-RECORD. 05 M-PART-ID PIC 9(9) COMP. 05 M-PART-TYPE PIC X(2). 05 M-PART-NAME PIC X(40). 05 M-PART-DATA. 10 M-MAIN-DESC PIC X(40). 10 M-MAIN-SUB-COUNT PIC 9(2) COMP. 10 M-MAIN-ASSEMBLIES OCCURS 10. 15 M-MAIN-SUB-ID PIC 9(9) COMP.

PROGRAM2 示例:

01 S-PARTS-RECORD. 05 S-PART-ID PIC 9(9) COMP. 05 S-PART-TYPE PIC X(2). 05 S-PART-NAME PIC X(40). 05 S-SUB-PART-DATA. 10 S-SUB-DESC PIC X(40). 10 S-SUB-COST PIC S9(4)V99 COMP. 10 S-SUB-WEIGHT PIC 9(4)V99 COMP-3. 10 FILLER PIC X(34).

在前面的示例中,您可以一次加载每个程序的数据字典,然后将不同的结构添加到记录布局中。但是,可能会出现更复杂的情况,如下面的 PROGRAM1 和 PROGRAM2 示例所示。

PROGRAM1 示例:

01 M-PARTS-RECORD. 05 M-PART-ID PIC 9(9) COMP. 05 M-PART-TYPE PIC X(2). 05 M-PART-NAME PIC X(40). 05 FILLER PIC X(82).

PROGRAM2 示例:

01 S-PARTS-RECORD. 05 S-PART-ID PIC 9(9) COMP. 05 S-PART-TYPE PIC X(2). 05 S-PART-NAME PIC X(40). 05 S-SUB-PART-DATA. 10 S-SUB-DESC PIC X(40). 10 S-SUB-COST PIC S9(4)V99 COMP. 10 S-SUB-WEIGHT PIC 9(4)V99 COMP-3. 10 FILLER PIC X(34).

在这种情况下,使用 FILLER 语句屏蔽 PROGRAM1 中的部分记录布局。如果您使用此信息构建记录布局,则 "M-PARTS-RECORD" 的 FILLER 块中的数据将被视为文本且转换不正确。在构建记录布局之前,开发人员需要尽量识别文件的绝对结构。

关系数据库

将大型机关系数据库转换为分布式关系数据库时需要考虑几个因素。例如,改用 ASCII 或 ANSI 字符集可能会导致数据的排序序列问题。有关这些问题的更多信息,请参阅本指南的应用程序迁移挑战部分中的排序序列

例如,键列返回数据的序列可能与大型机上返回数据的序列不同。CURSORS 和 WHERE 子句遵循数据库的排序序列。如果数据依赖于 EBCDIC 排序序列,尽可能让您的数据库使用 EBCDIC 排序序列。或者,在需要时更改应用程序逻辑以使用 EBCDIC 排序序列。请注意,在 SQL 语句中指定备用排序序列会在语句运行时产生额外的延迟。

数据量

与所有迁移一样,您必须将数据从大型机迁移到分布式环境。在考虑使用何种迁移工具之前,首先要考虑需要迁移的数据量。迁移数据可分为四个部分:

  • 集成测试数据

  • 系统测试数据

  • 割接或上线数据

  • 历史和档案数据

集成和系统测试数据的迁移通常不会构成重大挑战,因为在使用这些数据之前,您可以在很长一段时间内迁移这些数据。最好将时间和精力花在割接或上线数据以及历史或档案数据上。

最佳做法是在迁移初期确定上线活动的数据量,包括物理文件和数据库表。通过使用从导出文件中收集的数据,将数据从 EBCDIC 转换为 ASCII,然后将数据导入目标系统,您可以估计从大型机割接数据所需的时间。数据迁移窗口可能不可接受,具体取决于业务可能停机的时间以及上线部署后赶上进度所需的时间。然后,您必须决定是否要继续使用 EBCDIC,这可能会减少高达 50% 的数据割接,或者进行其他调整,比如计划延长业务中断和恢复。

历史数据通常作为并行项目执行,通常不会在上线部署之前完成。转换历史数据可能具有挑战性,尤其是在记录或表布局随着时间的推移而发生变化时。我们建议您制定迁移所需数据的计划,以便您的组织能够满足合规和监管要求。