SQL Server Rowversion/Timestamp-比较
-
11-10-2019 - |
题
我知道一个价值本身 RowVersion
列本身没有用,除了每次更新行时它都会更改。但是,我想知道它们是否对相对(不平等)比较有用。
如果我有一张桌子 RowVersion
列,是以下是正确的:
- 所有同时发生的更新(相同的更新语句或同一事务)是否都具有相同的值
RowVersion
柱子? - 如果我确实更新“ a”,然后是更新“ b”,“ b”中涉及的行是否比更新“ A”中涉及的行更高?
谢谢。
解决方案
每个数据库都有一个计数器 每个插入或更新都增加 在包含一个的表上执行的操作 rowversion
数据库中的列。此计数器是数据库 rowversion
. 。这跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间。 每次 那 一排 与 rowversion
柱子 被修改或插入, , 这 递增 数据库 rowversion
价值 被插入 rowversion
柱子。
http://msdn.microsoft.com/en-us/library/ms182776.aspx
- 据我了解,系统中实际上没有同时发生任何事情。这意味着所有人
rowversion
S应该是唯一的。我冒险说,如果在同一张桌子中允许重复项,它们将有效地无用。还要信任rowversion
MSDN对不使用它们作为主要钥匙的立场并不是因为会导致违规行为,而是因为它会导致外国关键问题。 - 根据MSDN的说法,“ Rowversion数据类型只是一个增量的数字……”因此,是的,以后更大。
提出问题 多少钱 MSDN指出,它会增加[[rowversion
]跟踪数据库中的相对时间“表明它不是流体整数的增加,而是基于时间的。但是,此“时间”一无所获 确切地, ,而是什么时候 与其他行有关 一行插入/修改。
其他提示
一些其他信息。 Rowversion可以很好地转换为BigInt,因此调试时可以显示更好的可读输出:
CREATE TABLE [dbo].[T1](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
[RowVer] [timestamp] NOT NULL
)
insert into t1 ([value]) values ('a')
insert into t1 ([value]) values ('b')
insert into t1 ([value]) values ('c')
select Id, Value,CONVERT(bigint,rowver)as RowVer from t1
update t1 set [value] = 'x' where id = 3
select Id, Value,CONVERT(bigint,rowver)as RowVer from t1
update t1 set [value] = 'y'
select Id, Value,CONVERT(bigint,rowver)as RowVer from t1
Id Value RowVer
1 a 2037
2 b 2038
3 c 2039
Id Value RowVer
1 a 2037
2 b 2038
3 x 2040
Id Value RowVer
1 y 2041
2 y 2042
3 y 2043
我花了很长时间试图解决这个问题 - 要求在特定序列编号后更新列。时间戳实际上只是一个序列编号 - 当C#函数BitConverter.toint64想要Littleendian时,它也是Bigendian。
我最终在我想要使用别名列“ Sequenceno”的数据的表上创建了DB视图
SELECT ID, CONVERT(bigint, Timestamp) AS SequenceNo
FROM dbo.[User]
C#代码首先看到视图(IE USERV)与普通表相同
然后在我的linq中,我可以加入视图和父表,并与序列编号进行比较
var users = (from u in context.GetTable<User>()
join uv in context.GetTable<UserV>() on u.ID equals uv.ID
where mysequenceNo < uv.SequenceNo
orderby uv.SequenceNo
select u).ToList();
要获得我想要的东西 - 自上次检查以来,所有条目都更改了。
是什么让您认为时间戳数据类型是邪恶的?数据类型对于并发检查非常有用。 LINQ-TO-SQL用于此目的。
您问题的答案:
1)否。每次更新行时,都会更新此值。如果要更新行说五次,则每个更新将增加时间戳值。当然,您意识到“同时发生”的更新确实不会。他们仍然一次只发生一次。
2)是的。
作为注意, timestamp
在SQL Server 2008中被弃用。 rowversion
应该使用。
从 这一页 在MSDN上:
这 时间戳 语法被弃用。此功能将在Microsoft SQL Server的未来版本中删除。避免在新开发工作中使用此功能,并计划修改当前使用此功能的应用程序。
Rowversion确实打破了SQL的“理想主义”方法之一 - 更新语句是一个单一的原子操作,并且表现得好像所有更新(对行中的所有列,以及表中的所有行)都出现在“同时”。但是在这种情况下,使用Rowversion,可以确定一排的更新与另一行更新。
请注意,无法保证行更新行更新(通过单个更新语句)的顺序 - 它可以巧合遵循与表格的群集密钥相同的顺序,但我不会指望这是真的。
要回答您的问题的一部分:您可以根据MSDN最终获得重复的值:
可以通过将“选择中的选择”列表中的“选择”列表中的选择来生成重复的Rowversion值。我们不建议以这种方式使用Rowversion。
每个数据库都有一个计数器,该计数器会在数据库中完成的每个数据修改。如果包含受影响的(通过更新/插入)行的表包含时间戳/rowversion列,则数据库的当前计数器值存储在更新/插入的记录的该列中。