Вопрос

Я знаю, что само значение для RowVersion столбец сам по себе не полезен, за исключением того, что он меняется каждый раз, когда обновляется строка.Однако мне было интересно, полезны ли они для относительного сравнения (неравенства).

Если у меня есть таблица с RowVersion столбец, является ли верным любое из следующих значений:

  • Будут ли все обновления, которые происходят одновременно (либо одно и то же заявление об обновлении, либо одна и та же транзакция), иметь одинаковое значение в RowVersion колонна?
  • Если я выполню обновление "A", за которым последует обновление "B", будут ли строки, включенные в обновление "B", иметь более высокое значение, чем строки, включенные в обновление "A"?

Спасибо.

Это было полезно?

Решение

От MSDN:

Каждая база данных имеет счетчик, который увеличение для каждой вставки или обновления операция, которая выполняется на таблице, которая содержит rowversion столбец в базе данных. Этот счетчик является базой данных rowversion. Анкет Это отслеживает относительное время в базе данных, а не фактическое время, которое может быть связано с часами. Каждый раз что строка с rowversion столбец модифицируется или вставлен, увеличен база данных rowversion ценность вставлен в rowversion столбец.

http://msdn.microsoft.com/en-us/library/ms182776.aspx

  • Насколько я понимаю, на самом деле ничего не происходит одновременно в системе. Это означает, что все rowversionS должен быть уникальным. Я рискну сказать, что они были бы эффективно бесполезны, если бы дубликаты были разрешены в одной таблице. Также отдавая должное 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

Я потратил целую вечность, пытаясь что-то с этим уладить - запросить столбцы, обновленные после определенного порядкового номера.Временная метка на самом деле является просто порядковым номером - она также является bigendian, когда c # функционирует как BitConverter.ToInt64 хочет использовать littleendian.

В итоге я создал представление базы данных в таблице, из которой мне нужны данные, с псевдонимом столбца 'SequenceNo'

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();

чтобы получить то, что я хочу - все записи изменились с момента последней проверки.

Что заставляет вас думать, что типы данных TimeStamp - это зло? Тип данных очень полезен для проверки параллелистики. Linq-to-SQL использует этот тип данных для этой цели.

Ответы на ваши вопросы:

1) Нет. Это значение обновляется каждый раз, когда строка обновляется. Если вы обновляете строку, скажем, пять раз, каждое обновление увеличит значение временной метки. Конечно, вы понимаете, что обновления, которые «происходят одновременно», действительно не делают. Они все еще встречаются только по одному, в свою очередь.

2) Да.

Как примечание, timestamp устарел в SQL Server 2008 и далее. rowversion вместо этого следует использовать.

Из эта страница на MSDN:

А временная метка Синтаксис устарел. Эта функция будет удалена в будущей версии Microsoft SQL Server. Избегайте использования этой функции в новой разработке и планируйте изменять приложения, которые в настоящее время используют эту функцию.

Rowversion нарушает один из "идеалистических" подходов SQL - что оператор UPDATE является единым атомарным действием и действует так, как будто все обновления (как для всех столбцов в строке, так и для всех строк в таблице) происходят "одновременно".Но в этом случае, с помощью Rowversion, можно определить, что одна строка была обновлена в несколько иное время, чем другая.

Обратите внимание, что порядок, в котором обновляются строки (с помощью одного оператора update), не гарантируется - по совпадению он может следовать тому же порядку, что и кластеризованный ключ для таблицы, но я бы не стал рассчитывать на то, что это правда.

Чтобы ответить на часть вашего вопроса: вы можете получить дублирующие значения в соответствии с MSDN:

Дублирующие значения RowVersion могут быть сгенерированы с помощью оператора SELECT Into, в котором столбец RowVersion находится в списке SELECT. Мы не рекомендуем использовать Rowversion таким образом.

Источник: RowVersion (Transact-SQL)

Каждая база данных имеет счетчик, который увеличивается на один за другим на каждую модификацию данных, которая проводится в базе данных. Если таблица, содержащая затронутая (обновление/вставка) строка, содержит столбец TimeStamp/RowVersion, текущее значение счетчика базы данных сохраняется в этом столбце обновленной/вставленной записи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top