2013-12-10 12 views
9

Czy Oracle ma podobny typ danych do SQL Server's RowVersion?Serwer SQL: odpowiednik RowVersion w Oracle

Po wstawieniu lub aktualizacji wiersza odpowiednia kolumna wersji (która jest typu RowVersion) zostanie zaktualizowana automatycznie.

MSDN says about RowVersion:

  • to typ danych, który naraża generowane automatycznie, unikalne binarnych numerów w bazie danych. Rowversion jest ogólnie używany jako mechanizm dla wierszy tabeli wytłaczania wersji. Rozmiar pamięci to 8 bajtów. Typ danych wierszowania z rzędami jest po prostu liczbą rosnącą i nie zachowuje daty ani czasu.

  • Każda baza danych posiada licznik, który jest zwiększany dla każdej wkładki lub operacji aktualizacji, który jest wykonywany na stole, który zawiera kolumnę rowversion w bazie danych. Ten licznik jest bazą danych rowversion. Śledzi to względny czas w bazie danych, a nie rzeczywisty czas, który można powiązać z zegarem. Tabela może mieć tylko jedną kolumnę z wierszowaniem. Za każdym razem, gdy wiersz z kolumną wierszowania został zmodyfikowany lub wstawiony, zwiększana jest wartość wierszająca bazy danych wstawiona w kolumnie z wierszowaniem.

  • Możesz użyć kolumny rowversion rzędu, aby łatwo określić, czy wartość w wierszu zmieniła się od czasu ostatniego odczytu. Jeśli w wierszu zostanie wprowadzona jakakolwiek zmiana, wartość rzędowości zostanie zaktualizowana. Jeśli w wierszu nie zostanie wprowadzona żadna zmiana, wartość rzędowości będzie taka sama, jak poprzednio odczytana w dniu .

  • Możesz dodać kolumnę rowversion do stołu, aby pomóc utrzymać integralność bazy danych, gdy wielu użytkowników aktualizowania wierszy w samym czasie. Możesz także chcieć wiedzieć, ile wierszy i wierszy zostało zaktualizowanych bez konieczności ponownego wysyłania zapytania do tabeli.

Jesteśmy projektowania modelu danych z Oracle i chciałby wykorzystać kolumnę Version zarządzać współbieżności.

Chciałbym również wiedzieć, czy istnieje lepszy sposób w świecie Oracle.

+0

row_Scn to robi. jeśli włączone są zależności wierszy. http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions142.htm – xQbert

Odpowiedz

4

Prosta odpowiedź brzmi "Nie", ale łatwo jest samodzielnie utworzyć kolumnę z numerem i wyzwalaczem ustawić/zaktualizować.

Prostym przykładem dla 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; 

