의사 컬럼

SQL 의사 컬럼(Pseudo Column)은 테이블의 컬럼처럼 동작하지만 실제로 테이블에 저장되지 않은 컬럼으로 사용자가 선언하지 않아도, Tibero 시스템이 자동으로 모든 테이블에 포함하는 컬럼입니다.

의사 컬럼은 사용자가 명시적으로 선언하지 않아도, Tibero 시스템이 자동으로 모든 테이블에 포함하는 컬럼입니다.

ROWID

ROWID는 전체 데이터베이스 내의 하나의 로우를 유일하게 참조하는 식별자 입니다. ROWID는 그로우의 디스크의 물리적인 위치를 가리키고 있으며, 그 로우가 삭제될 때까지 변화되지 않습니다.

Tibero에서는 데이터베이스의 저장을 위한 디스크 구조를 다단계로 구성하고 있습니다. ROWID를 이용해 디스크의 특정 로우를 찾아가기 위해서 ROWID는 이러한 디스크 구조를 반영해야 합니다.

Tibero의 ROWID 구조

Segment#
Data File#
Data Block#
Row#

4byte

2byte

4byte

2byte

  • ROWID는 전체 12byte로 구성되어 있으며, Segment, Data File, Data Block, Row가 각각 4, 2, 4, 2byte로 되어 있습니다.

  • ROWID 값을 표현하기 위한 포맷으로는 BASE64 인코딩을 이용합니다. BASE64 인코딩은 6bits에 포함된 숫자를 8bits 문자로 나타내는 방식으로, 0 ~ 63까지의 숫자를 A ~ Z, a ~ z, 0 ~ 9, +, /로 대치합니다.

  • ROWID를 BASE64 인코딩으로 변환하면 Segment#, Data File#, Data Block#, Row#가 각각 6, 3, 6, 3byte 로 되고, 'SSSSSSFFFBBBBBBRRR'의 형태를 갖습니다. (예: Segment# = 100, Data File# = 20, Data Block# = 250, Row# = 0인 ROWID는 'AAAABkAAUAAAAD6AAA')


ROWNUM

ROWNUM은 SELECT 문장의 실행 결과로 나타나는 로우에 대하여 순서대로 번호를 부여합니다. 질의 결과로 반환되는 첫 번째 로우는 ROWNUM = 1이며 두 번째 로우는 ROWNUM = 2, 세 번째 로우는 ROWNUM= 3, …, 등의 값을 갖습니다.

ROWNUM 할당 순서

  1. 질의를 수행합니다.

  2. 질의 결과로 로우가 생성됩니다.

  3. 로우를 반환하기 직전에 그 로우에 ROWNUM이 할당됩니다. Tibero는 내부적으로 ROWNUM 카운터를 가지고 있으며, 카운터 값을 질의 결과의 로우에 할당합니다.

  4. ROWNUM을 할당 받은 로우에 ROWNUM에 대한 조건식을 적용합니다. - 조건식을 만족하면 할당된 ROWNUM이 확정되고, 내부의 ROWNUM 카운터의 값이 1로 증가합니다. - 조건식을 만족하지 않으면 그 로우는 버려지고, 내부의 ROWNUM 카운터의 값은 증가하지 않습니다.

ROWNUM은 질의 결과의 로우 개수를 한정하기 위해 많이 사용됩니다. 아래의 SQL 문장은 10개의 로우 만을 반환하는 예시입니다.

SELECT * FROM EMP WHERE ROWNUM <= 10;

ROWNUM은 질의를 처리하는 거의 마지막 단계에서 할당됩니다. 그러므로 같은 SELECT 문장이라 하더라도 내부적으로 어떤 단계로 질의를 처리하였는가에 따라 다른 결과를 가져올 수 있습니다. 예를 들어 질의 최적화 기가 인덱스의 사용 유무를 어떻게 결정하느냐에 따라 다른 결과를 얻습니다.

ROWNUM을 포함하는 질의가 항상 같은 결과를 반환하도록 하기 위하여 ORDER BY 절을 사용할 수 있습니다. 하지만, Tibero에서는 WHRER 절을 포함하는 모든 부질의를 처리한 다음 ORDER BY 절을 처리합니다. 따라서 ORDER BY 절을 이용해서 항상 같은 결과를 얻을 수는 없습니다.

