엑시엄이 보는 DB 세상
오라클은 ROWID에도 숨은 아키텍처를 심어 놨다 0 0 99,999+

by axiom ROWID BASE64 [2014.05.22]


확장 ROWID는 오라클 8부터 오브젝트와 파티션의 개념이 도입되면서 데이터베이스의 세그먼트를 식별하기 위한 Data Object Number가 추가돼 10바이트로 관리되기 시작한다. 이것은 우리가 일반적으로 알 수 있는 내용이다.

ROWID는 다음과같이 구성 된다.

  • - ROWID type : OOOOOOFFFBBBBBBRRR
  • - 데이터베이스 세그먼트를 식별하기 위한 Data Object Number
  • - FFF : Tablespace에 상대적인 Data File Number
  • - BBBBBB : Row를 포함하는 Data Block Number
  • - RRR : Block에서의 Row의 Slot

ROWID는 10바이트로 구성된 16진수다!?

어느 날 ROWID의 구조에 대해 알아볼 필요가 생겼다. ROWID는 10바이트로 관리된다는 사실부터 시작했다

과연 10바이트로 돼 있을까? 당연히'0/B/F'문자들로 구성된 것으로 파악하고 2자리씩 1바이트로 계산해 봤더니 총 9바이트였다. 10바이트가 아닌 것이다.

그럼 나머지 1바이트는 어디로 갔을까? 매뉴얼도 물론 틀릴 수 있다. 그러나 매뉴얼에 대한 지식을 알고 그것을 파악하는 것은 독자들의 몫인 것이다. 즉 매뉴얼을 읽고 실제로 결과대로 나오는지 DB에 직접 접속해 봐야 한다.

ROWID가 그 대표적인 예라고 볼 수 있다. ROWID 슬롯 부분의'RRR'을 보자. 'RRR'은 16진수가 아닌 것을 알 수 있다. 16진수는'0~F'범위만을 가지기 때문이다. 즉 ROWID 출력 결과는 10바이트가 아니라는 것이다.

오라클은 우리가 모르는 또하나의 숨은 아키텍처를 심어 놓은 것이다. 이 글에서는 그 아키텍처가 무엇인지 분석하는 시간을 갖겠다.

ROWID의 숨은 아키텍처는 바로 이것

ROWID의 숨은 아키텍처는'BASE64 encoding'을 사용한다. BASE64의'64'는 64진수라는뜻이다

즉, 컴퓨터가 사용하는 2진수 데이터를 64진수로 표현하겠다는 것이다. BASE64 encoding의 구조를 보면 먼저 24비트 단위로 계산되고, 남는 비트가 생기면 그 뒤에 6비트 캐릭터를 0으로 패딩처리하게 되고, 추가로 남는 자리의 경우 6비트 캐릭터는 '='로 채워 넣는다

ROWID의 10바이트 구성을 설명한 [표 1]을 보자.

  • [표 1] ROWID 10바이트의 구성 포맷
  • ROWID 자릿수 범위 범위 (range) 크기 (bytes) Objet id 표현 범위
    1~6 1~32 4 0-4294967295
    7~9 33~44 1.5 0-4095
    10~15 45~64 2.5 0-1048575
    16~18 65~80 2 0-65535

BASE64 encoding의 구조 확인 - 준비 단계

지금까지 ROWID의 기본 지식에 대해 살펴봤다. 지금은 BASE64 encoding이 어떻게 ROWID를 표현하는지 확인해 보기로 하자.

[리스트 1]의 SQL은 해당 ROWID의 정보를 보여준다. 어떤 테이블이든지 상관없다.

  • [리스트 1] 해당 ROWID의 정보
  • SELECT ROWID as therowid, id
         , DBMS_ROWID.ROWID_OBJECT(ROWID) as objid
         , DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) as relfilenum
         , DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO(ROWID, 'SCOTT', 'T') as absfilenum
         , DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) as blocknum
         , DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) as rowslot 
      FROM t 
     WHERE id in (1, 2, 500, 501) 
     ORDER BY id; 
    
    THEROWID           ID   OBJID RELFILENUM ABSFILENUM BLOCKNUM ROWSLOT 
    ------------------ ---- ----- ---------- ---------- -------- -------
    AAACjyAAFAAAALNAAA 1    10482 5          5          717        0 
    AAACjyAAFAAAALNAAB 2    10482 5          5          717        1 
    AAACjyAAFAAAALPACG 500  10482 5          5          719      134 
    AAACjyAAFAAAALPACH 501  10482 5          5          719      135
    
    

[리스트 1]의 SQL 결과 중에 OBJECTID 부분인'AAACjy'와'10482'가 어떻게 매칭되는지 확인해 보기로 하자.

[그림 1]은 The Base64 Alphabet - Value Encoding 표이므로 이를 참고하면서 분석해 보자.

  • [그림 1] The Base64 Alphabet - Value Encoding
  • The Base64 Alphabet - Value Encoding

BASE64 encoding의 구조 확인 - 분석 단계

'AAACjy'는 각 자리수마다 6비트씩 계산된다는 것을 기억하자. Base64 Alphabet을 이용해 6비트마다 해당 문자를 매칭하면 [그림 2]과 같은 결과가 각각 나올것이다.

  • [그림 2] 문자 매칭 결과
  • 문자 매칭 결과

[그림 2]의 결과를 순서대로 붙여서 10진수로 표현하면, 결과 값은 '10482'가 나오게 된다. 이는 OBJID와 동일한 결과이며, 나머지도 같은 방법으로 찾으면 동일하다는것을 알수있다.

  • [그림 3] 10진수 표현 결과
  • 10진수 표현 결과

매뉴얼도 잘못된 내용이 나올 수 있다. 오라클 개발자들이 매뉴얼을 정리하는 것도 만만치 않을 뿐더러 간혹 상위버전에서 없어진 옵션 등을 그대로 놔두는 경우도 있고, 매뉴얼에 없는 옵션중에도 실제로 찾아보면 수행되는 것들이 많이 있는 것을 알 수있다.

이 글에서 언급한 ROWID는 그런 경우다. 매뉴얼에 간단히 설명된 ROWID의 실체를 DB에서 직접 확인하니 우리가 모르는 아키텍처가 심어져 있음을 새롭게 알수 있었다.

- 강좌 URL : http://www.gurubee.net/lecture/2757

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입