-- true면 마지막줄에 SQL종료 문자 ';' 를 출력함
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SQLTERMINATOR', true);
-- 줄 바뀜을 지원함
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'PRETTY', true);
-- 테이블 스페이스를 표시
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'TABLESPACE', true);
-- STORAGE정보를 표시
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'STORAGE', true);
-- SEGMENTS 정보를 표시
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SEGMENT_ATTRIBUTES', true);
-- I
-- 유저 기본 생성 ddl
SELECT DBMS_METADATA.GET_DDL('USER',username) as metadata FROM DBA_USERS;
SELECT DBMS_METADATA.GET_DDL('ROLE', role) as metadata FROM dba_roles;
SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', role) as metadata FROM role_role_privs;
SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', role) as metadata FROM ROLE_SYS_PRIVS;
SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', role) as metadata FROM ROLE_TAB_PRIVS;
SELECT DBMS_METADATA.GET_DDL('INDEX',index_name,owner) from dba_indexes where rownum < 2;
SELECT DBMS_METADATA.GET_DDL('TABLE',table_name,owner) from dba_tables where rownum < 2;
select dbms_metadata.get_ddl('CONSTRAINT',constraint_name,owner)
from dba_constraints
-- table grant ddl
select SYS.dbms_metadata.get_dependent_ddl('OBJECT_GRANT',table_name,owner)
from dual;
---
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', FALSE );
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS', FALSE );
SEGMENT(세그먼트)란 무엇인가
오라클의 세그먼트(segment)는 디스크 저장공간을 사용하는 객체다.
다양한 세그먼트 유형이 있지만 가장 일반적인 유형은 다음과 같다.
* 클러스터(Cluster): 클러스터 세그먼트는 테이블을 저장하는 세그먼트며, B*Tree 방식과 해시 방식이 존재한다.
클러스터는 다수 개 테이블의 데이터를 미리 조인하여 같은 데이터 블록에 함께 저장하거나 하나의 테이블에서 관련된 데이터를 함께 저장하기 위해 사용된다.
클러스터라는 용어의 의미는 관련된 정보를 물리적으로 함께 묶는 기능을 말한다.
* 테이블(Table): 테이블 세그먼트는 데이터베이스 테이블을 위한 세그먼트고, 인덱스 세그먼트와 함께 가장 일반적인 세그먼트 유형이다.
* 테이블 파티션/서브파티션(Table partition or subpartition): 이 유형은 파티셔닝에 사용되는 것으로서 테이블 세그먼트와 매우 유사하며, 테이블 파티션/서브파티션 세그먼트는 파티션된 테이블 데이터를 저장한다.
파티션 테이블은 한 개 이상의 파티션 세그먼트로 구성되고, 복합 파티션 테이블은 한 개 이상의 서브파티션 세그먼트로 구성된다.
* 인덱스(Index): 인덱스 세그먼트는 인덱스 구조를 저장한다.
* 인덱스 파티션(Index partition): 테이블 파티션 세그먼트와 유사하다.
이 세그먼트 유형은 파티션된 테이블 데이터를 저장한다.
파티션 테이블은 한 개 이상의 파티션 세그먼트로 구성되고, 복합 파티션 테이블은 한 개 이상의 서브파티션 세그먼트로 구성된다.
* LOB 파티션, LOB 서브파티션, LOB 인덱스, LOG 세그먼트(Lob partition, lob subpartition, lobindex, and lob segment): LOB 인덱스와 LOB 세그먼트는 대형 객체 또는 LOB 데이터를 저장한다.
한 테이블을 파티션으로 구성한다면 LOB 세그먼트 또한 파티션으로 구성되며, LOB 파티션 세그먼트가 사용된다.
어떤 이유 때문인지 LOB 인덱스 파티션 세그먼트 유형이 없다는 점은 흥미롭다.
오라클은 파티션된 LOB 인덱스 세그먼트를 인덱스 파티션으로 기록한다(그런데 왜 LOB 인덱스는 특별히 별도의 이름으로 부르는지 모르겠다!).
* 중첩 테이블(Nested table): 중첩 테이블을 저장하는 세그먼트 유형이다.
나중에 살펴볼 마스터/디테일 관계에서 자식 테이블의 특별한 경우에 사용된다.
* 롤백과 Type2 언두(Rollback and Type2 undo): 언두 데이터가 저장되는 세그먼트다.
롤백 세그먼트는 DBA가 수동으로 생성해야 하지만, Type2 언두 세그먼트는 오라클이 자동으로 생성하고 관리한다.
예를 들어 하나의 테이블은 하나의 세그먼트가 될 수 있고, 하나의 인덱스도 하나의 세그먼트가 될 수 있다.
'될 수 있다'를 강조하는 이유는 하나의 인덱스를 독립적인 여러 개의 세그먼트로 파티셔닝할 수 있기 때문이다.
인덱스 객체 자체는 명확하게 정의되지만, 물리적인 세그먼트는 그렇지 않다.
하나의 인덱스는 여러 개의 인덱스 파티션으로 구성될 수 있으며, 개별 인덱스 파티션은 각각 하나의 세그먼트가 될 것이다.
하나의 테이블도 하나의 세그먼트가 되거나 그렇지 않을 수 있다.
인덱스의 경우와 마찬가지로, 하나의 테이블이 파티셔닝을 통해 여러 개의 테이블 세그먼트로 구성될 수 있기 때문이다.
또한 클러스터 세그먼트에는 하나 이상의 테이블이 함께 존재하는 경우도 있다.
그러나 하나의 테이블이 하나의 세그먼트가 되고 하나의 인덱스가 하나의 세그먼트가 되는 것이 가장 일반적이다.
지금은 이렇게 생각하는 것이 가장 이해하기 쉬운 방법일 것이다.
3장 '파일'의 설명을 보면, 하나의 세그먼트는 여러 개의 익스텐트(EXTENT)로 구성되고, 개별 익스텐트(EXTENT)는 여러 개의 블록(BLOCK)으로 구성된다.
이것이 일반적인 저장 계층구조다.
그러나 이것은 일대일 관계인 일반적인 경우에 국한한다는 것을 기억해야 한다.
예를 들어 다음과 같이 간단한 CREATE TABLE 문을 생각해보자.
1 | create table t ( x int primary key , y clob, z blob ); |
이 문장을 수행하면 오라클 11g 릴리즈 1 버전까지는 6개의 세그먼트를 바로 생성하였으나, 오라클 11g 릴리즈 2 버전부터는 첫 번째 로우가 입력될 때까지 세그먼트 생성을 보류하는 것이 디폴트 설정이다(세그먼트 생성을 보류하지 않고, 즉시 수행하려면 아래 문법을 사용하면 된다).
아무런 테이블도 생성되지 않은 스키마에서 다음과 같은 결과를 확인할 수 있을 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | TEST@ORACLE11> create table t ( x int primary key , y clob, z blob ); TEST@ORACLE11> select segment_name, segment_type 2 from user_segments 3 ; no rows selected TEST@ORACLE11> create table t 2 (x int primary key , 3 y clob, 4 z blob ) 5 SEGMENT CREATION IMMEDIATE 6 / Table created. TEST@ORACLE11> select segment_name, segment_type 2 from user_segments; SEGMENT_NAME SEGMENT_TYPE ------------------------------------------------------- ------------------ T TABLE SYS_IL0000083705C00002$$ LOBINDEX SYS_IL0000083705C00003$$ LOBINDEX SYS_C0018672 INDEX SYS_LOB0000083705C00002$$ LOBSEGMENT SYS_LOB0000083705C00003$$ LOBSEGMENT 6 rows selected. |
결과의 첫 번째 로우를 보면 테이블 자체는 하나의 세그먼트로 생성하였고, 유일성을 보장하기 위한 기본 키(primary key)는 하나의 인덱스 세그먼트를 생성하였다.
- Note --------------------------------------------------------------------------
유니크 또는 기본 키 제약은 새로운 인덱스를 생성하는 경우도 있고, 생성하지 않는 경우도 있다.
유니크 또는 기본 키 제약 컬럼이 기존의 특정 인덱스에 존재하고 해당 인덱스의 선두 컬럼에 위치한다면, 새로운 인덱스를 생성하지 않고 기존 인덱스를 사용할 것이다.
---------------------------------------------------------------------------------
또한 LOB 컬럼은 세그먼트 2개를 생성했다.
하나는 CLOB(대형 문자 객체) 또는 BLOB(바이너리 대형 객체)의 데이터가 저장되는 실제 데이터 청크고, 또 하나는 그것을 구조화하는 세그먼트다.
LOB는 수기가바이트까지의 매우 큰 청크 데이터를 저장한다.
LOB는 LOB 세그먼트에 저장되고, LOB 인덱스는 LOB 데이터가 어느 트랙에 저장되는지 관리하고 데이터를 액세스하는 순서를 관리한다.
CREATE TABLE 문의 5번째 라인을 주목하자.
SEGMENT CREATION IMMEDIATE 절은 오라클 11g 릴리즈 2 이상에서 유효한 문법이다.
이전 버전에서 이 문법을 사용하면 오류가 발생한다.
ORA-00922: missing or invalid option
'oracle' 카테고리의 다른 글
DBMS_OUTPUT 패키지 (0) | 2016.10.14 |
---|---|
sysdba 로그인 제한!! (0) | 2016.10.14 |
dbms_stats.gather_table_stats에 대하여 (0) | 2016.10.07 |
CAST 함수 사용법 (0) | 2016.10.07 |
view (0) | 2016.09.30 |