2013-12-10 2 views
9

Имеет ли Oracle аналогичный тип данных до SQL Server's RowVersion?SQL Server: эквивалент RowVersion в Oracle

При вставке или обновлении строки соответствующий столбец Версии (тип RowVersion) обновляется автоматически.

MSDN says about RowVersion:

  • ли тип данных, который предоставляет автоматически сгенерированный уникальный двоичные номера в базе данных. rowversion обычно используется как механизм для строк таблицы тиснения. Размер хранилища составляет 8 байтов. Тип данных rowversion - это просто увеличивающееся число и не сохранить дату или время.

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

  • Вы можете использовать столбец rowversion строки, чтобы легко определить, изменилось ли значение в строке с момента последнего его чтения. Если вносятся любые изменения в строку, значение rowversion обновляется. Если в строке не было изменений , значение rowversion будет таким же, как когда оно было ранее прочитано .

  • Вы можете добавить столбец rowversion в таблицу, чтобы поддерживать целостность базы данных , когда несколько пользователей обновляют строки в одновременно. Вы также можете узнать, сколько строк и какие строки были добавлены без повторного запроса таблицы.

Мы разрабатываем модель данных с оракулом и хотели бы использовать столбец Версии для управления параллелизмом.

Я также хотел бы знать, есть ли лучший способ в мире Oracle.

+0

row_Scn это делает. если включена зависимость строк. http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions142.htm – xQbert

ответ

4

Простой ответ No - но его легко создать с помощью столбца NUMBER и триггера установить/обновить его.

Простой пример для Oracle 11gR2:

CREATE SEQUENCE global_rowversion_seq; 

ALTER TABLE mytable1 ADD rowversion NUMBER; 

ALTER TABLE mytable2 ADD rowversion NUMBER; 

CREATE TRIGGER mytable1_biu 
    BEFORE INSERT OR UPDATE 
    ON mytable1 
    FOR EACH ROW 
BEGIN 
    :NEW.rowversion := global_rowversion_seq.NEXTVAL; 
END mytable1_biu; 

CREATE TRIGGER mytable2_biu 
    BEFORE INSERT OR UPDATE 
    ON mytable2 
    FOR EACH ROW 
BEGIN 
    :NEW.rowversion := global_rowversion_seq.NEXTVAL; 
END mytable2_biu; 

