RowVersion
列の値自体は、行が更新されるたびに変更されることを除いて、実際には役に立たないことを知っています。しかし、私はそれらが相対的(不平等)比較に役立つかどうか疑問に思っていました。
RowVersion
列を持つテーブルがある場合、次のいずれかが当てはまります。
RowVersion
列の値は同じですか?ありがとう。
MSDNから :
各データベースには、データベース内のrowversion
列を含むテーブルで実行される挿入または更新ごとに増分操作であるカウンターがあります。このカウンターはデータベースrowversion
です。これは、クロックに関連付けることができる実際の時間ではなく、データベース内の相対時間を追跡します。 毎回それ行rowversion
列変更または挿入、増分データベースrowversion
valueがrowversion
列に挿入されます。
http://msdn.Microsoft.com/en-us/library/ms182776.aspx
rowversion
sは一意である必要があります。同じテーブル内で重複が許可されている場合、それらは事実上役に立たないと言ってもいいでしょう。また、複製されないrowversion
sに信用を与えることは、違反を引き起こすのではなく、外部キーの問題を引き起こすので、それらを主キーとして使用しないというMSDNのスタンスです。どれだけ増加するかの質問に対して、MSDNは「[rowversion
]はデータベース内の相対時間を追跡する」と述べており、流動的な整数ではないことを示しています増加しますが、時間ベースです。ただし、この「時間」は、exactlyの場合は何も明らかにせず、むしろ他の行との関係で行が挿入/変更された場合を明らかにします。
いくつかの追加情報。 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
私はこれを使って何かを整理しようとする年齢を費やしました-特定のシーケンス番号の後に更新された列を求めるために。タイムスタンプは実際には単なるシーケンス番号です-BitConverter.ToInt64のようなc#関数がリトルエンディアンを必要とする場合、それはビッグエンディアンでもあります。
エイリアス列「SequenceNo」を使用して、データが必要なテーブルにdbビューを作成してしまいました
SELECT ID, CONVERT(bigint, Timestamp) AS SequenceNo
FROM dbo.[User]
c#コードは最初に通常のテーブルと同じようにビュー(つまり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)いいえ。この値は、行が更新されるたびに更新されます。行を5回更新する場合、更新ごとにタイムスタンプ値が増加します。もちろん、「同時に発生する」更新は実際には発生しないことに気づくでしょう。順番に、それらはまだ一度に1つだけ発生します。
2)はい。
注として、timestamp
はSQL Server 2008以降では非推奨です。代わりにrowversion
を使用してください。
MSDNの このページ から:
timestamp構文は非推奨になりました。この機能は、Microsoft SQL Serverの将来のバージョンで削除される予定です。新しい開発作業ではこの機能を使用せず、現在この機能を使用しているアプリケーションの変更を計画してください。
Rowversionは、SQLの「理想的な」アプローチの1つを壊します。UPDATEステートメントは単一のアトミックアクションであり、すべてのUPDATE(行内のすべての列とテーブル内のすべての行の両方)が "同時"。ただし、この場合、Rowversionを使用すると、ある行が別の行とは少し異なるタイミングで更新されたと判断できます。
行が(単一のupdateステートメントによって)更新される順序は保証されないことに注意してください。偶然にも、テーブルのクラスター化キーと同じ順序に従う可能性がありますが、私はそれが当てはまるとは限りません。
あなたの質問の一部に答えるには、MSDNによると値が重複する可能性があります。
重複する行バージョン値は、行バージョン列がSELECTリストにあるSELECT INTOステートメントを使用して生成できます。この方法でrowversionを使用することはお勧めしません。
すべてのデータベースには、データベースで行われるすべてのデータ変更に対して1つずつ増加するカウンターがあります。影響を受ける(更新/挿入による)行を含むテーブルにタイムスタンプ/行バージョン列が含まれている場合、データベースの現在のカウンター値は、更新/挿入されたレコードのその列に格納されます。