CREATE TABLE
CREATE TABLE#
구문#
create_table ::=#
table_constraint ::=, temporary_attributes_clause ::=, table_partitioning_clause ::=, access_mode_clause ::=, physical_attributes_clause ::=, log_compression_clause ::= logging_clause ::=, parallel_clause ::=, table_compression_clause ::=, lob_column_properties ::=
column_definition ::=#
encrypt_clause ::=, variable_clause ::=, in_row_clause ::=, default_clause ::=, column_constraint ::=
encrypt_clause ::=#
variable_clause ::=#
in_row_clause ::=#
default_clause ::=#
column_constraint ::=#
unique_clause ::=, references_clause ::=, check_clause ::=
unique_clause ::=#
sort_order_clause ::=, directkey_clause ::=, using_index_clause ::=
unique_specification ::=#
sort_order_clause ::=#
directkey_clause ::=#
using_index_clause ::=#
index_partitioning_clause ::=, index_attribute_clause ::=
index_attribute_clause ::=#
memory_index_attributes ::=, disk_index_attributes ::=
references_clause ::=#
check_clause ::=#
table_constraint ::=#
table_unique_clause ::=, referential_constraint ::=, check_clause ::=
table_unique_clause ::=#
sort_order_clause ::=, directkey_clause ::=, using_index_clause ::=
referential_constraint ::=#
temporary_attributes_clause ::=#
table_partitioning_clause ::=#
range_partitioning ::=, hash_partitioning ::=, list_partitioning ::=, range_partitioning_using_hash ::=, row_movement_clause ::=
range_partitioning ::=#
partition_default_clause ::=, partition_range_caluse ::=
partition_default_clause ::=#
table_partition_description ::=
table_partition_description ::=#
lob_column_properties ::=, access_mode_clause ::=
partition_range_clause ::=#
table_partition_description ::=
hash_partitioning ::=#
table_partition_description ::=
list_partitioning ::=#
partition_default_clause ::=, partition_list_clause ::=
partition_list_clause ::=#
table_partition_description ::=
range_partitioning_using_hash ::=#
partition_default_clause ::=, partition_range_clause ::=
row_movement_clause ::=#
access_mode_clause ::=#
tablespace_clause ::=#
physical_attributes_clause ::=#
storage_clause ::=#
log_compression_clause ::=#
logging_clause ::=#
parallel_clause ::=#
table_compression_clause ::=#
lob_column_properties ::=#
LOB_storage_clause ::=#
lob_attributes ::=#
전제 조건#
아래의 조건 중 하나 이상을 만족해야 한다.l
- SYS 사용자이다.
- 사용자 자신의 스키마에 테이블을 생성하려면 CREATE TABLE 또는 CREATE ANY TABLE 시스템 권한을 가지고 있어야 한다.
- 다른 사용자의 스키마에 테이블을 생성하려면 CREATE ANY TABLE 시스템 권한을 가지고 있어야 한다.
설명#
명시된 이름의 새로운 테이블을 생성한다.
[GLOBAL] TEMPORARY#
[GLOBAL] TEMPORARY는 테이블이 임시 테이블임을 지정한다. GLOBAL 지정 여부에 따른 차이점은 없으므로 생략해도 된다. 이렇게 생성된 테이블의 정의는 모든 세션에서 볼 수 있지만, 임시 테이블의 데이터는 해당 테이블에 데이터를 삽입하는 세션에서만 볼 수 있다.
사용자가 처음으로 임시 테이블을 만들면, 테이블의 메타 데이터만 데이터 딕셔너리에 저장되고, 테이블의 데이터를 위한 공간은 할당되지 않는다. 해당 테이블에 처음으로 DML 작업이 수행되는 순간에 테이블 세그먼트를 위한 공간이 할당된다. 임시 테이블의 정의는 일반적인 테이블의 정의와 마찬가지로 데이터베이스에서 지속되지만, 임시 테이블의 테이블 세그먼트와 임시 테이블에 저장된 모든 데이터는 세션 또는 트랜잭션에 한정된다. ON COMMIT 키워드를 사용해서 테이블 세그먼트와 데이터가 세션 레벨인지 또는 트랜잭션 레벨인지를 지정할 수 있다. 자세한 설명은 아래의 temporary_attributes_clause를 참고하라.
세션에 한정되는 임시 테이블은 세션이 임시 테이블에 바인딩 되지 않은 경우에만 해당 임시 테이블에 대해 DDL 작업(ALTER TABLE, DROP TABLE, CREATE INDEX 등)이 허용된다.
트랜잭션에 한정되는 임시 테이블은 바인딩 여부에 상관 없이 임시 테이블에 대한 DDL 작업이 허용된다. 하지만, Altibase 내부적으로 DDL 작업 수행 전에 커밋을 먼저 하기 때문에, 임시 테이블에 대한 DDL 수행 후에 그 테이블의 데이터는 사라진다.
임시 테이블의 제약 사항:#
- 임시 테이블은 파티셔닝이 불가능하다.
- 임시 테이블에는 외래 키를 지정할 수 없다.
- lob_storage_clause의 TABLESPACE에는 임시 테이블을 저장하는 휘발성 테이블스페이스만 올 수 있다.
- 임시 테이블은 휘발성 테이블스페이스만 저장할 수 있다.
- 임시 테이블에 대해서는 분산 트랜잭션이 지원되지 않는다.
user_name#
생성될 테이블 소유자 이름을 명시한다. 생략하면 Altibase는 현재 세션에 연결된 사용자의 스키마에 테이블을 생성한다.
tbl_name#
생성될 테이블 이름을 명시한다. 테이블 이름은 "객체 이름 규칙"을 따라야 한다.
column_definition#
DEFAULT#
칼럼에 DEFAULT 절을 명시하지 않고 테이블을 생성한 경우, 데이터 삽입시 해당 칼럼의 값을 명시하지 않으면 NULL이 입력된다.
TIMESTAMP#
TIMESTAMP 칼럼은 여러 면에서 다른 데이터 타입들처럼 다뤄진다. 예를 들어, CREATE TABLE 문에 칼럼의 데이터 타입으로 TIMESTAMP를 명시한 경우 내부적으로 데이터 크기가 8Byte인 TIMESTAMP 칼럼이 생성된다. 그러나 TIMESTAMP 칼럼의 값은 시스템에 의해 결정되기 때문에 명시적으로 DEFAULT 값을 설정할 수 없다. 또한 TIMESTAMP 칼럼은 한 테이블에 하나만 생성할 수 있다.
column_constraint#
새로운 테이블을 생성할 때 칼럼에 대한 제약조건을 설정한다. 명시적으로 제약조건의 이름을 지정할 수 있다. LOCALUNIQUE 제약조건은 파티션드 테이블에 사용될 수 있다.
PRIMARY KEY#
기본키의 값은 테이블 내에서 유일해야 하며 기본키에 속하는 칼럼은 널(NULL) 값을 가질 수 없다. 한 테이블 내에 정의 가능한 기본키의 개수는 하나이며, 최대 32개 칼럼들의 조합에 대해 기본 키를 생성할 수 있다.
UNIQUE#
UNIQUE 제약조건을 정의하면 유니크 키에 해당하는 칼럼 (또는 칼럼의 조합)은 같은 값을 2개 이상 가질 수 없다. 단, 널 값은 허용된다.
같은 칼럼 또는 같은 칼럼의 조합에 대해 유니크 제약조건과 기본키를 동시에 정의할 수 없다. 또한, 같은 칼럼 또는 같은 칼럼의 조합에 대해 2개 이상의 유니크 제약조건도 존재할 수 없다. 그러나 다른 칼럼 또는 다른 칼럼들의 조합에는 존재할 수 있다. 최대 32개 칼럼의 조합에 대해 유니크 제약조건을 생성할 수 있다.
LOCALUNIQUE#
각 지역 인덱스별로 UNIQUE 제약조건을 만족해야 함을 명시하는 키워드이다.
(NOT) NULL#
해당 칼럼이 널 값을 가질 수 있다(없다)는 것을 의미한다.
CHECK#
해당 칼럼에 대한 무결성 규칙(Integrity Rule)을 지정한다. column_constraint 절의 condition 내에서는 해당 칼럼만 참조할 수 있다. CHECK 제약조건의 검사조건에는 아래와 같은 몇 가지 제한 사항이 있다.
- 부질의(subquery), 시퀀스, LEVEL 또는 ROWNUM 등의 모든 의사칼럼(Pseudo Column), 및 SYSDATE 또는 USER_ID 같은 비결정적(Non-deterministic) SQL 함수가 포함될 수 없다.
- PRIOR 연산자를 사용할 수 없다.
-
LOB 타입의 데이터를 사용할 수 없다.
-
참조 무결성(referential integrity)
-
TIMESTAMP
directkey_clause#
이 절은 Direct Key 인덱스를 생성시 사용할 수 있다. Direct Key 인덱스에 대한 자세한 내용은 CREATE INDEX 구문을 참고한다
check_clause#
이 절에는 테이블의 각 레코드 값이 만족해야 하는 조건을 지정한다. 조건의 결과는 참, 거짓, 또는 NULL 중 하나이어야 한다.
이 절은 칼럼 제약조건 또는 테이블 전체 제약조건이 될 수 있다.
table_constraint#
한 칼럼 또는 칼럼들의 조합에 대한 제약조건을 명시하는 절이다. 다음의 테이블 제약조건이 있다.
- PRIMARY KEY
- UNIQUE
- LOCALUNIQUE
- CHECK
- 참조 무결성(referential integrity)
using_index_clause#
제약조건을 위해 자동으로 생성되는 인덱스가 저장될 테이블스페이스를 지정하는 절이다.
PRIMARY KEY, UNIQUE 또는 LOCALUNIQUE 제약을 명시할 경우, 자동으로 생성되는 로컬 인덱스가 저장될 테이블스페이스를 각 인덱스 파티션 별로 지정할 수 있다. 자세한 설명은 CREATE INDEX 구문의 index_partitioning_clause를 참조한다.
references_clause#
외래키를 정의하는 절이다. 외래키에 의해 참조되는 다른 테이블의 참조키(referenced key)는 그 테이블에서 유니크 제약조건에 해당하거나 그 테이블의 기본키이어야 한다. 만약 이 절에 참조키의 칼럼들을 명시하지 않은 경우, 해당 테이블의 기본키가 자동으로 참조키가 된다.
NO ACTION#
"부모(parent) 테이블" (참조키가 있는 테이블)에 대해 INSERT, DELETE, 또는 UPDATE 구문을 실행하면, Altibase는 "자식(child) 테이블" (참조키를 참조하는 외래키를 가진 테이블)에 대한 무결성 검사를 한 후에 이 구문을 수행한다. NO ACTION은 무결성 검사 후에 자식 테이블에 대해서는 어떠한 작업도 하지 않음을 명시하는 옵션이다.
예를 들어 다음과 같이 employees 테이블을 생성하면, departments 테이블에서 어떤 부서를 삭제하려 할 때, employees 테이블의 레코드가 이 부서 번호를 참조하고 있다면, 삭제 시도는 실패하고 에러가 발생할 것이다.
CREATE TABLE employees (
ENO INTEGER PRIMARY KEY,
DNO INTEGER,
NAME CHAR(10),
FOREIGN KEY(DNO) REFERENCES
departments(DNO) ON DELETE NO ACTION );
ON DELETE CASCADE#
이는 부모 테이블의 행이 삭제되면 외래 키 값을 가진 자식 테이블에서 이 행을 참조하는 모든 행도 삭제될 것을 명시하는 옵션이다.
예를 들어 예를 들어 다음과 같이 employees 테이블을 생성하면, departments 테이블에서 어떤 부서를 삭제하려 할 때, employees 테이블에서 이 부서 번호를 참조하는 모든 행도 삭제된다.
CREATE TABLE employees (
ENO INTEGER PRIMARY KEY,
DNO INTEGER,
NAME CHAR(10),
FOREIGN KEY(DNO) REFERENCES
departments (DNO) ON DELETE CASCADE );
ON DELETE SET NULL#
부모 테이블의 행이 삭제되면 그 행을 참조하는 자식 테이블의 외래 키 칼럼의 값이 모두 NULL로 변경될 것을 명시하는 옵션이다. 이 옵션의 참조 무결성을 위해 해당 칼럼은 NULL이 허용되어야 한다.
예를 들어 departments 테이블을 참조하는 employees 테이블을 생성한 후에, departments 테이블에서 어떤 부서를 삭제한다. 이 때, employees 테이블에서 삭제된 부서 번호를 참조하는 모든 칼럼의 값은 NULL로 변경된다.
CREATE TABLE employees (
ENO INTEGER PRIMARY KEY,
DNO SMALLINT,
NAME CHAR(10),
CONSTRAINT dno_fk FOREIGN KEY (dno) REFERENCES
departments (dno) ON DELETE SET NULL );
MAXROWS#
테이블에 입력될 수 있는 최대 레코드 개수를 지정한다. 레코드 삽입시 전체 레코드 개수가 여기에서 지정한 수보다 많아질 경우 입력 시도는 실패하고 에러가 반환된다. MAXROWS 절은 table_partitioning_clause 절과 함께 명시할 수 없다.
temporary_attributes_clause#
이 절은 임시 테이블의 데이터가 트랜잭션에 한정되는지 또는 세션에 한정되는지를 지정하며, 아래 두 가지 옵션이 가능하다:
ON COMMIT DELETE ROWS#
트랜잭션에 한정되는 임시 테이블을 생성한다. 임시 테이블에 처음으로 데이터를 삽입하는 트랜잭션이 그 임시 테이블에 바인딩 된다. 트랜잭션 레벨의 바인딩은 COMMIT 또는 ROLLBACK 구문 수행으로 풀리게 된다. 트랜잭션이 커밋되면, Altibase는 해당 임시 테이블을 truncate 한다.
ON COMMIT PRESERVE ROWS#
세션에 한정되는 임시 테이블을 생성한다. 세션에서 임시 테이블에 처음으로 데이터가 삽입될 때 세션은 임시 테이블에 바인딩 된다. 이 바인딩은 세션이 종료 되거나 그 세션에서 테이블에 TRUNCATE 작업이 수행 될 때 풀린다. 사용자가 세션을 종료하면, Altibase는 세션에 바인딩 된 임시 테이블을 truncate 한다.
table_partitioning_clause#
파티션드 테이블을 생성하는 절이다. 범위 파티셔닝(range partitioning), 해시 파티셔닝(hash partitioning), 리스트 파티셔닝(list partitioning), 해시를 사용한 범위 파티셔닝(range using hash partitioning) 방법으로 파티션드 테이블을 생성한다. 파티션드 테이블을 생성할 때 row_movement_clause도 명시할 수 있다.
range_partitioning#
범위 파티션드 테이블 생성시 파티션 키 값의 범위를 명시하는 절이다. 주로 DATE 자료형에 많이 사용된다. 사용자가 지정한 값을 기준으로 테이블이 분할되기 때문에, 파티션별로 데이터의 고른 분포는 보장되지 않는다. 각 파티션의 범위는 그 범위의 최대값을 설정함으로써 결정된다.
명시된 범위 외의 모든 값과 NULL은 기본 파티션(default partition)에 속하게 된다. 여러 칼럼들의 조합으로 파티션 키를 정의할 수 있다.
범위 파티션드 테이블 생성시 기본 파티션 절은 생략할 수 있다. 기본 파티션 절이 생략된 경우에만 ALTER TABLE ADD PARTITION 구문을 사용할 수 있다.
범위 파티션드 테이블 생성 시 주의 사항#
- 기본 파티션이 없는 범위 파티션드 테이블을 생성할 수 있다.
- 범위 파티션드 객체에서 파티션 추가는 기본 파티션이 없는 범위 파티션드 테이블에서만 사용할 수 있다.
- 기본 파티션이 없는 범위 파티션드 테이블은 기본 파티션 추가 연산을 수행할 수 없다.
- 기본 파티션이 있는 범위 파티션드 테이블은 기본 파티션 삭제 연산을 수행할 수 없다.
- 기본 파티션이 없는 범위 파티션드 테이블은 CONJOIN/DISJOIN 구문을 사용할 수 없다.
- 범위 파티션드 테이블이 이중화 대상 테이블인 경우 파티션 추가 연산을 수행할 수 없다.
기본 파티션이 없는 범위 파티션드 테이블을 생성하면 SYS_TABLE_PARTITIONS_에서 PARTITION_NAME 이 없는 파티션이 추가로 생성된다.
iSQL> CREATE TABLE t1
(
i1 INT,
i2 INT
)
PARTITION BY RANGE ( i1 )
(
PARTITION p1 VALUES LESS THAN (10),
PARTITION p2 VALUES LESS THAN (20)
);
iSQL> SELECT PARTITION_NAME as p_name
, PARTITION_MIN_VALUE as min
, PARTITION_MAX_VALUE as max
FROM SYSTEM_.SYS_TABLES_ T
, SYSTEM_.SYS_TABLE_PARTITIONS_ p
WHERE T.USER_ID = 2
AND T.TABLE_NAME = 'T1'
AND T.TABLE_ID = P.TABLE_ID;
P_NAME MIN MAX
----------------------------------------
P1 10
P2 10 20
20
3 rows selected.
table_partition_description#
파티션별로 테이블스페이스를 지정할 수 있다. 또한 테이블에 한 개 이상의 LOB 칼럼이 있을 경우, 각 LOB 칼럼의 속성을 따로 명시할 수 있다. 그리고 파티션의 데이터에 대한 접근 모드를 설정할 수 있다.
테이블스페이스 절이 생략되면, 그 파티션은 해당 테이블의 기본 테이블스페이스(default tablespace)에 저장된다.
또한 LOB 칼럼이 저장될 테이블스페이스를 지정하지 않으면 LOB 데이터는 해당 파티션의 테이블스페이스에 저장된다.
다음의 예제에서 사용자의 기본 테이블스페이스는 tbs_05이다.
CREATE TABLE print_media_demo
(
product_id INTEGER,
ad_photo BLOB,
ad_print BLOB,
ad_composite BLOB
)
PARTITION BY RANGE (product_id)
(
PARTITION p1 VALUES LESS THAN (3000) TABLESPACE tbs_01
LOB (ad_photo) STORE AS (TABLESPACE tbs_02 ),
PARTITION p2 VALUES DEFAULT
LOB (ad_composite) STORE AS (TABLESPACE tbs_03)
) TABLESPACE tbs_04;
파티션 p1의 테이블스페이스는 명시적으로 지정되었으므로 tbs_01테이블스페이스에 저장된다. 그리고 해당 파티션의 ad_photo 칼럼은 tbs_02테이블스페이스에 저장된다. 기본 파티션인 p2의 테이블스페이스는 지정되지 않았으므로 print_media_demo 테이블의 기본 테이블스페이스인 tbs_04에 저장된다. 만약 이 테이블의 테이블스페이스를 지정하지 않았다면 사용자의 기본 테이블스페이스인 tbs_05에 저장될 것이다.
위의 설명을 그림으로 나타내면 다음과 같다.
partition_range_clause#
파티션에 저장될 상한값(noninclusive)을 지정한다. 이 값은 다른 파티션의 상한값과 겹치지 않아야 한다.
hash_partitioning#
이 절은 파티션 키 값에 대응하는 해시 값을 기준으로 테이블을 분할할 것을 명시한다. 이는 데이터가 파티션별로 고르게 분산되기를 원하는 경우에 적합하다. 여러 칼럼들의 조합으로 파티션 키를 정의할 수 있다.
list_partitioning#
이 절은 값의 집합을 기준으로 테이블을 분할할 것을 명시한다. 명시된 다른 파티션에 속하도록 명시되지 않은 값들은 자동으로 기본 파티션에 포함되기 때문에 기본 파티션은 생략할 수 없다.
기본 파티션에 속해 있던 값들의 집합으로 새로운 파티션을 추가하면 기본 파티션에서는 그 값이 제거될 것이다. 각 파티션이 가질 수 있는 값들은 서로 중복될 수 없기 때문이다. 리스트 파티션드 테이블을 위한 파티션 키는 단일 칼럼에만 정의될 수 있다.
partition_list_clause#
각 리스트 파티션은 적어도 1개 이상의 값을 가져야 한다. 한 리스트의 값은 다른 어떤 리스트에도 있을 수 없다.
range_partitioning_using_hash#
이 절은 파티션 키값에 대응하는 해시 값을 사용해 범위를 명시하는 절이다. 파티션 키는 단일 칼럼으로 지정하며 해시 값을 1000으로 나눈 나머지(mod) 값으로 범위를 지정한다. 1000은 고정값으로 변경할 수 없다. 데이터를 고르게 분포하는 해시 파티셔닝의 장점과 합병, 분할이 가능한 범위 파티셔닝의 장점을 결합한 파티셔닝이다.
row_movement_clause#
파티션드 테이블의 레코드가 갱신되어 파티션 키에 해당하는 칼럼의 값이 다른 파티션에 속하는 값으로 변경된 경우, 이 절은 그 레코드를 자동으로 다른 파티션으로 이동시킬지 아니면 에러를 발생시킬 것인지를 결정한다. 이 절을 생략하면 DISABLE ROW MOVEMENT옵션이 기본으로 설정된다.
CREATE TABLE … AS SELECT#
테이블 생성시, 다른 테이블에서 새로운 테이블로 칼럼의 속성과 데이터를 그대로 복사하려면 이 구문을 사용한다. 새로운 테이블의 칼럼 수는 SELECT 절로 검색되는 칼럼의 개수와 동일해야 한다. 또한 새로운 칼럼의 데이터 타입은 명시할 수 없고, 데이터가 검색되는 원래 칼럼의 데이터 타입과 동일하게 된다.
생성될 테이블의 칼럼 명을 명시하지 않을 경우에는 검색되는 칼럼의 이름이 그대로 사용된다. 검색 대상이 칼럼이 아니고 표현식인 경우 alias가 반드시 존재해야 한다. 이 alias가 새로운 테이블의 칼럼명이 될 것이다.
access_mode_clause#
데이터에 대한 접근 모드를 설정할 수 있다. 읽기 전용(Read-Only) 모드, 읽기/쓰기(READ/WRITE) 모드 또는 읽기/추가(READ/APPEND) 모드 중에서 선택할 수 있으며, 생략하면 기본으로 '읽기/쓰기' 모드로 설정된다.
주의: 테이블이나 파티션에 대한 접근 모드가 '읽기 전용' 또는 '읽기/추가'로 설정되어 있어도 이중화에 의한 복제, TRUNCATE 구문 수행, LOB 칼럼 변경은 허용된다.
tablespace_clause#
테이블이 저장될 테이블스페이스를 지정하는 절이다.
이 절을 생략할 경우 테이블은 이 테이블을 생성하려 하는 사용자의 기본 테이블스페이스에 저장될 것이다. 사용자 생성 시 DEFAULT TABLESPACE를 생략했었다면 테이블은 시스템 메모리 기본 테이블스페이스(SYSTEM MEMORY DEFAULT TABLESPACE)에 생성된다.
CREATE TABLE 문 내에 UNIQUE 또는 PRIMARY KEY 제약조건이 명시된 경우 이들을 위한 인덱스는 테이블이 저장되는 테이블스페이스에 생성될 것이다.
physical_attributes_clause#
PCTFREE, PCTUSED, INITRANS 및 MAXTRANS를 지정하는 절이다. 이 절이 파티션드 테이블에 명시될 경우 PCTFREE와 PCTUSED 값은 그 테이블의 모든 파티션에 적용될 것이다.
PCTFREE 절#
페이지에 이미 저장되어 있는 레코드가 갱신될 때 이용하기 위해 예약해 둔 여유
공간의 양을 비율로 정의한다. 레코드는 이 예약된 공간 외에만 삽입된다. 이
값은 한 페이지내의 여유 공간을 백분율로 표시한다.
예를 들어 PCTFREE가 20으로 명시된 테이블의 경우, 각 페이지 크기의 80%에만
레코드가 입력되며, 나머지 20%는 레코드의 갱신 용도로 사용된다. 이 값은
디스크 기반의 테이블에 대해서만 의미가 있다.
명시할 수 있는 값은 0에서 99까지의 정수이며, 백분율을 의미한다. 명시하지
않을 경우 기본 PCTFREE 값은 10이다. 이 옵션은 테이블에 할당된 페이지에만
적용된다.
PCTUSED 절#
한 페이지가 레코드 삽입이 가능한 상태로 다시 돌아가기 위해 페이지의 사용
공간이 줄어들어야 하는 최소 비율을 나타낸다. 여유 공간의 비율이 PCTFREE에
도달한 페이지에는 더 이상 레코드가 삽입되지 않고, 갱신 또는 삭제만 허용된다.
이후 레코드 갱신 또는 삭제 작업으로 페이지의 사용 공간의 비율이 PCTUSED에서
명시한 값 이하로 떨어지게 되면 이 페이지는 다시 레코드 삽입이 가능한 상태로
된다.
예를 들어 PCTUSED 값을 40으로 명시한 경우, 어떤 페이지의 여유 공간의 비율이
PCTFREE에 명시된 값에 도달하면, 이 페이지의 사용 공간 비율이 39% 이하로
떨어질 때까지 이 페이지에는 레코드 삽입이 불가능하다. 사용 공간의 비율이 40%
미만으로 떨어져야 비로소 새로운 레코드가 다시 그 페이지에 삽입된다. 이 값은
디스크 기반 테이블에 대해서만 의미가 있다.
명시할 수 있는 값은 0에서 99까지의 정수이며, 백분율을 의미한다. 명시하지
않을 경우 기본 PCTUSED 값은 40 이다. 이 옵션은 테이블에 할당된 페이지에만
적용된다.
INITRANS 절#
TTS(Touched Transaction Slot)의 초기 개수를 지정한다. 기본값은 2이다.
MAXTRANS 절#
TTS(Touched Transaction Slot)의 최대 개수를 지정한다. 기본값은 120이다.
참고
위의 PCTFREE와 PCTUSED는 페이지 사용의 최적화를 위해 다음과 같은 형태로 함께 사용된다. 이 예제에서는 PCTFREE는 20, PCTUSED는 40으로 지정하였다.
각 페이지의 20%는 기존 레코드에 대한 변경 연산을 위한 공간으로 예약되며, 이 페이지의 나머지 80%의 공간까지만 새로운 레코드들이 삽입된다.
이 시점이 되면 더 이상 어떠한 새로운 레코드도 이 페이지에 삽입될 수 없다. 이미 저장된 레코드에 대한 갱신과 삭제 연산만이 가능하다. 갱신 연산은 예약해둔 20%의 빈 공간을 사용한다. 레코드가 삭제되어 사용중인 공간이 40% 아래로 떨어지면 그 페이지에 다시 새로운 레코드를 삽입할 수 있다.
페이지 공간의 사용은 PCTFREE와 PCTUSED의 값을 이용하여 위와 같은 방법으로 계속 순환된다.
storage_clause#
사용자가 세그먼트에 대한 익스텐트 관리 파라미터를 지정할 수 있는 구문이다.
INITEXTENTS 절#
세그먼트 생성시 초기 할당되는 익스텐트 개수를 지정한다. 명시하지 않을 경우 기본으로 1개의 익스텐트가 할당된다.
NEXTEXTENTS 절#
세그먼트 크기 확장시마다 추가될 익스텐트 개수를 명시한다. 명시하지 않을 경우 기본으로 1개의 익스텐트만큼 확장된다.
MINEXTENTS 절#
세그먼트의 최소 익스텐트 개수를 지정한다. 명시하지 않을 경우 기본값은 1이다.
MAXEXTENTS 절#
세그먼트가 포함할 수 있는 최대 익스텐트 개수를 지정한다. 명시하지 않을 경우 제한이 없는 것으로 지정된다.
LOB_storage_clause#
디스크 테이블의 LOB 칼럼 데이터는 LOB 칼럼이 속한 테이블과 별도의 테이블스페이스에 저장될 수 있다. 그러나 메모리 테이블의 경우는 별도 저장이 불가능하다. 즉, 테이블과 동일한 테이블스페이스에만 저장될 수 있다.
parallel_clause#
병렬 질의를 처리하는 쓰레드의 개수를 명시한다. 이 절을 생략하면 NOPARALLEL을 지정한 것과 동일하다.
NOPARALLEL#
쿼리를 병렬로 처리하지 않는다.
PARALLEL integer#
integer에 명시한 개수만큼의 쓰레드가 병렬로 쿼리를 처리한다. 입력 가능한 값의 범위는 1 ~ 65535이다. PARALLEL 1은 NOPARALLEL과 동일하다.
현재 Altibase는 아래와 같은 병렬 질의만 지원한다.
- 파티션드 테이블을 스캔하는 병렬 질의.
- 일반 테이블을 스캔하는 병렬 질의. 단, 테이블 전체를 스캔(full scan)하지 않는 쿼리, 서브쿼리, 반복 실행되는 경우 병렬 수행이 불가능하다.
- 실행 계획에 HASH, SORT, GRAG 노드가 포함되는 병렬 질의. 단, 이러한 노드의 경우에는 각 노드당 병렬 작업 쓰레드가 한 개씩만 생성된다.
table_compression_clause#
압축할 칼럼의 이름을 쉼표로 구분하여 명시한다. MAXROWS 절에는 압축 칼럼당 자동으로 생성되는 딕셔너리 테이블에 입력할 수 있는 행의 최대 개수를 명시한다. 명시하지 않으면 기본값은 일반 테이블과 동일한 264-1개이다.
CREATE TABLE 구문에 이 절과 subquery를 모두 명시하여 테이블 생성과 데이터 삽입을 하나의 구문으로 수행하는 것을 지원하지 않는다.
압축이 가능한 데이터 타입과 각 타입 별 최소 크기는 다음과 같다.
데이터 타입 | 최소 크기 |
---|---|
CHAR, VARCHAR, BYTE | 6 |
NCHAR, NVARCHAR (UTF-8) | 6 |
NCHAR, NVARCHAR (UTF-16) | 3 |
NIBBLE | 13 |
BIT, VARBIT | 25 |
DATE |
주의 사항#
다음은 테이블 생성시 유념해야 할 몇 가지 사항이다.
- 정의한 칼럼 크기가 최대 허용 크기를 넘거나 최소 크기 보다 작으면 오류가 발생한다. 최대와 최소 크기는 각 데이터 타입마다 다르다.
- 한 테이블의 최대 칼럼 수는 1024개이다.
- 기본키는 한 테이블에 한 개만 존재할 수 있다.
- 참조 제약조건의 경우 외래키와 참조키의 칼럼 개수는 동일해야 한다. 또한 외래키와 참조키의 각 칼럼 데이터 타입은 동일해야 한다.
- 한 테이블에 생성할 수 있는 인덱스, 기본키 및 유니크 키의 총 개수는 1024개를 넘을 수 없다.
- CREATE TABLE AS SELECT의 경우 칼럼 명을 명시하였다면 그 개수는 검색 대상에 명시한 칼럼 개수와 동일해야 한다.
- CREATE TABLE AS SELECT문 실행시 CREATE TABLE 문에 칼럼 명을 명시하지 않고 SELECT문의 검색 대상에는 표현식을 사용한 경우, 반드시 새로운 테이블의 칼럼 이름으로 사용될 별명(alias name)을 표현식에 명시해야 한다.
- MAXROWS 절에 파티션드 테이블 사용은 지원되지 않는다.
- 범위 파티션드 테이블과 해시 파티션드 테이블을 위한 파티션 키 칼럼은 최대 32개로 구성될 수 있다.(인덱스 생성 시 인덱스 키 칼럼의 개수 제한과 동일하다.)
- NOLOGGING(FORCE/NOFORCE) 옵션으로 생성된 인덱스의 경우 시스템이나 미디어 고장시 인덱스의 일관성이 보장되지 않을 수 있다. 인덱스 일관성이 깨진 경우 'The index is inconsistent.'라는 오류 메시지가 나온다. 이러한 오류를 해결하려면 일관성이 깨진 인덱스를 찾아 삭제한 후에 해당 인덱스를 다시 생성하도록 한다. 인덱스의 일관성은 V$DISK_BTREE_HEADER성능 뷰에서 확인할 수 있다.
- CREATE INDEX 구문과 마찬가지로 로컬 파티션드 인덱스가 저장될 테이블스페이스를 지정할 수 없다.
- CREATE TABLE ... AS SELECT의 경우, CHECK 제약조건을 지정할 수 없다.
- PRIMARY KEY, UNIQUE, TIMESTAMP 제약조건을 갖는 칼럼은 압축이 불가능하다.
예제 1: 테이블 생성 기본#
다음 테이블들을 생성하라.
-
테이블 이름: employees
칼럼: 사원번호, 사원이름과 성, 직책, 전화번호, 부서번호, 월급, 성별, 생일, 입사일자, 상태iSQL> CREATE TABLE employees( eno INTEGER PRIMARY KEY, e_lastname CHAR(20) NOT NULL, e_firstname CHAR(20) NOT NULL, emp_job VARCHAR(15), emp_tel CHAR(15), dno SMALLINT, salary NUMBER(10,2) DEFAULT 0, sex CHAR(1) CHECK(sex IN ('M', 'F')), birth CHAR(6), join_date DATE, status CHAR(1) DEFAULT 'H'); Create success.
-
테이블 이름: orders
칼럼: 주문번호, 주문일자, 판매사원, 고객번호, 상품번호, 주문수량, 도착 예정일자, 주문상태iSQL> CREATE TABLE orders( ono BIGINT, order_date DATE, eno INTEGER NOT NULL, cno BIGINT NOT NULL, gno CHAR(10) NOT NULL, qty INTEGER DEFAULT 1, arrival_date DATE, processing CHAR(1) DEFAULT '0', PRIMARY KEY(ono, order_date)); Create success.
예제 2: CREATE TABLE … AS SELECT 사용#
다음 질의는 직원 테이블에서 부서 번호가 1002인 조건을 만족하는 데이터를 가진 테이블 dept_1002를 생성한다.
iSQL> CREATE TABLE dept_1002
AS SELECT * FROM employees
WHERE dno = 1002;
Create success.
예제 3: TIMESTAMP 타입을 가진 테이블 생성#
TIMESTAMP 타입 칼럼을 가지는 테이블을 생성한다.
iSQL> CREATE TABLE tbl_timestamp(
i1 TIMESTAMP CONSTRAINT const2 PRIMARY KEY,
i2 INTEGER,
i3 DATE,
i4 Byte(8));
Create success.
테이블 tbl_timestamp의 속성은 다음과 같다.
[ TABLESPACE : SYS_TBS_MEM_DATA ]
[ ATTRIBUTE ]
------------------------------------------------------------------------------
NAME TYPE IS NULL
------------------------------------------------------------------------------
I1 TIMESTAMP FIXED NOT NULL
I2 INTEGER FIXED
I3 DATE FIXED
I4 BYTE(8) FIXED
[ INDEX ]
------------------------------------------------------------------------------
NAME TYPE IS UNIQUE COLUMN
------------------------------------------------------------------------------
CONST2 BTREE UNIQUE I1 ASC
[ PRIMARY KEY ]
------------------------------------------------------------------------------
I1
명시적으로 Byte(8) 데이터 타입을 선언한 칼럼 i4와 TIMESTAMP 데이터 타입 칼럼인 i1을 구별하는 방법은 SYS_CONSTRAINTS_와 SYS_CONSTRAINT_COLUMNS_ 메타 테이블을 조회해서 칼럼 타입이 TIMESTAMP 인지를 확인하는 것이다.
참고: INSERT나 UPDATE 수행 시 사용자가 TIMESTAMP 칼럼 값을 DEFAULT로 명시한 경우, 당시의 시스템 시간값이 그 TIMESTAMP 칼럼에 쓰여진다.
iSQL> INSERT INTO tbl_timestamp VALUES(DEFAULT, 2, '02-FEB-01', Byte'A1111002');
1 row inserted.
iSQL> UPDATE tbl_timestamp SET i1 = DEFAULT, i2 = 102, i3 = '02-FEB-02', i4 = Byte'B1111002' WHERE i2 = 2;
1 row updated.
iSQL> SELECT * FROM tbl_timestamp;
I1 I2 I3 I4
------------------------------------------------------------------
4E3778C900037AE9 102 02-FEB-2002 B111100200000000
1 row selected.
마찬가지로 INSERT나 UPDATE 수행 시 사용자가 TIMESTAMP 칼럼 값을 명시하지 않은 경우, 당시의 시스템 시간 값이 INSERT 또는 UPDATE 수행에 사용된다.
iSQL> INSERT INTO tbl_timestamp(i2, i3, i4) VALUES(4, '02-APR-01', Byte'C1111002');
1 row inserted.
iSQL> UPDATE tbl_timestamp SET i2=104, i3='02-APR-02', i4=BYTE'D1111002' WHERE i2=4;
1 row updated.
iSQL> SELECT * FROM tbl_timestamp;
I1 I2 I3 I4
------------------------------------------------------------------
4E3778C900037AE9 102 02-FEB-2002 B111100200000000
4E37794900083702 104 02-APR-2002 D111100200000000
2 rows selected.
예제 4: 임시 테이블 생성 및 사용#
<질의> 한 세션에서 임시 테이블을 생성하고 데이터를 삽입한 후, 해당 세션에서는 데이터가 조회되고, 다른 세션에서는 조회되는 데이터가 없는 것을 보여준다.
iSQL> create volatile tablespace my_vol_tbs size 12M autoextend on maxsize 1G;
Create success.
iSQL> create temporary table t1(i1 integer, i2 varchar(10)) on commit delete rows tablespace my_vol_tbs;
Create success.
iSQL> create temporary table t2(i1 integer, i2 varchar(10)) on commit preserve rows tablespace my_vol_tbs;
Create success.
iSQL> desc t2;
[ TABLESPACE : MY_VOL_TBS ]
[ ATTRIBUTE ]
------------------------------------------------------------------------------
NAME TYPE IS NULL
------------------------------------------------------------------------------
I1 INTEGER FIXED
I2 VARCHAR(10) FIXED
T2 has no index
T2 has no primary key
iSQL> alter table t2 add constraint t2_pk primary key (i1);
Alter success.
iSQL> insert into t2 values (1, 'abc');
1 row inserted.
iSQL> insert into t2 values (2, 'def');
1 row inserted.
iSQL> select * from t2;
I1 I2
---------------------------
1 abc
2 def
2 rows selected.
iSQL> connect sys/manager;
Connect success.
iSQL> select * from t2;
I1 I2
---------------------------
No rows selected.
예제 5: 테이블스페이스 지정#
질의에서 지정한 테이블스페이스에 테이블을 생성하라.
<질의> 테이블 소유자가 uare1인 테이블 tbl1을 생성하라. (사용자 생성 시 기본 테이블스페이스가 지정되지 않았다.)
iSQL> CONNECT uare1/rose1;
Connect success.
iSQL> CREATE TABLE tbl1(
i1 INTEGER,
i2 VARCHAR(3));
Create success.
참고: 사용자 생성 시 기본 테이블스페이스가 지정되지 않은 경우 시스템 메모리 기본 테이블스페이스에 테이블이 생성 된다.
<질의> 사용자 생성 시 지정된 기본 테이블스페이스 user_data에 다음 조건을 만족하는 테이블 books과 inventory를 생성하라.
books 칼럼: 책번호, 책이름, 저자, 판, 출판연도, 가격, 출판사코드 (테이블 books에 입력할 수 있는 최대 레코드 개수는 2개이다.)
inventory 칼럼: 예약구독번호, 책번호, 상점코드, 구입날짜, 구입량, 지불여부
iSQL> CREATE TABLE books(
isbn CHAR(10) CONSTRAINT const1 PRIMARY KEY,
title VARCHAR(50),
author VARCHAR(30),
edition INTEGER DEFAULT 1,
publishingyear INTEGER,
price NUMBER(10,2),
pubcode CHAR(4)) MAXROWS 2
TABLESPACE user_data;
Create success.
iSQL> CREATE TABLE inventory(
subscriptionid CHAR(10) PRIMARY KEY,
isbn CHAR(10) CONSTRAINT fk_isbn REFERENCES books (isbn),
storecode CHAR(4),
purchasedate DATE,
quantity INTEGER,
paid CHAR(1))
TABLESPACE user_data;
Create success.
또는
iSQL> CREATE TABLE inventory(
subscriptionid CHAR(10),
isbn CHAR(10),
storecode CHAR(4),
purchasedate DATE,
quantity INTEGER,
paid CHAR(1),
PRIMARY KEY(subscriptionid),
CONSTRAINT fk_isbn FOREIGN KEY(isbn) REFERENCES books(isbn))
TABLESPACE user_data;
Create success.
예제 6: Direct Key 인덱스 사용#
<질의> 테이블 tab1을 생성할 때 id(INTEGER) 칼럼을 UNIQUE 하면서, Direct Key 인덱스로 설정한다.
iSQL> CREATE TABLE tab1 (id INTEGER UNIQUE DIRECTKEY );
Create success.
예제 7: 인덱스 파티션에 테이블스페이스 지정#
<질의> I1 칼럼에 대한 UNIQUE 제약을 갖는 파티션드 테이블 T1을 생성하라.
CREATE TABLE T1
(
I1 INTEGER UNIQUE USING INDEX LOCAL
(
PARTITION P1_UNIQUE ON P1 TABLESPACE TBS3,
PARTITION P2_UNIQUE ON P2 TABLESPACE TBS2,
PARTITION P3_UNIQUE ON P3 TABLESPACE TBS1
)
)
PARTITION BY RANGE (I1)
(
PARTITION P1 VALUES LESS THAN (100),
PARTITION P2 VALUES LESS THAN (200) TABLESPACE MEM_TBS1,
PARTITION P3 VALUES DEFAULT TABLESPACE MEM_TBS2
) TABLESPACE SYS_TBS_DISK_DATA;
예제 8: 범위 파티션드 테이블 생성#
<질의 1> 아래 그림과 같이 2006년의 각 분기별로 파티셔닝하여 range_sales 테이블을 생성한다.
CREATE TABLE range_sales
(
prod_id NUMBER(6),
cust_id NUMBER,
time_id DATE
)
PARTITION BY RANGE (time_id)
(
PARTITION Q1_2006 VALUES LESS THAN (TO_DATE('01-APR-2006')),
PARTITION Q2_2006 VALUES LESS THAN (TO_DATE('01-JUL-2006')),
PARTITION Q3_2006 VALUES LESS THAN (TO_DATE('01-OCT-2006')),
PARTITION Q4_2006 VALUES LESS THAN (TO_DATE('01-JAN-2007')),
PARTITION DEF VALUES DEFAULT
) TABLESPACE SYS_TBS_DISK_DATA;
<질의 2> 파티션의 테이블스페이스를 지정하여 파티션드 테이블 생성
CREATE TABLE T1
(
I1 INTEGER,
I2 INTEGER
)
PARTITION BY RANGE (I1)
(
PARTITION P1 VALUES LESS THAN (100),
PARTITION P2 VALUES LESS THAN (200) TABLESPACE TBS1,
PARTITION P3 VALUES DEFAULT TABLESPACE TBS2
) TABLESPACE SYS_TBS_DISK_DATA;
<질의 3> 다중 칼럼을 파티션 키로 갖는 파티션드 테이블 생성
CREATE TABLE T1
(
I1 DATE,
I2 INTEGER
)
PARTITION BY RANGE (I1, I2)
(
PARTITION P1 VALUES LESS THAN (TO_DATE('01-JUL-2006'), 100),
PARTITION P2 VALUES LESS THAN (TO_DATE('01-JAN-2007'), 200),
PARTITION P3 VALUES DEFAULT
) TABLESPACE SYS_TBS_DISK_DATA;
<질의 4> 필요시 데이터가 자동으로 다른 파티션으로 옮겨지는 파티션드 테이블 생성
CREATE TABLE T1
(
I1 INTEGER,
I2 INTEGER
)
PARTITION BY LIST (I1)
(
PARTITION P1 VALUES (100, 200),
PARTITION P2 VALUES (150, 250),
PARTITION P3 VALUES DEFAULT
) ENABLE ROW MOVEMENT TABLESPACE SYS_TBS_DISK_DATA;
예제 9: 리스트 파티션드 테이블 생성#
<질의> nls_territory 칼럼의 값이 'CHINA' 또는 'THAILAND'인 asia 파티션, 'GERMANY', 'ITALY', 'SWITZERLAND'인 europe 파티션, 'AMERICA'인 west 파티션, 'INDIA'인 east 파티션, 그 외 나머지 값은 기본 파티션으로 분할되는 list_customers 테이블을 생성한다.
CREATE TABLE list_customers
(
customer_id NUMBER(6),
cust_first_name VARCHAR(20),
cust_last_name VARCHAR(20),
nls_territory VARCHAR(30),
cust_email VARCHAR(30)
)
PARTITION BY LIST (nls_territory)
(
PARTITION asia VALUES ('CHINA', 'THAILAND'),
PARTITION europe VALUES ('GERMANY', 'ITALY', 'SWITZERLAND'),
PARTITION west VALUES ('AMERICA'),
PARTITION east VALUES ('INDIA'),
PARTITION rest VALUES DEFAULT
) TABLESPACE SYS_TBS_DISK_DATA;
예제 10: 해시 파티션드 테이블 생성#
<질의> product_id에 따라서 4개의 해시 파티션으로 분할되는 테이블을 생성한다.
CREATE TABLE hash_products
(
product_id NUMBER(6),
product_name VARCHAR(50),
product_description VARCHAR(2000)
)
PARTITION BY HASH (product_id)
(
PARTITION p1,
PARTITION p2,
PARTITION p3,
PARTITION p4
) TABLESPACE SYS_TBS_DISK_DATA;
예제 11: 해시를 사용한 범위 파티셔드 테이블 생성#
<질의> product_id에 따라서 4개의 해시 값을 사용하여 범위 파티션으로 분할되는 테이블을 생성한다.
CREATE TABLE range_using_hash_products
(
product_id NUMBER(6),
product_name VARCHAR(50),
product_description VARCHAR(2000)
)
PARTITION BY RANGE_USING_HASH (product_id)
(
PARTITION p1 VALUES LESS THAN (250),
PARTITION p2 VALUES LESS THAN (500),
PARTITION p3 VALUES LESS THAN (750),
PARTITION p4 VALUES DEFAULT
) TABLESPACE SYS_TBS_DISK_DATA;
예제 12: LOB 데이터를 위한 테이블스페이스 지정#
<질의> LOB 데이터를 별도의 테이블스페이스에 저장하되, image1칼럼은 테이블스페이스 lob_data1에, image2 칼럼은 테이블스페이스 lob_data2에 저장하는 테이블을 생성한다.
CREATE TABLE lob_products
(
product_id integer,
image1 BLOB,
image2 BLOB
) TABLESPACE SYS_TBS_DISK_DATA
LOB(image1) STORE AS ( TABLESPACE lob_data1 )
LOB(image2) STORE AS ( TABLESPACE lob_data2 );
예제 13: 익스텐트 관리 파라미터를 지정한 테이블 생성#
<질의> 디스크 테이블스페이스인 usertbs에 local_tbl 테이블을 생성한다. 단 테이블 생성시 익스텐트 10개를 할당하고 세그먼트 확장시마다 1개씩 확장하도록 한다.
iSQL> CREATE TABLE local_tbl (i1 INTEGER, i2 VARCHAR(32) )
TABLESPACE usertbs
STORAGE ( INITEXTENTS 10 NEXTEXTENTS 1 );
Create success.
<질의> 디스크 테이블스페이스인 usertbs에 local_tbl 테이블을 생성한다. 단, 테이블 생성시 최소 익스텐트 개수는 3으로 하고 최대 익스텐트 개수는 100으로 제한한다.
iSQL> CREATE TABLE local_tbl ( i1 INTEGER, i2 VARCHAR(32) )
TABLESPACE usertbs
STORAGE ( INITEXTENTS 3 MINEXTENTS 3 MAXEXTENTS 100 );
Create success.