programing

SQL Server: Oracle에서 동일한 RowVersion

telecom 2023. 6. 24. 08:46
반응형

SQL Server: Oracle에서 동일한 RowVersion

Oracle의 데이터 유형이 SQL Server의 데이터 유형과 유사합니까?

할 때 열(은 행삽하거유나업할때열버해전당트이데입을(형))RowVersion는 자동으로 는 자동으로 업데이트됩니다.

MSDN은 RowVersion에 대해 다음과 같이 말합니다.

  • 데이터베이스 내에서 자동으로 생성된 고유 이진 번호를 표시하는 데이터 유형입니다.rowversion은 일반적으로 버전 변환 테이블 행의 메커니즘으로 사용됩니다.저장소 크기는 8바이트입니다.행 버전 데이터 유형은 증가하는 숫자일 뿐 날짜나 시간은 보존되지 않습니다.

  • 각 데이터베이스에는 데이터베이스 내에 행 버전 열이 포함된 테이블에서 수행되는 각 삽입 또는 업데이트 작업에 대해 증분되는 카운터가 있습니다.이 카운터는 데이터베이스 행 버전입니다.이것은 시계와 연관될 수 있는 실제 시간이 아니라 데이터베이스 내의 상대 시간을 추적합니다.테이블에는 하나의 행 버전 열만 있을 수 있습니다.행 버전 열이 있는 행을 수정하거나 삽입할 때마다 증분 데이터베이스 행 버전 값이 행 버전 열에 삽입됩니다.

  • 행의 행 버전 열을 사용하여 마지막으로 읽은 이후 행의 값이 변경되었는지 쉽게 확인할 수 있습니다.행이 변경되면 행 버전 값이 업데이트됩니다.행을 변경하지 않으면 행 버전 값은 이전에 읽었을 때와 동일합니다.

  • 여러 사용자가 동시에 행을 업데이트할 때 데이터베이스의 무결성을 유지하기 위해 행 버전 열을 테이블에 추가할 수 있습니다.테이블을 다시 쿼리하지 않고 업데이트된 행 수와 행 수를 확인할 수도 있습니다.

Oracle로 데이터 모델을 설계하고 있으며 Version 열을 사용하여 동시성을 관리하고자 합니다.

또한 오라클 세계에서 더 나은 방법이 있는지 알고 싶습니다.

Oracle의 SCN(시스템 변경 번호): http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039

SCN(시스템 변경 번호)은 Oracle Database에서 사용하는 논리적 내부 타임스탬프입니다.SCN은 트랜잭션의 ACID 속성을 충족하는 데 필요한 데이터베이스 내에서 발생하는 이벤트를 정렬합니다.Oracle Database는 SCN을 사용하여 모든 변경 사항이 Disk에 있는 것으로 알려진 SCN을 표시하므로 복구 시 불필요한 재실행이 적용되지 않습니다.또한 데이터베이스는 SCN을 사용하여 복구가 중지될 수 있도록 데이터 집합에 대한 redo가 존재하지 않는 지점을 표시합니다.

SCN은 단조롭게 증가하는 순서로 발생합니다.관찰된 SCN은 논리적 시점을 나타내고 반복된 관찰은 동일하거나 더 큰 값을 반환하므로 Oracle Database는 시계처럼 SCN을 사용할 수 있습니다.한 이벤트가 다른 이벤트보다 SCN이 낮은 경우 데이터베이스와 관련하여 이전에 발생했습니다.여러 이벤트가 동일한 SCN을 공유할 수 있으며, 이는 데이터베이스와 관련하여 동시에 발생했음을 의미합니다.

모든 트랜잭션에는 SCN이 있습니다.예를 들어 트랜잭션이 행을 업데이트하면 데이터베이스는 이 업데이트가 발생한 SCN을 기록합니다.이 트랜잭션의 다른 수정사항은 동일한 SCN을 가집니다.트랜잭션이 커밋되면 데이터베이스는 이 커밋에 대한 SCN을 기록합니다.


행의 합니다. ORA_ROWSCN은 SCN입니다.
http://docs.oracle.com/cd/B28359_01/server.111/b28286/.htm#SQLRF51145http ://docs.oracle.com/cd/B28359_01/server.111/b28286/pseudocolumns007.htm#SQLRF51145

예:

SELECT ora_rowscn, t.* From test t;

데모 --> http://www.sqlfiddle.com/ #!4/535bc/1
(SQLFiddle에서는 명시적 커밋이 작동하지 않습니다. 실제 데이터베이스에서는 각 커밋이 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/.htm#g1026131http ://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                               

간단한 대답은 아니오입니다. 그러나 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;

경우에 따라 이 설계는 동일한 시퀀스를 사용하는 모든 데이터베이스 삽입/업데이트의 경합으로 인해 극단적인 상황(예: 삽입/업데이트 작업이 매우 높은 데이터베이스)에서 성능에 영향을 미칠 수 있습니다.물론 이러한 상황에서는 어쨌든 처음부터 트리거를 피할 수 있습니다.

행 버전 열을 사용하는 방법에 따라 대신 각 테이블에 대해 별도의 시퀀스를 사용하는 것이 좋습니다.이는 물론 행 버전이 더 이상 글로벌하게 고유하지 않다는 것을 의미하지만, 테이블 내의 행과 변경 사항을 비교하는 데만 관심이 있다면 이 방법으로도 괜찮습니다.

또 다른 방법은 각 행의 카운터를 개별적으로 전진시키는 것입니다. 이 방법을 사용하면 시퀀스가 필요하지 않고 행의 변경 사항을 감지할 수 있습니다(단, 행을 다른 행과 비교할 수는 없습니다).

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 등으로 증가합니다.

오라클 문서에 따르면 ORA_ROWSCN을 사용하고 "ROWDEPENCYNS"를 사용하여 오라클 행 수준 종속성을 추적할 수 있습니다.물리적 데이터 블록당 아님.

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

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

언급URL : https://stackoverflow.com/questions/20487657/sql-server-rowversion-equivalent-in-oracle

반응형