(Jeśli jesteś na wcześniejszej wersji Oracle, przypisania w wyzwalacze muszą być wykonane z zapytaniem, np:

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

Pamiętajmy, że w niektórych przypadkach projekt ten może mieć wpływ na wydajność w sytuacjach ekstremalnych (np. W bazach danych o bardzo wysokiej aktywności wstawiania/aktualizacji) z powodu rywalizacji ze wszystkimi wstawieniami/aktualizacjami bazy danych przy użyciu tej samej sekwencji. prawdopodobnie uniknie wyzwalaczy w pierwszym miejsce mimo to.

W zależności od tego, w jaki sposób korzystasz z kolumny rowversion, dobrym pomysłem może być użycie oddzielnej sekwencji dla każdej tabeli. Oznaczałoby to oczywiście, że rowversion nie byłby już globalnie unikalny - ale jeśli interesuje Cię tylko porównywanie zmian w wierszach w tabeli, to byłoby dobrze.

Innym podejściem jest postęp licznik dla każdego wiersza z osobna - to nie musi sekwencję i pozwala na wykrycie zmian w rzędzie (ale nie pozwala na porównanie dowolnego wiersza do innego wiersza):

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; 

Każdy wiersz zostanie wstawiony z rowversion = 1, a kolejne aktualizacje tego wiersza zwiększą go do 2, 3 itd.

+0

Cześć, Wydajesz się być bliżej odpowiedzi, gdybyś mógł rozwinąć więcej na tej linii, byłoby wspaniale. Mam zaktualizowane pytanie, proszę to sprawdzić. Dzięki. – Falaque

+0

Dzięki za odpowiedź. – Falaque

14

Oracle ma SCN (System zmiany numerów) http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039

Szereg zmian systemu (SCN) jest logiczne, wewnętrzny datownik stosowany przez Oracle Database. SCN porządkują zdarzenia, które występują w bazie danych, co jest konieczne, aby spełnić właściwości ACID transakcji. Baza danych Oracle używa numerów SCN do oznaczania numeru SCN, przed którym znane są wszystkie zmiany na dysku, tak aby odzyskiwanie nie powodowało niepotrzebnych powtórzeń. Baza danych wykorzystuje również numery SCN do oznaczenia punktu, w którym nie ma żadnych powtórzeń dla zestawu danych, aby można było zakończyć odzyskiwanie.

SCN występują w sekwencji rosnącej monotonicznie.Baza danych Oracle może używać SCN, podobnie jak zegar, ponieważ zaobserwowany SCN wskazuje na punkt logiczny w czasie, a powtarzające się obserwacje zwracają równe lub większe wartości. Jeśli jedno zdarzenie ma niższy numer SCN niż inne zdarzenie, miało ono miejsce wcześniej w odniesieniu do bazy danych. Kilka zdarzeń może mieć ten sam numer SCN, co oznacza, że ​​miały miejsce w tym samym czasie w odniesieniu do bazy danych.

Każda transakcja ma numer SCN. Na przykład, jeśli transakcja aktualizuje wiersz, baza danych rejestruje numer SCN, w którym wystąpiła ta aktualizacja. Inne modyfikacje tej transakcji mają ten sam numer SCN. Kiedy transakcja zostanie zatwierdzona, baza danych zarejestruje numer SCN dla tego zatwierdzenia.


Użyj pseudocolumn ORA_ROWSCN zbadać aktualną SCN rzędów:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/pseudocolumns007.htm#SQLRF51145

przykład:

SELECT ora_rowscn, t.* From test t; 

Demo ->http://www.sqlfiddle.com/#!4/535bc/1
(Na SQLFiddle wyraźne commity najwyraźniej don” t działa - na prawdziwej bazie danych każde zatwierdzenie zwiększa SCN).


Przykładem na „prawdziwe” bazy danych:

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 

Jeśli SCN transakcji jest wiedzieć, możemy użyć zapytania flashback do uzyskania przeszłości wartość rzędu:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#g1026131

Przykład:

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

Dzięki za fajną odpowiedź, ale RowVersion jest rzeczywistą kolumną i jest używana do oznaczania wersji kolumny. Cel ORA_ROWSCN nie wydaje się tak. Zaktualizowałem pytanie, aby uzyskać więcej informacji na temat RowVersion. – Falaque

+1

@Falaque: Nie, Oracle nie ma ** dokładnego ** odpowiednika kolumny SQL Server ROWVERSION. Aby uzyskać optymalną współbieżność, stosuje się ORA_ROWSCN. Byłoby pomocne, gdybyś zaktualizował swoje pytanie, aby dać więcej perspektywy na pytanie, dlaczego chcesz ROWVERSION w Oracle. Jeśli przenosisz bazę danych z SQL Server do Oracle, musisz pominąć kolumny ROWVERSION z tabel i użyć ORA_ROWSCN w zapytaniach zamiast nazw wszystkich kolumn ROWVERSION. Jeśli to jest problem, potraktuj to jako tylko wierzchołek góry lodowej, a rzeczy takie jak bardzo różne modele izolacji transakcji lub problemy z obudową ciągów będą następne ... –

+0

@TomekSzpakowicz, dziękuję. Zaktualizowałem pytanie. – Falaque