假设我有一个包含许多表格的数据库。我想在某些表上执行数据存档,即创建一个具有相同结构(相同的约束,索引,列,触发器等)的相同表作为新表,并将特定数据从旧表插入到新表中。
示例,当前表包含2008-2017的数据,我想仅将2010-2017中的数据移动到新表中。然后,我可以删除旧表并使用类似于旧表的命名约定重命名新表。
我该如何处理?
答案 0 :(得分:1)
对于你所讨论的克隆重命名 - 丢弃逻辑的类型,基础知识非常简单。真的唯一一次这是一个好主意,如果你有一个包含大量数据的表,你无法承受停机时间或阻塞,你只打算这样做。这个过程看起来像这样:
sp_rename
原始表(例如)myTable
到myTable_OLD
(只是区别于真实表格的东西)。然后sp_rename
克隆表从(例如)myTable_CLONE
到myTable
myTable_OLD
。如果它不能按您的要求工作,只需回复sp_rename
个对象。如果你走那条路,就要考虑几点考虑因素
identity_insert on
,然后重新设置标识,以便在旧标识停止的位置进行检索(nolock)
插入我需要的所有行,或者你需要这样做,这样可以减轻原始表中select的影响。然后,在我移动了99%的数据之后,我将打开一个事务,阻止原始表,插入只是自大量数据移动后进入的新数据,然后执行sp_rename
的东西
sp_rename
<之间原始表格中的最后一位数据/ LI>
<强>替代强> 我想到了其他一些选择:
表格分区: 这会跨多个分区对单个表进行分片(可以像单个表一样进行管理)。比方说,您可以按年度对数据进行分区,然后当您想要清除数据的结尾年份时,可以将该分区“切换”为特殊的表,然后可以截断该表。所有这些操作都只是元数据,所以它们非常快。这对于大量数据非常有效,其中删除和所有讨厌的事务日志记录都不可行
表格分区的缺点是设置和管理是一种痛苦。
批量删除: 如果您的数据不是太,那么您可以在数据的尾端进行批量删除。如果你能找到一种方法来获取删除的聚集索引,那么它们应该合理地轻量级。只要你没有比你可以摆脱它更快地积累数据,这种事情的好处是你只是半连续地运行它,它只是蚕食数据的尾端
快照隔离:
如果删除导致阻塞过多,您还可以设置快照隔离等功能,基本上可以在tempdb
中存储行的历史版本。设置isolation level read committed snapshot
的任何查询都将读取那些更改前的行,而不是争夺“真实”表上的锁。然后,您可以对您的内容进行批量删除,并且知道任何打到表的查询都不会被删除(或任何其他DML操作)阻止,因为他们要么读取删除前快照,要么他们会读取删除后快照。他们不会等待进程内删除以确定它是否将提交或回滚。不幸的是,这并非没有缺点。对于大型数据集,它可能会给tempdb
带来很大的负担,它也可能是一个黑盒子。这也需要你的DBA支持。