我需要在3个表中进行数十万条记录的批量插入。这些表的简单分类如下:
TableA
--------
TableAID (PK)
TableBID (FK)
TableCID (FK)
Other Columns
TableB
--------
TableBID (PK)
Other Columns
TableC
--------
TableCID (PK)
Other Columns
当然,批量插入的问题在于它只能用于一个表,因此FK成为问题。
我一直在寻找解决此问题的方法,从我从各种来源收集到的信息来看,使用SEQUENCE column可能是最好的选择。我只想确保我已将我阅读过的各种线程和帖子中的逻辑正确地拼凑在一起。让我知道我是否有正确的主意。
首先,将表修改如下:
TableA
--------
TableAID (PK)
TableBSequence
TableCSequence
Other Columns
TableB
--------
TableBID (PK)
TableBSequence
Other Columns
TableC
--------
TableCID (PK)
TableCSequence
Other Columns
然后,从应用程序代码中,我将使用以下逻辑对数据库进行五个调用:
从TableC请求X序列号,其中X是要插入到TableC中的已知记录数。 (第一个数据库调用。)
从TableB请求Y序列号,其中Y是要插入到TableB(第二个DB调用)的已知记录数。
用现在已知的序列号修改A,B和C的现有对象(它们是生成的用于镜像表的模型)。
批量插入到TableA中。 (第3次数据库调用)
然后,当然,我们总是会加入序列。
我有三个问题:
我的基本逻辑正确吗?
在表B和C中,我是否可以从PK中删除聚簇索引,然后放入序列中?
一旦从表B和C请求了序列号,它们是否会以某种方式锁定在请求和批量插入之间?我只需要确保在请求和插入之间,其他进程不会请求并使用相同的数字。
谢谢!
编辑:
键入并发布后,我一直在更深入地阅读SEQUENCE文档。我想我一开始误解了。 SEQUENCE不是列类型。对于表中的实际列,我只需要使用INT(或者可能是BIGINT),具体取决于我希望拥有的记录数。实际的SEQUENCE对象是一个完全独立的实体,其任务是根据请求生成数值并跟踪已经生成的数值。因此,如果我理解正确,我将生成两个SEQUENCE对象,一个与表B结合使用,另一个与表C结合使用。
这回答了我的第三个问题。
答案 0 :(得分:1)
我的基本逻辑正确吗?
是的。这里的另一种常见方法是将数据批量加载到临时表中,并在服务器端执行类似的操作。
您可以使用sp_sequence_get_range存储过程从客户端请求序列值的范围。
在表B和C中,我是否要从PK中删除聚簇索引
不,正如您稍后提到的,该序列只是为您提供PK值。
答案 1 :(得分:1)
对不起,刚读错您的问题。我现在看到您正在尝试生成自己的PK,而不是允许MS SQL为您生成它们。刮擦我的上述评论。
正如David Browne提到的那样,您可能希望使用登台表来避免施加在应用程序堆上的负担。使用tempdb并使用每个表的单个事务直接在表上进行修改。然后,将登台表复制到其目标,或者在追加时使用MERGE。如果要强制执行FK,如果选择以相反的顺序插入(C => B => A),则可以暂时删除这些约束。如果在插入过程中遇到性能问题,您可能还需要考虑临时删除索引。最后,考虑使用SSIS代替自定义应用。