【发布时间】:2013-10-23 18:37:44
【问题描述】:
如果我们有一个巨大的事实表并想添加一个新维度,我们可以这样做:
BEGIN TRANSACTION
ALTER TABLE [GiantFactTable]
ADD NewDimValueId INT NOT NULL
CONSTRAINT [temp_DF_NewDimValueId] DEFAULT (-1)
WITH VALUES -- table is not actually rebuilt!
ALTER TABLE [GiantFactTable]
WITH NOCHECK
ADD CONSTRAINT [FK_GiantFactTable_NewDimValue]
FOREIGN KEY ([NewDimValueId])
REFERENCES [NewDimValue] ([Id])
-- drop the default constraint, new INSERTs will specify a value for NewDimValueId column
ALTER TABLE [GiantFactTable]
DROP CONSTRAINT [temp_DF_NewDimValueId]
COMMIT TRANSACTION
注意:以上所有操作都只处理表元数据,无论表大小如何,都应该很快。
然后我们可以运行一个作业在小事务中回填GiantFactTable.NewDimValueId,这样就不会违反 FK。 (此时任何插入/更新 - 例如回填操作 - 都由 FK 验证,因为它已启用,但不是“受信任的”)
回填后我们知道数据是一致的,我的问题是SQL引擎怎么也能开悟呢? 无需让表脱机。
此命令将使 FK 受信任,但它需要架构修改 (Sch-M) 锁定,并且可能需要数小时(数天?)才能使表脱机:
ALTER TABLE [GiantFactTable]
WITH CHECK CHECK CONSTRAINT [FK_GiantFactTable_NewDimValue]
关于工作负载:表有几百个分区(固定数量),数据一次附加到一个分区(以循环方式),从不删除。还有一个恒定的读取工作负载,它使用集群键一次从一个分区获取(相对较小)范围内的行。 一次检查一个分区并使其脱机是可以接受的。但我找不到任何语法来做到这一点。还有其他想法吗?
【问题讨论】:
标签: sql sql-server foreign-keys sql-server-2012 check-constraints