我会保持这个简短而甜蜜的。我正在尝试将类型列添加rowversion
到现有表中。我的想法是,通过将其添加为NULL
,现有行不会被标记时间戳,但可惜它们是。如果这是这种行为,那么该列在什么情况下会接受空值?
2 回答
如果他们让您选择将其设为可空类型,那么可空与不可空之间的功能区别是什么
在实践中没有功能差异(但可能存在存储差异,见下文)。您不能插入NULL
到rowversion
列中。
即使您在语句中NULL
为rowversion
列指定INSERT
,服务器也会插入生成的非空值。无论您如何声明rowversion
列(NULL
或NOT NULL
),它都会像这样工作。
文档只提到一次可以为空rowversion
:
不可为空的
rowversion
列在语义上等同于binary(8)
列。可为空的rowversion
列在语义上等同于varbinary(8)
列。
如果您指定rowversion
nullable,它应该在磁盘上占用更多空间以允许存储可能的NULL
值(这在实践中是不可能发生的)。每个可为空的列都会产生开销,请参阅:SQL Server 中“空”值的大小
除了存储空值所需的空间之外,还有一个可以为空的列的开销。
此外,varbinary(8)
在磁盘上占用的空间比binary(8)
存储值的长度要多。
说了这么多,我尝试创建两个表,每个表有 10M 行。一个带有可空rowversion
列,第二个带有不可空rowversion
列。在我的测试中,两个表占用的磁盘空间完全相同。我在 SQL Server 2014 Express 上进行了测试。
即使您将其设置为 NULL,rowversion 也会取一个值:
CREATE TABLE MyTest (myKey int PRIMARY KEY, myValue int);
GO
INSERT INTO MyTest (myKey, myValue) VALUES (1, 0);
GO
INSERT INTO MyTest (myKey, myValue) VALUES (2, 0);
GO
SELECT * FROM MyTest;
GO
ALTER TABLE MyTest ADD rv rowversion NULL;
GO
SELECT * FROM MyTest;
GO
DROP TABLE MyTest;
+-------+---------+------------+
| myKey | myValue | rv |
+-------+---------+------------+
| 1 | 0 | 0000020331 |
+-------+---------+------------+
| 2 | 0 | 0000020332 |
+-------+---------+------------+