加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 检查外键约束“在线”

发布时间:2020-12-12 06:35:58 所属栏目:MsSql教程 来源:网络整理
导读:如果我们有一个巨大的事实表并且想要添加一个新维度,我们可以这样做: BEGIN TRANSACTIONALTER TABLE [GiantFactTable]ADD NewDimValueId INT NOT NULLCONSTRAINT [temp_DF_NewDimValueId] DEFAULT (-1)WITH VALUES -- table is not actually rebuilt!ALTER T
如果我们有一个巨大的事实表并且想要添加一个新维度,我们可以这样做:
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. (此时任何INSERT / UPDATE – 例如回填操作 – 都由FK验证,因为它已启用,但不是“可信”)

回填后我们知道数据是一致的,我的问题是SQL引擎怎么能开悟呢?不使表离线.

此命令将使FK受信任,但它需要架构修改(Sch-M)锁定,并且可能需要数小时(几天?)才能使表离线:

ALTER TABLE [GiantFactTable]
WITH CHECK CHECK CONSTRAINT [FK_GiantFactTable_NewDimValue]

关于工作负载:表有几百个分区(固定数量),数据一次附加到一个分区(以循环方式),从不删除.还有一个恒定的读取工作负载,它使用群集密钥一次从一个分区获取(相对较小的)行范围.
一次检查一个分区,使其脱机,是可以接受的.但我找不到任何语法来做到这一点.还有其他想法吗?

解决方法

我想到了一些想法,但它们并不漂亮:

重定向工作负载并脱机运行检查约束

>创建具有相同结构的新表.
>更改“插入”工作负载以插入新表
>将“读取”工作负载使用的分区中的数据复制到新表(或具有相同结构的第三个表)
>更改“读取”工作负载以使用新表
>运行alter table以检查约束,并在需要时使用它
>将两个工作负载更改回主表.
>将新行重新插入主表
>放新桌子

上面的变化是在步骤3中将相关分区切换到新表.这应该比复制数据更快但我认为在检查约束后你将不得不复制(而不仅仅是切换)数据.

将所有数据插入新表中

>创建一个启用了相同结构和约束的新表
>将“插入”工作负载更改为新表
>批量复制从旧表到新表的所有数据,并等待完成所需的时间
>将“读取”工作负载更改为新表.如果步骤3耗时太长而“读取”工作负载需要仅插入新表的行,则必须手动管理此转换.
>放下旧桌子

使用索引来加速约束检查?

我不知道这是否有效,但您可以尝试在外键列上创建非聚集索引.还要确保外键引用的表上的相关唯一键有索引. alter table命令可能能够使用它们来加速检查(至少通过最小化IO与执行全??表扫描相比).当然,索引可以在线创建,以避免任何中断.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读