如何在SQL Server中使用多个表执行数据存档?

时间:2017-10-04 02:05:53

标签: sql sql-server ssms

假设我有一个包含许多表格的数据库。我想在某些表上执行数据存档,即创建一个具有相同结构(相同的约束,索引,列,触发器等)的相同表作为新表,并将特定数据从旧表插入到新表中。

示例,当前表包含2008-2017的数据,我想仅将2010-2017中的数据移动到新表中。然后,我可以删除旧表并使用类似于旧表的命名约定重命名新表。

我该如何处理?

1 个答案:

答案 0 :(得分:1)

对于你所讨论的克隆重命名 - 丢弃逻辑的类型,基础知识非常简单。真的唯一一次这是一个好主意,如果你有一个包含大量数据的表,你无法承受停机时间或阻塞,你只打算这样做。这个过程看起来像这样:

  1. 将原始表中的所有数据插入克隆表
  2. 在单个事务中,sp_rename原始表(例如)myTablemyTable_OLD(只是区别于真实表格的东西)。然后sp_rename克隆表从(例如)myTable_CLONEmyTable
  3. 当你感到高兴时,一切都按照你想要的方式行动myTable_OLD。如果它不能按您的要求工作,只需回复sp_rename个对象。
  4. 如果你走那条路,就要考虑几点考虑因素

    • 标识列:如果您的表格中包含任何标识,则必须使用identity_insert on,然后重新设置标识,以便在旧标识停止的位置进行检索
    • 当你这样做时,你是否有幸阻止桌子?一般来说,如果你需要做这种事情,答案是否定的。我发现效果很好的是使用(nolock)插入我需要的所有行,或者你需要这样做,这样可以减轻原始表中select的影响。然后,在我移动了99%的数据之后,我将打开一个事务,阻止原始表,插入只是自大量数据移动后进入的新数据,然后执行sp_rename的东西
      • 这样您就不会为大部分数据移动锁定任何内容,而只会阻止表格查看原始插入内容与sp_rename <之间原始表格中的最后一位数据/ LI>
      • 如何确定“自开始以来”的内容将取决于您的表格的结构。如果您有标识或日期戳列,则可以选择在移动的最大字段后输入的行。如果你的桌子上没有可以轻松插入的东西,你可能需要发挥创意。

    <强>替代 我想到了其他一些选择:

    表格分区: 这会跨多个分区对单个表进行分片(可以像单个表一样进行管理)。比方说,您可以按年度对数据进行分区,然后当您想要清除数据的结尾年份时,可以将该分区“切换”为特殊的表,然后可以截断该表。所有这些操作都只是元数据,所以它们非常快。这对于大量数据非常有效,其中删除和所有讨厌的事务日志记录都不可行

    表格分区的缺点是设置和管理是一种痛苦。

    批量删除: 如果您的数据不是,那么您可以在数据的尾端进行批量删除。如果你能找到一种方法来获取删除的聚集索引,那么它们应该合理地轻量级。只要你没有比你可以摆脱它更快地积累数据,这种事情的好处是你只是半连续地运行它,它只是蚕食数据的尾端

    快照隔离: 如果删除导致阻塞过多,您还可以设置快照隔离等功能,基本上可以在tempdb中存储行的历史版本。设置isolation level read committed snapshot的任何查询都将读取那些更改前的行,而不是争夺“真实”表上的锁。然后,您可以对您的内容进行批量删除,并且知道任何打到表的查询都不会被删除(或任何其他DML操作)阻止,因为他们要么读取删除前快照,要么他们会读取删除后快照。他们不会等待进程内删除以确定它是否将提交或回滚。不幸的是,这并非没有缺点。对于大型数据集,它可能会给tempdb带来很大的负担,它也可能是一个黑盒子。这也需要你的DBA支持。