我们的数据库是SQL Server 2008 R2。我们有一些表,其中有一些 varchar(500) 列,我想将它们切换到 datetime2 或 bigint。我可以保证要切换的列中的所有数据对于正确的类型都是有效的。列更改确实会影响索引,但不会影响键。

在与同事讨论时,我们得出了两种解决该问题的方法。这两个操作都可以通过 T-Sql 脚本完成。

  1. 通过 select into 创建临时表,删除旧表并使用正确的数据类型重新创建表。重新创建索引。
  2. 通过更改当前表/数据类型ALTER TABLE x ALTER COLUMN Y datetime2 然后重建或重新创建索引。

因为我相信数据会干净地转换,所以我倾向于#2。我的同事和一位 DBA 朋友更喜欢#1,但我的同事不记得为什么要这样训练他。DBA 朋友正在度假,所以我没有问他原因。

有人可以提供他们认为更好的选项以及为什么的见解吗?最终这是我的决定,我想知道为什么#1 会比#2 更受青睐?

有帮助吗?

解决方案

我最近在我的组织中这样做了,我们想要处理一个包含十亿多行的表。

这个想法的所有功劳都归功于 Aaron Bertrand,并且来自他的博客文章 技巧射击:模式切换-A-Roo

在小桌子上测试以​​下过程,并在 PROD 中进行操作之前让自己感到舒服。

  1. 创建2个模式 fakeshadow 经授权 dbo.
  2. 创建一个包含所需列和数据类型的表 shadow 模式例如 create table shadow.Correct_Table ...
  3. 插入数据并创建原表有的所有索引 shadow 模式表。
  4. 这样,您就可以拥有包含数据和索引的相同表副本,但它们位于不同的架构中(逻辑上分离)。
  5. 完成后更新表上的统计信息 shadow 架构。
  6. 切换模式(这是元数据操作并且速度非常快)

    --- ALTER SCHEMA TargetSchema TRANSFER SourceSchema.TableName; 
    
    BEGIN TRANSACTION;
    
      ALTER SCHEMA fake TRANSFER     dbo.original_table;
      ALTER SCHEMA dbo  TRANSFER  shadow.Correct_Table;
    
    COMMIT TRANSACTION;
    
    ALTER SCHEMA shadow TRANSFER fake.Lookup;
    
  7. 进行最后检查,看看一切是否按计划进行。你应该做一个 select count(1) from dbo.Correct_table

  8. 确认第 7 步并且您满意后,请放弃 shadow.table, shadow 模式和 fake 架构作为清理。

其他提示

这是我的看法。

#1 的优点

  • 由于您使用的是单独的表,因此您的生产表将一直处于使用状态,直到您完成为止。没有锁(除了读取数据所需的锁)。
  • 这也符合@AaronBertrand 所说的:你可以零碎地做,测试等
  • 您可以根据需要更改列顺序

#2 的优点

  • 这是一个全有或全无的操作。当您没有查看时,您不可能丢失在原始表中插入/修改的数据。
  • 保留专门分配给该对象的任何权限。如果您使用#1,您必须确保编写脚本并应用它们。

话虽这么说,我通常会在小表或可能发生中断时使用#2(不过,总是事先进行备份),如果我无法得到那么大的中断或者我必须重新安排,则使用#1列顺序等如果我要做#1,我通常会通过 GUI 生成脚本,然后在运行之前仔细检查它。

请小心删除并重新创建选项:这可能会使 sys.depends 处于奇怪的状态,并导致列的顺序或类型发生变化的缓存计划出现问题。

您还需要采取措施维护任何对象级别权限,因为这些权限将在 DROP 并且不会自动重新创建后续的 CREATE.

ALTER TABLE 在我看来,是更干净的选项,但请确保在生产中执行之前进行彻底测试,以确保之后一切顺利,并确保您知道操作将花费多长时间(对于包含许多行的表,这可能会花费相当长的时间) )。

我的同事最终找到了一篇关于他所指内容的文章: http://www.nigelrivett.net/SQLAdmin/AlterTableProblems.html. 。阅读本文并意识到我们的年终报告即将发布后,我们决定不对列类型进行更改,并将在接下来的几个月内重新审视这一点。我想读完这篇文章后,我可能会选择 Drop/Create 方法。

感谢大家对此的反馈。当我们决定继续前进时,需要考虑许多有趣的方法。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top