

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

# 第 3 阶段：迁移
<a name="phase-3-migrate"></a>

数据库迁移的主要任务是在最短的停机时间内完成迁移。由于两个数据库都应使用相同的编程语言和通信协议，因此您可能需要将代码和架构转换为相似的查询语法、过程和函数。转换架构时，请考虑以下方面：
+ 根据新引擎的需要修改数据库连接。
+ 修复代码转换过程中出现的任何警告和错误。
+ 根据转换后的架构修改相应的表映射和代码。
+ 识别并重构您的应用程序使用的任何供应商特定功能。

您可以使用任何第三方迁移工具进行架构代码转换，例如 SAP ASE 数据库和适用于 Amazon RDS for SQL Server 的 Amazon RDS。你可能需要手动转换一些代码，因为 SQL Server 不支持非 ANSI SQL。

转换代码后，转换应用程序代码或动态 SQL 应用程序，然后执行单元和功能测试。有关更多信息，请参阅[测试迁移的数据库对象 (SybaseToSQL)](https://learn.microsoft.com/en-us/sql/ssma/sybase/testing-migrated-database-objects-sybasetosql?view=sql-server-ver15)。

## 转换数据
<a name="converting-the-data.08113c62-7c5a-5df1-abcf-462e3e9209f4"></a>

通过清理、标准化、验证和排序对原始数据进行转换，使其更有用。在数据库迁移中，以下列方式使用提取、转换和加载 (ETL) 进程：
+ 在数据库内部
+ 使用外部脚本
+ 使用第三方工具

ETL 工具的示例包括 AWS Glue Informatica 和 Talend。对于从 SAP ASE 到 SQL Server 的迁移，一些免费工具可以自动转换存储的过程和函数。

## 校验数据库对象
<a name="validating-database-objects"></a>

验证数据库有助于防止后续迁移阶段出现问题。代码转换后，通过比较 SAP ASE 和 RDS SQL Server 之间的以下元素来验证您的数据库架构：
+ 架构
+ 表
+ 观看次数
+ 函数
+ 存储过程索引
+ 触发器
+ 约束（例如，主键、外键、检查和默认值）

检查每个对象是否正确迁移。如果您发现差异，请找出失败的原因。您可能需要在目标数据库中手动创建缺失的对象或转换 Transact-SQL 代码。有关更多信息，请参阅[从 SAP ASE 迁移到 Amazon RDS for SQL Server 或微软 SQL Server 后验证数据库对象](https://aws.amazon.com/blogs/database/validate-database-objects-after-migrating-from-sap-ase-to-amazon-rds-for-sql-server-or-microsoft-sql-server/)。

## 使用迁移数据 AWS DMS
<a name="migrating-data-using-dms"></a>

如果您有多个数据库用户，则可能需要按计划迁移应用程序。根据数据库大小和迁移窗口，此类数据迁移需要了解满负荷和增量负载。因此， AWS DMS 可以根据以下过程连接源数据库和目标数据库以复制数据库内容：
+ 创建复制服务器。
+ 创建描述数据存储连接的源端点和目标端点。
+ 创建一个或多个迁移任务，以便在源数据存储和目标数据存储之间迁移数据。
+ 正在从 SAP ASE 复制到 SQL Server
+ （可选）通过更改数据捕获完成从 SAP ASE 到 SQL Server 的数据迁移

您可能需要进行优化 AWS DMS 以处理某些数据类型。有关更多信息，请参阅[使用 SAP ASE 数据库作为源 AWS DMS](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.SAP.html)。

## 迁移离线数据
<a name="migrating-offline-data"></a>

您可以使用 AWS Storage Gateway 将 SAP ASE 数据库与亚马逊简单存储服务 (Amazon S3) Service 集成，后者为本地 SAP ASE 数据库备份提供经济实惠、可扩展且安全的存储。有关更多信息，请参阅[使用将 SAP ASE 数据库集成到 Amazon S3 AWS Storage Gateway](https://aws.amazon.com/blogs/storage/integrate-an-sap-ase-database-to-amazon-s3-using-aws-storage-gateway/)。

## 使用第三方工具
<a name="using-third-party-tools"></a>

有些应用程序充当与其他应用程序接口的单一接触点 (SPOC)。迁移到 SQL Server 数据库平台时，这些互连可能会受到影响，并且数据库监控可能需要使用服务器特定的通信协议的本机或第三方工具。重要的是要评估这些依赖的应用程序和工具是否已经支持 SQL Server，或者它们是否需要修改才能正常运行。

对于打包的应用程序，请咨询供应商以确定他们是否支持 Amazon RDS for SQL Server。对于自定义应用程序，您可能需要修改代码以确保与迁移的数据库兼容。

## 监控数据库
<a name="monitoring-the-database"></a>

无论您选择哪种迁移路径，Amazon CloudWatch 都会在收集指标（例如 CPU 类型、内存和 I/O 函数）方面发挥作用。它还能够设置指标阈值，并在触发阈值时启动操作。

例如，您可以为 Amazon RDS 集群指标、通知和操作创建警报，以检测和关闭未使用或未充分利用的读取器实例。对指标和事件设置警报有助于最大限度地减少停机时间和业务影响。 AWS 服务 像 Amazon S3、[Amazon RDS Performance Insigh](https://aws.amazon.com/rds/performance-insights/) ts CloudWatch、Amazon 一样，已经与 RDS 数据库平台集成，我们建议他们监控性能。 AWS CloudTrail 

## 验证数据
<a name="validating-the-data"></a>

从 SAP ASE 到 Amazon RDS for SQL Server 的数据迁移完成后，请验证数据以确保准确性和一致性。使用以下 SQL 查询为数据库中的每个表生成元数据语句。

### 步骤 1：生成元数据语句和列列表
<a name="step-1-generate-metadata-statements-and-column-lists"></a>

```
SELECT dt.schema_name, dt.table_name,
    STRING_AGG(dt.column_name, ',') AS column_name,
    STRING_AGG(dt.cname, ',') AS column_order
FROM (
    SELECT 
        object_name(a.id) AS table_name,
        a.name colname,
        c.name col_type,
        a.isnullable,
        a.name AS cname,
        schema_name(b.uid) AS schema_name,
        CASE 
            WHEN a.isnullable = 1 THEN
                CASE 
                    WHEN c.name LIKE '%char%' 
                        THEN 'coalesce(ltrim(rtrim('+a.name+')),''X'') as '+a.name
                    WHEN (c.name LIKE '%int%' OR c.name = 'numeric') 
                        THEN 'coalesce('+a.name+',0) as '+a.name
                    WHEN c.name IN ('decimal','float','money') 
                        THEN 'coalesce('+a.name+',0.0) as '+a.name
                    WHEN c.name LIKE 'datetime%' 
                        THEN 'coalesce(convert(nvarchar(30),'+a.name+',112),''99991231'') as '+a.name
                    ELSE a.name 
                END
            WHEN c.name LIKE 'datetime%' 
                THEN 'coalesce(convert(nvarchar(30),'+a.name+',112),''99991231'') as '+a.name
            WHEN c.name LIKE '%char%' 
                THEN 'coalesce(ltrim(rtrim('+a.name+')),''X'') as '+a.name
            ELSE a.name
        END AS column_name
    FROM syscolumns a
    INNER JOIN sysobjects b
        ON a.id = b.id 
        AND b.type = 'U'
    INNER JOIN systypes c
        ON a.usertype = c.usertype
        AND a.xusertype = c.xusertype
        AND c.name != 'varbinary'
    INNER JOIN (
        SELECT 
            OBJECT_NAME(ic.OBJECT_ID) AS table_name,
            COL_NAME(ic.OBJECT_ID, ic.column_id) AS column_name
        FROM sys.indexes AS i
        INNER JOIN sys.index_columns AS ic
            ON i.OBJECT_ID = ic.OBJECT_ID
            AND i.index_id = ic.index_id
            AND i.is_primary_key = 1
    ) pk
        ON pk.table_name = object_name(a.id)
        AND pk.column_name = a.name
) dt 
GROUP BY dt.schema_name, dt.table_name;
```

下表列出了输出示例：


| 
| 
| **架构名称** | **表名** | **列名称** | **列顺序** | 
| --- |--- |--- |--- |
| 人员 | 地址 | 地址标识 | 地址标识 | 
| 人员 | AddressType | AddressType身份证 | AddressType身份证 | 
| 人员 | BusinessEntity | BusinessEntity身份证 | BusinessEntity身份证 | 
| 人员 | BusinessEntityAddress | BusinessEntityID、地址 ID、 AddressType ID | BusinessEntityID、地址 ID、 AddressType ID | 

### 步骤 2：使用元数据结果生成比较查询并创建 SELECT 语句
<a name="step-2-generate-comparison-queries"></a>

```
SELECT <column_name>
FROM [schema_name].[table_name]
ORDER BY <column_order>;
```

以下是生成的查询的示例：

```
SELECT BusinessEntityID, AddressID, AddressTypeID
FROM [Person].[BusinessEntityAddress]
ORDER BY BusinessEntityID, AddressID, AddressTypeID;
```

### 第 3 步：验证
<a name="step-3-validation"></a>

1. 在两个数据库中运行元数据查询。

1. 为每个表生成和运行`SELECT`语句。

1. 比较源数据库和目标数据库之间的结果：
   + 行数应匹配。
   + 数据值应相同。
   + 检查是否存在数据类型转换问题。

### 步骤 4：验证行数
<a name="step-4-validate-row-count"></a>

```
SELECT COUNT(1) AS total_rows
FROM [schema_name].[table_name];
```

### 步骤 5：更新应用程序的配置以指向新数据库
<a name="step-5-update-your-application-configuration"></a>

1. 更新安全组。

1. 根据需要修改 DNS 连接字符串以连接到目标数据库。

## 测试迁移
<a name="testing-the-migration"></a>

测试过程可以帮助您识别开发过程中被忽视的问题，例如查询转换不正确或索引缺失。它可能表明需要根据工作负载性能对数据库引擎进行调整或查询修改。

功能测试（包括应用程序工作流程的单元测试）有助于确保与新数据库的无缝集成。性能测试通过验证可接受的响应时间和识别瓶颈来帮助优化数据库。

虽然存在手动和自动测试方法，但我们建议使用自动化方法，因为它效率更高，特别是对于额外的测试周期。