数据迁移测试中的挑战






4.67/5 (2投票s)
数据迁移测试中面临的挑战
引言
几个月前,我们有机会参与了我们的第一个数据库迁移测试项目。项目目标是确保从使用 MS SQL 作为数据库的源系统迁移到使用相同数据库的目标系统的数据的正确性。在测试期间,我们有机会发挥了我们的 SQL 查询编写技能。我们希望在本文中分享我们的学习和经验。
背景
什么是数据迁移?
数据迁移是从源系统和目标系统之间传输数据的过程。它包括数据清洗、验证和数据质量。人们经常将“数据转换”一词与“数据迁移”互换使用,但我们应该知道,转换是迁移的一个组成部分。
测试周期中遇到的挑战
- 第一个也是最大的挑战是数据映射。源数据库表到目标数据库表之间没有一对一的映射文档。我们通过研究源和目标数据库表结构创建了一个初始映射文档,并获得了相关团队的批准。这对后续的测试阶段很有帮助。
- 源和目标数据库表之间存在一些结构更改,这增加了测试的挑战。例如,源表列直接映射到主表中的主键,数据类型如
varchar
或int
,而在目标数据库中,除了常见的数据类型,它们还为表的每一行生成了自动 GUID。 - 下一个挑战是将源数据库的原始数据与目标数据库中的视图进行比较。在源数据库中,可以通过连接 2 到 3 个表来获取大部分信息,但在目标数据库中并非如此。因此,测试人员需要从视图而不是原始数据中获取所需数据。
迁移测试中的常见问题
数据类型
更改。- 迁移的值取决于源数据库中存在的其他字段/表。
- 源表中的数据可能是字符类型,但在目标表中,映射的列是整数。
- 两个或多个列的连接。
Using the Code
测试数据完整性的方法
为了检查源和目标之间的数据完整性,创建了不同集的 SQL 脚本。
例如,需要验证源数据库和目标数据库中的两个 SQL 表之间的数据完整性。这是通过使用临时表和完全外部联接来实现的。
-用于从目标数据库获取数据的临时表-
drop table #mosoblink
select convert(varchar, CheckinDateTime,101) as dt, PartyID, RoleId, count(*) as Ct
into #mosoblink
from dbo.Checkin
where convert(varchar, CheckinDateTime,101) = '10/19/2015'
group by convert(varchar, CheckinDateTime,101), PartyID, RoleID
order by 1
-用于从源数据库获取数据的临时表-
drop table #eClubblink
select convert(varchar(10), sdtTime,101) as dt, a.vcMemberID, _
replace(vcVisibleMemberID,'P','') as MemberID, count(*) as ct
into #eClubblink
from tblCheckins a
inner join tblMembers b on a.vcMemberID = b.vcMemberID
where convert(varchar, sdttime,101) = '10/19/2015'
group by convert(varchar(10), sdtTime,101), a.vcMemberID, replace(vcVisibleMemberID,'P','')
-用于逐行比较数据的完全外部联接-
select a.*, b.*
from #mosoblink a full outer join #eClubblink b on a.RoleID = b.MemberID
where coalesce(a.ct,0) <> coalesce(b.ct,0)
上述脚本的示例结果集
dt | PartyID | RoleId | Ct | dt | vcMemberID | MemberID | ct |
NULL |
NULL |
NULL |
NULL |
11/7/2015 |
1030025722 |
1030025722 |
1 |
源数据库和目标数据库中行数差异是上述脚本的结果集。测试人员可以轻松识别不匹配项,并能够缩短测试时间。
遵循上述方法时遇到的挑战
上述方法在只有单个源系统的情况下是有效的。上述查询从源和目标表中提取数据,将其放入临时表中,并基于 Member ID(在每种情况下都是唯一的)使用完全外部联接进行比较,该 Member ID 被迁移到目标表中的 Role ID。当我们需要将多个源系统的数据迁移到一个通用系统时,这种方法的真正好处才显现出来。
由于最初我们是从单个源迁移数据的,现在随着推广过程的推进,我们发现这种方法存在一个问题。我们有两个位于不同地点(例如英国和美国)的源系统,每个系统都有自己的服务器。每个源系统中生成的 Member ID 在其自身范围内都是唯一的,但仅限于源系统内部,并且我们的应用程序是为每个服务器单独配置的,并且没有任何同步作业在这些服务器之间同步数据。但是我们的目标系统是一个通用系统,拥有一个处理每个源系统数据的单一服务器。
当我们继续将数据迁移到目标表并开始测试时,我们发现大约 20-25% 的记录的签入计数存在差异。一些记录的签入计数比预期的要多,而有些记录甚至没有一个签入记录。这都是因为在系统中是唯一的 Member ID 与另一个源系统的 Member ID 重叠了。
例如:来自美国源系统的记录的 Member ID 1020000909
(在美国源系统内是唯一的)与来自英国源系统的具有相同 Member ID 的记录重叠了。由于这些 Member ID 是在运行时自动生成的,并且由于不同地点的服务器差异以及它们之间没有同步活动,因此产生了这类记录。
关注点
为遇到的问题提供的解决方案
在多次会议讨论上述问题的解决方案后,团队决定修改目标表和源表中的 Role ID 和 Member ID,方法是在其中一个源系统的记录的 Member ID 中附加源系统 ID。我们找出 ID 重叠的记录,并在其中附加了源系统 ID。我们对英国源系统采用了这种方法。
例如:英国记录的 Member ID 1020000909
被修改为 1020000909-4
,其中 4
是英国的源系统 ID,在两个地方都进行了修改,使其不会与美国源系统中的具有相同 Member ID 的记录(即在源表以及目标表(在 Role ID 内部)中)发生冲突。该解决方案消除了重叠记录的差异,现在每条记录的签入计数都匹配,因为每条记录都有其唯一的 Role ID。
历史
- 2016年1月12日:初始版本