跨多个相关表批量插入?

BULK INSERT across multiple related tables?

我需要在 3 table 秒内批量插入数十万条记录。 table 的简单细分为:

TableA
--------
TableAID (PK)
TableBID (FK)
TableCID (FK)
Other Columns

TableB
--------
TableBID (PK)
Other Columns

TableC
--------
TableCID (PK)
Other Columns

当然,批量插入的问题在于它只能与一个 table 一起使用,因此 FK 成为一个问题。

我一直在寻找解决这个问题的方法,根据我从各种来源收集到的信息,使用 SEQUENCE column 可能是最好的选择。我只是想确保我已经正确地将我读过的各种线程和帖子中的逻辑拼凑在一起。如果我有正确的想法,请告诉我。

首先,将 table 修改为如下所示:

TableA
--------
TableAID (PK)
TableBSequence
TableCSequence
Other Columns

TableB
--------
TableBID (PK)
TableBSequence
Other Columns

TableC
--------
TableCID (PK)
TableCSequence
Other Columns

然后,在应用程序代码中,我将使用以下逻辑对数据库进行五次调用:

然后,当然,我们总是会加入序列。

我有三个问题:

  1. 我的基本逻辑正确吗?

  2. 在 Tables B 和 C 中,我会从 PK 中删除聚簇索引并改为放入序列吗?

  3. 一旦从 Tables B 和 C 请求序列号,它们是否会以某种方式锁定在请求和批量插入之间?我只需要确保在请求和插入之间,其他进程不会请求和使用相同的数字。

谢谢!

编辑:

输入并发布后,我一直在深入阅读 SEQUENCE 文档。我想我一开始误解了它。 SEQUENCE 不是列类型。对于 table 中的实际列,我将只使用 INT(或可能是 BIGINT),具体取决于我希望拥有的记录数)。实际的 SEQUENCE 对象是一个完全独立的实体,其工作是根据请求生成数值并跟踪已经生成的数值。因此,如果我理解正确的话,我会生成两个 SEQUENCE 对象,一个与 Table B 结合使用,另一个与 Table C.

结合使用

这就回答了我的第三个问题。

Do I have the basic logic correct?

是的。这里的另一种常见方法是将数据批量加载到暂存区 table,并在服务器端执行类似的操作。

您可以使用 sp_sequence_get_range 存储过程从客户端请求序列值范围。

In Tables B and C, would I remove the clustered index from the PK

不,正如您后来提到的,该序列只是为您提供 PK 值。

抱歉,一开始看错了你的问题。我现在看到您正在尝试生成自己的 PK 而不是让 MS SQL 为您生成它们。划掉我上面的评论。

正如 David Browne 所提到的,您可能希望使用暂存 table 来避免对应用程序堆造成压力。使用 tempdb 并直接在 table 上对每个 table 使用单个事务进行修改。然后,将暂存 table 复制到它们的目标,或者如果附加则使用 MERGE。如果您正在执行 FK,如果您选择以相反的顺序插入 (C=>B=>A),则可以暂时删除这些约束。如果在插入期间遇到性能问题,您可能还需要考虑临时删除索引。最后,考虑使用 SSIS 而不是自定义应用程序。