sql-server - 删除 vs 回滚策略 - ETL 负载

标签 sql-server etl sql-server-2016

我正在以下列方式将数据加载到表中:

DECLARE @srcRc INT;
DECLARE @dstRc INT;

SET @srcRc = ( SELECT COUNT(*) FROM A )

INSERT  INTO t
        (Col1
        ,Col2
        ,Col3
        )
        SELECT  A.Col1
               ,A.Col2
               ,B.Col3
        FROM    A
                JOIN B
                    ON A.Id = B.Id;

SET @dstRc = @@ROWCOUNT

现在我正在比较变量 @srcRc@dstRc . ROWCOUNT必须相同。如果不是,则需要删除插入的行。

Q1:回滚插入的行的最佳策略是什么?

我有几个想法:

1) 如果行数不匹配,则在事务中运行负载并回滚。
2)将标志列(位)添加到名为toBeDeleted的目标表中,运行加载,如果行数不匹配,更新 toBeDeleted列与 1值以将其标记为删除的候选对象。然后以批处理模式(while 循环)删除。或者不要删除它们,但在使用 t 时总是从查询中排除删除候选者 table 。
3) 在插入行之前,先比较行数。如果不匹配,则不要启动负载。
DECLARE @srcRc INT;
DECLARE @dstRc INT;
SET @srcRc = ( SELECT   COUNT(1) FROM A );
SET @dstRc = ( SELECT   COUNT(1) FROM A JOIN B ON A.Id = B.Id );

Q2:对于更多的行,比如 10-100 百万,什么是更好的解决方案?
Q3:或者对于类似的情况有没有更好的策略?

最佳答案

好的,假设:

当表 A 和 B 的内容可能已更改时,您需要在稍后的某个日期回滚

T 中可能还有其他行您不想作为回滚的一部分删除。

然后您必须保留您插入的行的列表,因为您无法从 A 和 B 可靠地重新生成该列表,并且您不能从 T 中删除所有内容

你可以通过两种方式做到这一点

  • 更改您的导入,以便它首先将行插入到导入表中,保持导入表卡在附近,直到您确定不再需要它为止。
  • 向 T [importId] 添加一个额外的列,在其中放入唯一标识值

  • 显然,第一种策略使用了更多的磁盘空间。因此,您保留数据的时间越长,数据越多,额外的列看起来就越好。

    另一种选择是分别生成导入数据的列表,并使您的事务 sql 成为批量插入,并将所有数据硬编码到 sql 中。

    这适用于小列表、初始设置数据等。

    编辑:

    从您的评论看来,您本身并不希望回滚。但最好的方法是在导入过程中应用业务逻辑。

    在这种情况下,您的第三个答案是最好的。当您知道源数据不正确时,不要进行导入。

    关于sql-server - 删除 vs 回滚策略 - ETL 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41016610/

    相关文章:

    python - 使用 sqlalchemy 连接两个不同的数据库

    javascript - 下拉选择不自动填充文本框

    sql-server - 更改 SQL Server 2008 中现有表的列顺序/添加新列

    c# - 即使在释放资源后也无法关闭 excel

    sql-server - 从高级编辑器更改数据类型与数据转换

    sql - 对 ETL 的良好 SQL Server Integration Services (SSIS) 示例/样本的建议?

    sql - 允许登录运行存储过程而无法从表中选择

    sql-server - 从 Azure Databricks 连接到 SQL Server

    python - SQL Server 2016 会通过外部脚本支持 Python 吗?

    sql-server - SQL Server 2016 全文索引突然停止工作