简介
这篇文章描述了如何通过使用SQL Server中的本地复制技术来改善SQL Server中的ETL过程。
在一个企业环境中,通常你会有多个数据库,根据操作情况,这些数据库跨越多个服务器。例如,业务可以分为订单、销售和考勤等数据库。由于业务数据分布在这些数据库中,为了报告的目的,我们可能要把这些数据带到一个单一的数据库中,并进行许多转换,如下图所示。

挑战
正如我们所知,报告数据库与操作数据库在结构上有变化。报告数据库可能遵循非正常化的结构,以提高读取性能,因为报告数据库可能没有很多写入。除了非正常化的结构,报告数据库可能有聚集的数据以提高报告数据库的性能。这意味着在报告数据库中不能避免转换。
通常情况下,这种转换是使用Extract-Transform-Load或ETL完成的。然而,如果ETL直接在业务系统上执行,那么在业务数据库上就会出现性能问题。因为ETL是以批处理的方式应用于大量的数据,行和表的锁将被放置,这将给操作数据库带来性能问题。
如果报告数据库直接依赖于操作数据库,如果操作数据库有任何变化,报告数据库也应该被改变。例如,可能会有这样的情况:数据库可能需要转移到新的数据库服务器或现有的数据库服务器。
为了避免这些问题,复制被用来改善SQL Server中的ETL过程,如下图所示。

然而,这种复制必须通过特殊的配置来改善SQL Server中的ETL过程。
复制配置
首先,复制往往会有很大的负载,并且在未来会增加负载。为了方便大规模的复制,我们建议为复制保留独立的分配器。
正如你所知,在SQL Server中有三种复制类型,即快照复制、事务性复制和合并复制。在这些复制配置中,快照复制被淘汰。合并复制会给表添加触发器和GUID列,不会成为改善SQL Server中ETL过程的一个流行选择。然而,事务性复制需要表的主键。如果你有没有主键的表,你将不能使用这些表。需要注意的是,虽然事务性复制使用的是数据库日志,但你不需要将数据库配置为完全恢复模式。然而,如果复制有任何问题,数据库日志将会增长。因此,应该对复制进行特别监控,并且应该修复复制中的任何问题以阻止数据库日志的增长。
配置出版物
如你所知,SQL Server复制遵循发布者-订阅者的方法。你需要从操作数据库中发布文章(表),而在复制数据库中会有一个对所创建出版物的订阅。
让我们从操作数据库中创建出版物。正如我们所知,复制是按数据库来创建的。因此,我们需要每个数据库至少有一个复制。这个出版物很简单,如下图所示。

在这个出版物中,我们将选择需要发布的表,以改善SQL Server中的ETL过程。
在标准出版物创建后,我们需要在选择出版物的属性后,从下面的屏幕中改变所发布文章的一些属性。
重要的两个必须改变的配置在以下屏幕中显示。

我们需要对复制数据库应用相同的索引。如果没有对复制数据库应用相同的索引,在数据复制过程中就会出现性能问题。这个配置不仅与这个案例有关,而且对所有的复制配置都是通用的。
接下来是一个与本配置相关的重要配置。由于我们要将多个数据库中的表复制到一个数据库中,可能会出现同一表名在多个数据库中存在的情况。例如,雇员表可能由考勤、销售和订单这三个数据库组成。由于表名不能重复,我们需要使表名独一无二。 最简单的选择之一是将数据库名称添加到目标表中。例如,订单表中的雇员表可以配置为Orders_Employee,而考勤表中的雇员表可以配置为Attendance_Employee作为目的地。这种配置如下图所示。

这个配置需要对所有出版物中的所有文章单独进行,以改善SQL Server的ETL过程。
在对出版物进行配置后,你会看到出版物如下所示。

如果你有多个数据库服务器中的操作数据库,你将看到相关数据库服务器中的出版物。
订阅
接下来是创建一个订阅,将数据复制到复制数据库,以改善SQL Server中的ETL过程。这是一个标准的订阅创建,你会在典型的复制设置中看到。
订阅创建后,你会看到你的配置如下。请注意,出于安全原因,SQL Server的名称是隐藏的。

此外,由于你是将这个配置用于ETL,所以可以为不同的时间安排定义订阅计划。在一个典型的订阅的情况下,我们希望有连续的复制,在这种情况下可以修改。
一旦复制到位,你会看到在出版数据库中创建了以下表。

你可以看到,这些表是以数据库名称的前缀创建的,这样就可以保持表名的唯一性。
让我们看看如何为雇员表创建索引。在每个数据库中,都有一个Employee表,每个表的EmployeeID列都有名为PK_Employee的主键,有两个数据库的NIC号码有一个唯一索引。
让我们看看它们是如何在复制的表中创建的。

你可以看到,在复制的数据库中只创建了一个主键和唯一索引的实例。正如你所知,主键和唯一键是约束条件,它们应该有一个唯一的名字。这意味着PK_Employee可以有唯一的实例,这对Unique约束来说也是如此。
你有两个选择。第一个选项是让操作数据库维护唯一约束。然而,这并不实际,因为操作数据库是孤立开发的,它们可能缺乏团队间的沟通。因此,大多数情况下,这必须由复制方来承担,这将是我们的第二个选择。在创建复制后,我们需要验证是否应用了所有的约束条件,如果没有,我们需要每年应用这些约束条件来改善SQL Server的ETL过程。
由于所有的表现在都在一个数据库中,所以从复制的数据库中编写ETL要容易得多,不会影响到操作数据库的任何操作。
这些问题是如何解决的
现在让我们回顾一下,看看这对改善SQL Server的ETL过程有什么作用。
- 由于复制是一个异步过程,它不会影响操作数据库。由于SQL Server中的ETL过程不需要持续的复制,你可以在高峰期安排对系统的影响最小的时间。
- 当数据库需要从一个实例转移到另一个实例或一个新的数据库服务器时,这只是一个由DBA团队改变发布的问题。不需要对ETL做任何改变
由于这两个原因,你可以看到Replication可以用来改善SQL Server中的ETL过程。
总结
我们研究了利用复制来改善SQL Server中的ETL过程。由于复制方法的异步性,这种方法减轻了操作系统的负荷。在这种方法中,我们使复制的表是唯一的,我们需要确保目标表中的约束也是唯一的。
