我在 Microsoft SQL Server 2005 服务器的数据库中有一个表,大小为 16gb,有 5800 万行。
它有一个名为“balance_forward”的列,它是 char(10)(数字列的不寻常选择,但我没有设计表格)我需要增加它的大小以容纳大小超过十个字符的余额(xxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. xx)
我尝试将其更改为 char(12) (有风险,我没有任何借口)但我认为*这导致数据库的日志文件增长了许多 GB(并填满了日志驱动器)并且操作仍然失败(数据类型仍然字符(10))
后来我意识到至少更改为 varchar(12) 会更有意义,这样该列不会强行占用更多空间,但它会有更多空间来容纳更大的数据。
我的问题是 - 这也会导致日志文件再次增长(我设法通过将其他文件移出日志驱动器来释放一些空间)
我是否正确地假设使用 varchar 而不是 char 会阻止现有数据占用更多空间?
(理想情况下,数据类型应更改为最适合财务余额的类型,但我认为这将是 5800 万行的更剧烈变化)
*我不能确定。我以为在操作之前我在日志驱动器上看到了足够的空间,但我可能看到了“mb”并将其误认为是“gb”。所以可能是日志已经填满了驱动器。显然日志可以增长,直到填满分配的驱动器/空间
基于这个和这篇文章,我会说,是的,从
char(10)
to的变化varchar(12)
会触及每一行,因此会增加日志。我的推理是,列已经从行结构的固定长度部分移动到可变长度部分,存储引擎将不得不立即保存这些信息。可变长度列将有两个字节的开销来跟踪实际长度(见上文)。如果您的数据的平均长度为 8 字节或更少,那么您将通过这种方式获得胜利。否则,您将占用更多空间
varchar
。您需要的数字可以以数字类型存储在 9 个字节中。我怀疑这会对您的应用程序造成太大的改变,即使它是保存这些数据的正确方法。
我建议您添加一个正确类型和长度的新可空列。从上面的帖子来看,这将是一个只有元数据的操作,日志记录最少。放置触发器以使新列与现有列保持同步。然后,您的应用程序可以在执行以下步骤时继续工作。以块的形式复制现有数据。在您的开发箱上进行测试,以找出适合您系统的已用时间和日志大小的块大小。根据我的经验,10,000 是正确的。一切就绪后,删除旧列和触发器,然后重命名新列。需要重建索引来回收空间。这是一些处理这个主题的SO帖子。