(Если вы на более ранней версии Oracle, присвоений в триггерах должно быть сделано с помощью запроса, например:

SELECT global_rowversion_seq.NEXTVAL 
    INTO :NEW.rowversion 
    FROM dual; 

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

В зависимости от того, как вы используете столбец rowversion, может быть целесообразно использовать отдельную последовательность для каждой таблицы. Это означало бы, конечно, что rowversion больше не будет глобально уникальным, но если вас интересует только сравнение изменений с строками в таблице, то это будет хорошо.

Другой подход заключается в продвижении счетчика для каждой строки в отдельности - это не нуждается в последовательности и позволяет обнаружить изменения в ряд (но не позволяет сравнивать любую строку на другую строку):

ALTER TABLE mytable ADD rowversion NUMBER; 

CREATE TRIGGER mytable_biu 
    BEFORE INSERT OR UPDATE 
    ON mytable 
    FOR EACH ROW 
BEGIN 
    :NEW.rowversion := NVL(:OLD.rowversion, 0) + 1; 
END mytable_biu; 

Каждая строка будет вставлена ​​с rowversion = 1, затем последующие обновления этой строки будут увеличивать ее до 2, 3 и т. Д.

+0

Привет, Вам кажется, что ближе к ответу, если бы вы могли подробнее рассказать об этой линии, было бы здорово. Я обновил вопрос, пожалуйста, проверьте его. Благодарю. – Falaque

+0

Спасибо, что ответили. – Falaque

14

Oracle имеет SCN (System Change Numbers): http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039

Ряд изменений системы (SCN) является логическим, внутренняя метка времени используется Oracle Database. SCN заказывают события, которые происходят в базе данных, что необходимо для удовлетворения ACID-свойств транзакции. Oracle Database использует SCN для отметки SCN, перед которой все изменения, как известно, находятся на диске, так что восстановление позволяет избежать ненужного повтора. База данных также использует SCN, чтобы отметить точку, в которой не существует повтора для набора данных, чтобы восстановление могло прекратиться.

SCN происходят в монотонно возрастающей последовательности.Oracle Database может использовать SCN как часы, потому что наблюдаемый SCN указывает на логическую точку во времени, а повторные наблюдения возвращают равные или более высокие значения. Если одно событие имеет более низкое значение SCN, чем другое событие, то оно произошло раньше времени в отношении базы данных. Несколько событий могут совместно использовать один и тот же SCN, что означает, что они произошли одновременно с базой данных.

Каждая транзакция имеет SCN. Например, если транзакция обновляет строку, база данных записывает SCN, с которой произошло это обновление. Другие изменения в этой транзакции имеют один и тот же SCN. Когда транзакция завершается, база данных записывает SCN для этого фиксации.


Используйте псевдостолбец ORA_ROWSCN для изучения текущего SCN строк:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/pseudocolumns007.htm#SQLRF51145

Пример:

SELECT ora_rowscn, t.* From test t; 

Demo ->http://www.sqlfiddle.com/#!4/535bc/1
(На SQLFiddle явные фиксаций, видимо, дон» t work - в реальной базе данных каждая фиксация увеличивает SCN).


Пример на «реальные» базах данных:

CREATE TABLE test(
    id int, 
    value int 
); 

INSERT INTO test VALUES(1,0); 
COMMIT; 
SELECT ora_rowscn, t.* FROM test t; 

ORA_ROWSCN   ID  VALUE 
---------- ---------- ---------- 
    3160728   1   0 

UPDATE test SET value = value + 1 WHERE id = 1; 
COMMIT; 
SELECT ora_rowscn, t.* FROM test t; 

ORA_ROWSCN   ID  VALUE 
---------- ---------- ---------- 
    3161657   1   1 

UPDATE test SET value = value + 1 WHERE id = 1; 
COMMIT; 
SELECT ora_rowscn, t.* FROM test t; 

ORA_ROWSCN   ID  VALUE 
---------- ---------- ---------- 
    3161695   1   2 

Если SCN транзакции будет знать, мы можем использовать запрос ретроспективного кадра, чтобы получить прошлое значение строки:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#g1026131

Пример:

SELECT t.*, 
     versions_startscn, versions_starttime, 
     versions_endscn, versions_endtime, 
     versions_xid, versions_operation 
FROM test VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE t; 

     ID  VALUE VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID  VERSIONS_OPERATION 
---------- ---------- ----------------- ------------------- --------------- ------------------- ---------------- ------------------ 
     1   2   3161695 13/12/10 08:19:39          06000300EA070000 U     
     1   1   3161657 13/12/10 08:18:39   3161695 13/12/10 08:19:39 06001200EA070000 U     
     1   0            3161657 13/12/10 08:18:39       


SELECT t.*, 
     versions_startscn, versions_starttime, 
     versions_endscn, versions_endtime, 
     versions_xid, versions_operation 
FROM test VERSIONS BETWEEN SCN 3161657 AND 3161657 t; 

     ID  VALUE VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID  VERSIONS_OPERATION 
---------- ---------- ----------------- ------------------- --------------- ------------------- ---------------- ------------------ 
     1   1   3161657 13/12/10 08:18:39          06001200EA070000 U        
+0

Спасибо за хороший ответ, но RowVersion является фактическим столбцом и используется для штамповки столбца. Цель ORA_ROWSCN не кажется такой. Я обновил вопрос, чтобы дать больше информации о RowVersion. – Falaque

+1

@Falaque: Нет, Oracle не имеет ** точного ** эквивалента столбца ROWVERSION SQL Server. Для оптимистического параллелизма используется ORA_ROWSCN. Было бы полезно, если бы вы обновили свой вопрос, чтобы дать больше информации о том, почему вы хотите ROWVERSION в Oracle. Если вы переносите базу данных из SQL Server в Oracle, вам необходимо опустить столбцы ROWVERSION из таблиц и использовать ORA_ROWSCN в запросах вместо всех столбцов ROWVERSION. Если это проблема, подумайте, что это просто верхушка айсберга с такими вещами, как очень разные модели изоляции транзакций или проблемы с строкой корпуса ... –

+0

@TomekSzpakowicz, спасибо. Я обновил вопрос. – Falaque

0

В соответствии с документацией оракула вы можете использовать ORA_ROWSCN и использовать «ROWDEPENDENCIES», чтобы сделать отслеживание зависимостей на уровне строки на уровне оракула. а не на физический блок данных.

Ref: https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns007.htm

http://www.dba-oracle.com/t_row_scn_rowdependencies.htm

Смежные вопросы