更改 nvarchar 列的大小时,是否需要删除唯一索引?重新创建索引时表会被锁定吗?

Sta*_*eff 14 index sql-server alter-table locking unique-constraint

在我们的数据库中存在一个大表,或多或少是这样的:

CREATE TABLE dbo.production_data
(
    pd_id BIGINT PRIMARY KEY,
    serial NVARCHAR(16) NOT NULL UNIQUE,
    ...
);
Run Code Online (Sandbox Code Playgroud)

但是现在串行字段的大小变得很小,所以我想将其更改为 32。Visual Studio 模式比较工具建议通过以下方式执行此操作:

DROP INDEX ux_production_data_serial ON dbo.production_data;
GO
ALTER TABLE dbo.production_data ALTER COLUMN serial NVARCHAR(32) NOT NULL;
GO
CREATE INDEX ux_production_data_serial ON dbo.production_data(serial ASC);
Run Code Online (Sandbox Code Playgroud)

这真的需要吗?或者更像是这样做的超级保存方式?

另外在重新创建唯一索引时,我的表会被锁定吗?因为这将是一个大问题(因为该表有 3000 万行,我猜重新创建索引需要相当长的时间),因为下一个维护窗口是未来几个月。我的选择是什么?

Mar*_*ith 24

无需删除和重新创建索引。

只需使用

ALTER TABLE dbo.production_data
  ALTER COLUMN serial NVARCHAR(32) NOT NULL; 
Run Code Online (Sandbox Code Playgroud)

这是仅元数据更改。

将列从 更改NVARCHAR(16)NVARCHAR(32)根本不会影响存储。

反过来(从 NVARCHAR(32)NVARCHAR(16))会给你一个关于对象依赖于列的错误,所以也许 Visual Studio 只是总是生成样板代码,而不是检查它是否真的需要。

  • 好奇为什么 Visual Studio 将其编写为 DROP/CREATE INDEX。可能是不必要的,无条件的 CYA。 (2认同)
  • @AaronBertrand - 我想这只是在不需要的情况下缺少优化。在线书籍表明,在产品实际上并不需要它的少数情况下需要它 [直到此更新](https://connect.microsoft.com/SQLServer/feedback/details/768134/documentation-for-alter -table-alter-column-restrictions-needs-reviewing) (2认同)