繁体   English   中英

如何在具有多个表的SQL Server中执行数据归档?

[英]How to perform data archive in SQL Server with many tables?

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

例如,当前表具有2008-2017年的数据,我只想将2010-2017年的数据移动到新表中。 然后,在此之后,我可以删除旧表,并使用类似于旧表的命名约定重命名新表。

我应该如何处理?

对于您正在谈论的克隆-重命名-删除逻辑,其基础非常简单。 确实,这是一个唯一的好主意,如果您有一个包含大量数据的表,而您又无法承受停机或阻塞的负担,而您只打算这样做。 该过程如下所示:

  1. 将原始表中的所有数据插入克隆表中
  2. 在一个单一的交易, sp_rename从(例如)原始表myTablemyTable_OLD (只是要真实表区别)。 然后sp_rename将克隆表从(例如) myTable_CLONEmyTable
  3. 当您感到满意时,请放下myTable_OLD ,一切都会按照您的要求进行。 如果您想要的方法不起作用,只需sp_rename对象即可。

如果您走那条路线,需要考虑几个因素

  • 标识列:如果表上有任何标识,则必须使用identity_insert on然后重新设置标识以在旧标识不再保留的位置进行提取
  • 执行此操作时,您是否能挡台? 通常,如果您需要做这种事情,答案是否定的。 我发现不错的方法是使用(nolock)插入我需要的所有行,或者您需要这样做,以便减轻从原始表中进行选择的影响。 然后,在我移动了99%的数据之后,我将打开一个事务,阻塞原始表, 插入由于大量数据移动而产生的新数据,然后执行sp_rename
    • 这样一来,您就不会在大部分数据移动中锁定任何内容,而只阻塞表中原始插入和sp_rename之间进入原始表的最后一部分数据
    • 您如何确定“自开始以来”的内容将取决于表的结构。 如果您有标识或日期戳列,则可以只选择移至这些字段的最大值之后的行。 如果您的桌子没有可以轻松连接的东西,则可能需要发挥创意。

替代方案我想到了其他两种替代方案:

表分区:这可以将单个表划分为多个分区(可以像管理单个表一样对其进行管理)。 可以说,按年份对数据进行分区,然后,当要清除尾随的数据时,可以将该分区“切换”到一个特殊的表中,然后可以对其进行截断。 所有这些操作仅是元数据,因此它们非常快。 对于删除和所有麻烦的事务记录都不可行的大量数据,这也非常有效

表分区的缺点是设置和管理很麻烦。

批量删除:如果您的数据不太大,则可以在数据的尾端进行批量删除。 如果你能找到一个办法让聚集索引旨在为您删除,他们应该是合理的轻量化。 只要累积数据的速度不超过消除数据的速度,这种事情的好处就是您可以半连续地运行它,而它只会蚕食数据的尾端

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM