仅订阅者触发器

时间:2017-10-10 07:04:24

标签: sql-server tsql triggers replication database-trigger

有两台服务器。首先是生产中的ERP系统。第二个是用于重度分析查询的BI服务器。我们每天通过备份更新BI服务器。但是,这还不够,有些用户希望比第二天更频繁地看到他们的数据更改。除了要求备份或复制之外,我无法访问ERP服务器并且无法执行任何操作。

在开始要求复制之前。我想了解是否可以使用订阅者触发器来处理并非所有数据,而是更改。有一个ETL过程可以更快地进行一些查询(索引,转换等)。触发器应该可以解决问题,但我找不到在订户端使用它们的方法。 ERP系统不允许在数据库级别进行任何更改。因此,订阅者数据库似乎适用于触发器(它们不会影响ERP服务器性能)。尽管如此,我找不到一种方法来设置它们。处理所有数据是一个疯狂的开销。

用例:简化示例,比方说,我们有两个复制表:

+------------+-------------+--------+
|     dt     | customer_id | amount |
+------------+-------------+--------+
| 2017-01-01 |           1 |    234 |
| 2017-01-02 |           1 |    123 |
+------------+-------------+--------+

+------------+-------------+------------+------------+
| manager_id | customer_id | date_from  |  date_to   |
+------------+-------------+------------+------------+
|          1 |           1 | 2017-01-01 | 2017-01-02 |
|          2 |           1 | 2017-01-02 |       null |
+------------+-------------+------------+------------+

我需要将它们转换为以下索引表:

+----------+-------------+------------+--------+
|  dt_id   | customer_id | manager_id | amount |
+----------+-------------+------------+--------+
| 20170101 |           1 |          1 |    234 |
| 20170102 |           1 |          2 |    123 |
+----------+-------------+------------+--------+

所以,我创建了另一个数据库,我存储了上面的表。现在,为了更新表,我必须截断它并再次重新插入所有数据。我可以加入它们以检查差异,但对于大桌子它也太重了。触发器有助于仅跟踪更改的记录。第一个输入表可以使用触发器:

create trigger SaleInsert
on Table1
after insert 
begin 
    insert into NewDB..IndexedTable
    select 
    //some transformation
    from inserted
    left join Table2
    on Table1.customer_id = Table2.customer_id
    and Table1.dt >= Table2.date_from
    and Table1.dt < Table2.date_to
end

同样的想法更新,删除,第二个表的类似方法。我可以用很少的滞后自动更新DWH。是的,我预计高负载数据库的性能会滞后。从理论上讲,它应该在具有相同配置的服务器上顺利运行。

但是,同样,订户方没有触发器。任何想法,替代品?

4 个答案:

答案 0 :(得分:5)

MS SQL Server具有“更改跟踪”功能,可能对您有用。您启用数据库以进行更改跟踪并配置要跟踪的表。然后,SQL Server会在每次更新时创建更改记录,在表上插入,删除,然后让您查询自上次检查以来所做记录的更改。这对于同步更改非常有用,并且比使用触发器更有效。它比管理自己的跟踪表更容易管理。这是自SQL Server 2005以来的一项功能。

How to: Use SQL Server Change Tracking

更改跟踪仅捕获表的主键,让您查询哪些字段可能已被修改。然后,您可以查询这些表上的表连接以获取当前数据。如果您希望它捕获数据,您也可以使用Change Capture,但它需要更多的开销,至少需要SQL Server 2008企业版。

Change Data Capture

一般过程是:

  • 获取当前的同步版本
  • 获取用于获取更改的上一个同步版本
  • 获取自上一版本(插入,更新和删除)以来已更改的表的所有主键。
  • 使用数据加入密钥并下拉数据(如果不使用更改捕获)。
  • 保存数据和当前同步版本(从第一步开始)。

然后,只要您想订阅下一组更改,就会重复此过程。 SQL Server为您提供了存储更改和版本控制的幕后策略。您还可能需要查看快照隔离...它可以很好地使用它。链接的文章提供了更多相关信息。

答案 1 :(得分:3)

这个答案有些迂回,但考虑到你的严格限制,或许你会考虑它。

首先,按照您的决定进行复制。您提到创建另一个数据库,但是因为如何创建触发器来填充它而陷入困境。答案在于能够运行快照后脚本。创建复制发布时,DBA可以指定在快照之后在订阅服务器上运行的脚本。

Post-snapshot script

您可以让脚本创建您需要的所有触发器。

另外,为了防止复制用'#34;无触发器&#34;覆盖你的触发器。 (如ERP数据库中所定义)DBA需要验证对于您触发的每个表,复制用户触发器设置为 False

Copy user triggers

答案 2 :(得分:0)

在实施触发器或更改ERP数据库跟踪之前,您无法获得ERP数据库的更新。最好的方法是进行复制,如果您无法访问ERP服务器并且无法执行任何操作,除了要求备份或复制。

答案 3 :(得分:0)

如果您在ERP系统数据库上使用完全恢复模型,则可以使用日志文件传送来完成此操作。这在生产系统和报告系统之间仍会有一定程度的延迟。如果在ERP系统和报告系统上发布DML语句之间存在一些延迟,则此解决方案将起作用。如果您需要几乎即时访问报告系统中的数据,复制和相关的开销是您唯一的好选择。有关配置日志文件传送的详细信息: https://docs.microsoft.com/en-us/sql/database-engine/log-shipping/about-log-shipping-sql-server