我可以创建一个带有默认值和外键的新列作为仅元数据操作吗?

Mic*_*art 4 sql-server

可以使用默认值创建一个新列作为仅元数据操作(不是数据大小操作):

ALTER TABLE dbo.MyReallyBigTable
ADD MyThingId INT NOT NULL 
    DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)

但是是否也可以创建这样一个引用另一个表作为仅元数据操作的列?

ALTER TABLE dbo.MyReallyBigTable
ADD MyThingId INT NOT NULL 
    DEFAULT 0 
    REFERENCES dbo.MyThing(MyThingId);
Run Code Online (Sandbox Code Playgroud)

理论上这是可能的,因为在引用的表中应该只有一个值要检查。但是,在我的示例中,外键创建似乎是一个数据大小操作。

Dav*_*oft 5

您可以这样做,但前提是您在创建时不检查 FK。外键将对后续的 INSERT 和 UPDATE 强制执行,但不会被查询优化器信任。例如:

drop table if exists MyReallyBigTable
drop table if exists MyThing
go
select o.* into dbo.MyReallyBigTable
from sys.objects o, sys.columns c

go
create table MyThing(MyThingId int primary key )
insert into MyThing(MyThingId) values (0)

set statistics io on
go
ALTER TABLE dbo.MyReallyBigTable
ADD MyThingId INT NOT NULL 
    DEFAULT 0 
    --REFERENCES dbo.MyThing(MyThingId);
go
alter table MyReallyBigTable
with nocheck
add constraint  fk_MyReallyBigTable_MyThing 
foreign key (MyThingId) references MyThing(MyThingId)
set statistics io off
Run Code Online (Sandbox Code Playgroud)

当您有时间进行表扫描并检查所有行以使 FK 受信任时,您可以稍后回来:

select name, is_not_trusted 
from sys.foreign_keys
go
alter table MyReallyBigTable with check check constraint fk_MyReallyBigTable_MyThing
go
select name, is_not_trusted 
from sys.foreign_keys
Run Code Online (Sandbox Code Playgroud)