首页 > 解决方案 > SSDT 将 2 列添加到表的末尾会导致表重建

问题描述

我们正在使用 Azure DevOps 将更改自动部署到我们的生产数据库,这是一个 Azure SQL 数据库。这对于大多数版本来说运行良好,因为我们大部分时间都进行了有限的更改。有时给我们带来问题的是需要大量时间才能完成的表重建。最终结果很好,只有长时间运行会导致网站停机,这是我们无法承受的。

我们在 Visual Studio 中使用一个数据库项目来管理这个和其他一些数据库。这包括我们在使用 SSDT 发布时包含的 xml 文件,其中包含部署过程的设置。(即忽略列顺序等)。

以下更改导致表的表重建:

CREATE TABLE [dbo].[AccountCompany] (
    [CompanyId]                   INT             IDENTITY (1, 1) NOT NULL,
    [AccountTypeCode]             NVARCHAR (2)    DEFAULT ('00') NOT NULL,
    <Various columns, some with defaults>
    [PONumberMandatoryUpstream] BIT NULL, 
    [PONumberMandatoryDownstream] BIT NULL, 
    CONSTRAINT [PK_AccountCompany] PRIMARY KEY CLUSTERED ([CompanyId] ASC),
    CONSTRAINT [FK_AccountCompany_AccountBranchType] FOREIGN KEY ([BranchTypeCode]) REFERENCES [dbo].[AccountBranchType] ([BranchTypeCode]),
    CONSTRAINT [FK_AccountCompany_AccountCustomerBusinessSegment] FOREIGN KEY ([BusinessSegment]) REFERENCES [dbo].[AccountCustomerBusinessSegment] ([BusinessSegmentCode]),
    CONSTRAINT [FK_AccountCompany_AccountDmsEndpoint] FOREIGN KEY ([DmsEndpointId]) REFERENCES [dbo].[AccountDmsEndpoint] ([DmsEndpointId]),
    CONSTRAINT [FK_AccountCompany_AccountDmsType] FOREIGN KEY ([DmsTypeCode]) REFERENCES [dbo].[AccountDmsType] ([DmsTypeCode]),    
    CONSTRAINT [FK_AccountCompany_AccountType] FOREIGN KEY ([AccountTypeCode]) REFERENCES [dbo].[AccountType] ([AccountTypeCode]),
    CONSTRAINT [FK_AccountCompany_Currency_Purchase] FOREIGN KEY ([PurchaseCurrencyCode]) REFERENCES [dbo].[Currency] ([CurrencyCode]),
    CONSTRAINT [FK_AccountCompany_Currency_Sales] FOREIGN KEY ([SalesCurrencyCode]) REFERENCES [dbo].[Currency] ([CurrencyCode]),
    CONSTRAINT [FK_AccountCompany_MasterLanguage] FOREIGN KEY ([CultureCode]) REFERENCES [dbo].[MasterLanguage] ([CultureCode])
);

GO
CREATE NONCLUSTERED INDEX [IX_AccountCompany_LocationCode_Active]
    ON [dbo].[AccountCompany]([LocationCode] ASC, [Active] ASC)
    INCLUDE([AccountTypeCode], [BranchTypeCode], [DeliveryTimeDealer], [DeliveryTimeDealerGroup], [DeliveryTimeDealerPreferred], [DeliveryTimeFacingPdc], [DeliveryTimeTotalPaccar], [DmsDealerId], [DmsEndpointId], [DmsTypeCode], [FleetCustomerCode], [Guid], [CultureCode], [LogoAssetSequential], [LogoUrl], [Name], [PurchaseCurrencyCode], [RowVersion], [RushOrder], [SalesCurrencyCode]);

GO
CREATE NONCLUSTERED INDEX [IX_AccountCompany_Guid]
    ON [dbo].[AccountCompany]([Guid] ASC);

GO
CREATE NONCLUSTERED INDEX [IX_AccountCompany_DmsTypeCode]
    ON [dbo].[AccountCompany]([DmsTypeCode] ASC);

GO
CREATE NONCLUSTERED INDEX [IX_AccountCompany_AccountTypeCode]
    ON [dbo].[AccountCompany]([AccountTypeCode] ASC);

最后两列 PONumberMandatoryUpstream 和 PONumberMandatoryDownstream 可能会导致表重建。两列都是新列,并添加到表的末尾,没有外键/约束/索引。如果我手动与模式比较进行比较,我只会看到一个不重建表的 ALTER TABLE ADD COLUMN 语句。由于某种原因,自动部署决定表需要重建。

任何人都知道为什么 SSDT 认为该表需要重建?

我的第一个猜测可能与发布 xml 文件中的设置有关。我尝试将这些设置与架构比较中的设置进行比较,但似乎没有区别。如果需要,我可以包含部署日志和发布设置文件。

标签: sql-serverdatabaseazureazure-sql-databasesql-server-data-tools

解决方案


经过两天的调试,我弄清楚了问题所在。结果我们的一位管理员启用了数据库发现和分类https://docs.microsoft.com/en-us/azure/sql-database/sql-database-data-discovery-and-classification?tabs=azure-t-sql . 这在表定义中添加了一些关于特定列和分类的额外 SQL 语句,这些语句不在数据库项目中。每次部署这些表都会重建,在我们的例子中是 44 个表。

这种分类结构是相当新的,ssdt 部署还不能在管道中处理它。将这些语句添加到数据库项目中不起作用,因为这会在管道中产生错误,例如未知语句。我们唯一的选择是在 ssdt 支持之前禁用分类。


推荐阅读