SQL Server RowVersion/时间戳 - 比较
我知道 RowVersion 列的值本身并没有什么用处,只是每次更新行时它都会发生变化。但是,我想知道它们对于相对(不平等)比较是否有用。
如果我有一个包含 RowVersion
列的表,则以下任一情况为 true:
- 同时发生的所有更新(相同的更新语句或相同的事务)在
RowVersion< 中是否具有相同的值/代码> 列?
- 如果我先更新“A”,然后更新“B”,则更新“B”中涉及的行的值是否会高于更新“A”中涉及的行的值?
谢谢。
I know that the value itself for a RowVersion
column is not in and of itself useful, except that it changes each time the row is updated. However, I was wondering if they are useful for relative (inequality) comparison.
If I have a table with a RowVersion
column, are either of the following true:
- Will all updates that occur simultaneously (either same update statement or same transaction) have the same value in the
RowVersion
column? - If I do update "A", followed by update "B", will the rows involved in update "B" have a higher value than the rows involved in update "A"?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
来自 MSDN:
每个数据库都有一个计数器对于数据库中包含
rowversion
列的表执行的每个插入或更新操作都会递增。该计数器是数据库rowversion
。这跟踪数据库内的相对时间,而不是与时钟关联的实际时间。 每次修改或插入具有rowversion
列的行时,增量 > 数据库rowversion
value 插入到rowversion
列中。http://msdn.microsoft.com/en-us/library/ms182776.aspx
对于增量多少的问题,MSDN 指出,“[
rowversion
] 跟踪数据库内的相对时间”,这表明它不是一个流动的整数增量,而是基于时间。然而,这个“时间”并没有揭示确切的时间,而是相对于其他行插入/修改行的时间。From MSDN:
Each database has a counter that is incremented for each insert or update operation that is performed on a table that contains a
rowversion
column within the database. This counter is the databaserowversion
. This tracks a relative time within a database, not an actual time that can be associated with a clock. Every time that a row with arowversion
column is modified or inserted, the incremented databaserowversion
value is inserted in therowversion
column.http://msdn.microsoft.com/en-us/library/ms182776.aspx
rowversion
s should be unique. I venture to say that they would be effectively useless if duplicates were allowed within the same table. Also giving credance torowversion
s not being duplicated is MSDN's stance on not using them as primary keys not because it would cause violations, but because it would cause foreign key issues.To the question of how much it increments, MSDN states, "[
rowversion
] tracks a relative time within a database" which indicates that it is not a fluid integer incrementing, but time based. However, this "time" reveals nothing of when exactly, but rather when in relation to other rows a row was inserted/modified.一些附加信息。
RowVersion 可以很好地转换为 bigint,因此在调试时可以显示更好的可读输出:
Some additional information.
RowVersion converts nicely to bigint and thus one can display better readable output when debugging:
需要注意的是,从 SQL Server 2008 开始,
timestamp
已被弃用。应改用rowversion
。来自 MSDN 上的此页面:
Just as a note,
timestamp
is deprecated in SQL Server 2008 onwards.rowversion
should be used instead.From this page on MSDN:
我花了很长时间试图解决这个问题 - 要求在特定序列号之后更新列。时间戳实际上只是一个序列号 - 当 BitConverter.ToInt64 等 C# 函数需要小尾数时,它也是大尾数。
我最终在我想要数据的表上创建了一个数据库视图,并使用别名列“SequenceNo”
c# 代码首先看到与普通表相同的视图(即 UserV),
然后在我的 linq 中我可以连接视图和父表并进行比较使用序列号
来获取我想要的内容 - 自上次检查以来所有条目都已更改。
I spent ages trying to sort something out with this - to ask for columns updated after a particular sequence number. The timestamp is really just a sequence number - it's also bigendian when c# functions like BitConverter.ToInt64 want littleendian.
I ended up creating a db view on the table i want data from with an alias column 'SequenceNo'
c# Code first sees the view (ie UserV) identically to a normal table
then in my linq I can join the view and parent table and compare with a sequence number
to get what I want - all the entries changed since the last time I checked.
是什么让您认为时间戳数据类型是邪恶的?该数据类型对于并发检查非常有用。 Linq-To-SQL 正是出于此目的使用此数据类型。
您的问题的答案:
1) 否。每次更新行时,该值都会更新。如果您要更新该行五次,则每次更新都会增加时间戳值。当然,您意识到“同时发生”的更新实际上并非如此。它们仍然一次只轮流出现一个。
2)是的。
What makes you think Timestamp data types are evil? The data type is very useful for concurrency checking. Linq-To-SQL uses this data type for this very purpose.
The answers to your questions:
1) No. This value is updated each time the row is updated. If you are updating the row say five times, each update will increment the Timestamp value. Of course, you realize that updates that "occur simultaneously" really don't. They still only occur one at a time, in turn.
2) Yes.
Rowversion 确实打破了 SQL 的“理想化”方法之一 - UPDATE 语句是单个原子操作,并且就像所有 UPDATE(对行中的所有列以及表中的所有行)都发生在“同一时间”。但在这种情况下,使用 Rowversion,可以确定一行的更新时间与另一行略有不同。
请注意,行更新的顺序(通过单个更新语句)无法保证 - 它可能巧合地遵循与表的聚集键相同的顺序,但我不认为这是真的。
Rowversion does break one of the "idealistic" approaches of SQL - that an UPDATE statement is a single, atomic action, and acts as if all UPDATEs (both to all columns within a row, and all rows within the table) occur "at the same time". But in this case, with Rowversion, it is possible to determine that one row was updated at a slightly different time than another.
Note that the order in which rows are updated (by a single update statement) is not guaranteed - it may, by coincidence follow the same order as the clustered key for the table, but I wouldn't count on that being true.
要回答您的部分问题:根据 MSDN,您最终可能会得到重复的值:
来源:行版本 (Transact-SQL)
To answer part of your question: you can end up with duplicate values according to MSDN:
Source: rowversion (Transact-SQL)
每个数据库都有一个计数器,每次在数据库中进行数据修改时,该计数器都会一一递增。如果包含受影响的(通过更新/插入)行的表包含时间戳/行版本列,则数据库的当前计数器值存储在更新/插入记录的该列中。
Every database has a counter that is incremented one by one on every data modification that is done in the database. If the table containing the affected (by update/insert) row contains a timestamp/rowversion column, the current counter value of the database is stored in that column of the updated/inserted record.