아래는 질의를 실행할 때마다 다른 결과를 얻는 질의예시입니다.

SELECT * FROM EMP WHERE ROWNUM <= 10 ORDER BY EMPNO;

위의 질의를 아래와 같이 변환하면 ORDER BY 절을 먼저 처리하게 되므로, 항상 같은 결과를 얻을 수 있습니다.

SELECT * FROM (SELECT * FROM EMP ORDER BY EMPNO) 
WHERE ROWNUM <= 10;

또한, 아래와 같은 SELECT 문장은 하나의 로우도 반환하지 않습니다.

SELECT * FROM EMP WHERE ROWNUM > 1;

그 이유는 ROWNUM 값이 확정되기 전에 ROWNUM에 대한 조건식이 수행되기 때문입니다.

위의 SELECT 문의 결과는 첫 번째 로우가 ROWNUM = 1이기 때문에 조건식을 만족하지 않습니다. 조건식을 만족하지 않으면 ROWNUM 카운터의 값은 변하지 않습니다. 따라서 두 번째 결과 로우도 ROWNUM = 1이므로 반환되 않으므로, 하나의 로우도 반환되지 않습니다.


LEVEL

LEVEL은 계층 질의를 실행한 결과에 각 로우의 트리 내 계층을 출력하기 위한 컬럼 타입입니다. 최상위 로우의 LEVEL 값은 1이며, 하위 로우로 갈수록 1씩 증가힙니다.

계층 질의와 LEVEL 컬럼 값의 출력에 대해서 는 “계층 질의”에서 참고하세요.


CONNECT_BY_ISLEAF

CONNECT_BY_ISLEAF 의사 컬럼은 현재 로우가 CONNECT BY 조건에 의해 정의된 트리(Tree)의 리프 (Leaf)이면 1을 반환하고 그렇지 않을 경우에는 0을 반환합니다. 이 정보는 해당 로우가 계층 구조(Hierarchy) 를 보여주기 위해 확장될 수 있는지 없는지를 나타냅니다.

아래는 CONNECT_BY_ISLEAF 의사 컬럼을 사용한 예시입니다.

SQL> SELECT ENAME, CONNECT_BY_ISLEAF, LEVEL, SYS_CONNECT_BY_PATH(ENAME,'-') "PATH"
     FROM EMP2
       START WITH ENAME = 'Clark' 
       CONNECT BY PRIOR EMPNO = MGRNO 
       ORDER BY ENAME;

ENAME           CONNECT_BY_ISLEAF LEVEL     PATH
--------------- ----------------- ---------- -----------------------
Alicia                           1         3 -Clark-Martin-Alicia
Allen                            1         3 -Clark-Ramesh-Allen
Clark                            0         1 -Clark
James                            1         3 -Clark-Martin-James
John                             0         3 -Clark-Ramesh-John
Martin                           0         2 -Clark-Martin
Ramesh                           0         2 -Clark-Ramesh
Ward                             1         4 -Clark-Ramesh-John-Ward


CONNECT_BY_ISCYCLE

CONNECT_BY_ISCYCLE은 계층형 질의에서 사용되는 의사 컬럼으로서 해당 로우가 자식 노드를 갖고 있음과 동시에 그 자식 노드가 해당 로우의 부모 노드가 되는지를 판별합니다. 즉, 부모 노드와 자식 노드의 루프 여부를 판별하여 이러한 자식 노드가 있을 경우 1, 없을 경우 0을 반환합니다.

이 의사컬럼은 CONNECT BY 절에 반드시 NOCYCLE 구문이 명시되어야만 사용할 수 있습니다. 만약 NOCYCLE 을 명시할 경우 루프가 발생하더라도 오류를 발생시키지 않습니다.

아래는CONNECT_BY_ISCYCLE 의사 컬럼을 사용한 예시입니다.

SQL> SELECT ENAME, CONNECT_BY_ISCYCLE, LEVEL FROM EMP
     START WITH ENAME = 'Alice'
     CONNECT BY NOCYCLE PRIOR EMPNO = MGRNO 
     ORDER BY ENAME;


ENAME           CONNECT_BY_ISCYCLE  LEVEL    
--------------- ------------------- ----- 
Alice                            0      1
Smith                            1      2
Micheal                          0      3 
Viki                             0      2
Jane                             1      2
Jacob                            0      4     

Last updated