sql-server - 仅限订阅者触发器

标签 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,几乎没有延迟。是的,我预计高负载数据库的性能会滞后。理论上,在相同配置的服务器上应该可以流畅运行。

但是,同样,订阅者端没有触发器。有什么想法、替代方案吗?

最佳答案

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 在幕后为您完成存储更改和版本控制的所有魔力。您可能还想研究一下快照隔离……它配合得很好。链接的文章有更多相关信息。

关于sql-server - 仅限订阅者触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46660488/

相关文章:

sql - 1950 年之前的日期等同于 future 日期

java - 使用 PreparedStatement 和 executeBatch 在 jdbc 上最快 'update'

sql-server - 为范围内的每个月选择前 5 个 SUM(每个客户一个)

sql - T-SQL通过RelevanceDate从表/log_table中检索历史数据

database - Oracle 数据库中表触发器的多模式权限

sql - 挑出 EVENTDATA 的特定部分用于 DDL 触发器?

sql-server - 在 SQL Server 中为 Webhook 添加表触发器

sql - 如何在 SQL Server 中对字段值中的撇号进行转义?

sql-server - 在运行优化顾问之前,是否可以从 SQL Server Profiler 跟踪数据中删除 "exec sp_reset_connection"?

sql - TSQL Pivot 4 值列