> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tibero-manuals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tibero.com/tibero-manuals/7.2.6.manuals/sql-reference-guide/data-definition-language/common-syntax-elements.md).

# 공통 문법 요소

### 제약 조건

테이블 또는 뷰에 포함되는 데이터의 무결성을 위해 제한 사항을 설정할 수 있으며, 이를 제약 조건이라고 합니다. 제약 조건의 이름은 생략할 수 있습니다. 생략하면 시스템에서 유일한 이름을 자동으로 생성합니다. 제약 조건에는 NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK가 있습니다.

각 제약 조건의 문법은 다음과 같습니다.

<div align="left"><figure><img src="https://content.gitbook.com/content/evqs7Ne3nMyXQFkBSQWR/blobs/E64GFLJ63c0z6ZQnwSxy/constraint.png" alt="" width="563"><figcaption></figcaption></figure></div>

#### **NOT NULL**

NOT NULL 제약 조건은 해당 컬럼 값으로 NULL을 허용하지 않으며, 반드시 데이터를 입력해야 합니다. 이와 반대로 제약 조건이 **NULL**이면 해당 컬럼은 NULL 값을 허용합니다. 컬럼에 NULL이나 NOT NULL을 명시하지 않으면 NULL이 기본값으로 설정됩니다.

#### **UNIQUE**

UNIQUE 제약 조건은 해당 컬럼의 유일성을 보장하는 제약 조건입니다. 한 로우(row)의 컬럼 조합(combination) 값은 다른 로우의 같은 컬럼 조합 값으로 중복될 수 없습니다. 즉, 동시에 두 개 이상의 로우가 동일한 컬럼 조합 값을 갖는 것을 제한합니다.

UNIQUE 제약 조건은 해당 제약 조건에 설정된 컬럼 값으로 NULL 값을 갖는 것을 허용합니다. 하나의 컬럼만 갖는 UNIQUE 제약 조건이라면 여러 로우에서 해당 컬럼에 NULL 값을 가질 수 있습니다.

그러나 여러 컬럼을 포함하는 UNIQUE 제약 조건이라면, 제약 조건에 포함된 컬럼이 모두 NULL인 경우를 제외하고 컬럼의 일부가 NULL이더라도 컬럼 조합 값이 같으면 허용하지 않습니다.

다음은 UNIQUE 제약 조건의 예입니다.

```
UNIQUE(a, b)
```

위와 같이 제약 조건이 컬럼 `a`, `b`에 설정되어 있으면 해당 컬럼에 `(1, NULL)`, `(NULL, 2)` 같은 값을 가진 로우는 허용됩니다. 하지만 `(1, NULL)`이 두 개 이상 존재하는 것은 허용되지 않습니다. 반면 모든 컬럼 조합이 NULL인 `(NULL, NULL)` 값은 여러 로우에서 가질 수 있습니다.

#### **PRIMARY KEY**

PRIMARY KEY 제약 조건은 NOT NULL 제약 조건과 UNIQUE 제약 조건을 결합한 것과 같습니다. 테이블이나 뷰는 하나의 PRIMARY KEY 제약 조건만 가질 수 있습니다.

Tibero는 UNIQUE 제약 조건이나 PRIMARY KEY 제약 조건이 설정된 컬럼에 유일 인덱스(unique index)를 생성합니다. `constraint_state`에서 인덱스를 지정하지 않으면 자동으로 UNIQUE 인덱스를 생성하거나, 이미 존재하는 UNIQUE 인덱스를 사용합니다.

#### **FOREIGN KEY**

FOREIGN KEY 제약 조건은 같은 테이블 또는 서로 다른 두 테이블의 키 컬럼 사이 관계를 나타냅니다. 즉, 어떤 컬럼의 REFERENCED KEY와 FOREIGN KEY 사이의 관계입니다. FOREIGN KEY로 지정된 컬럼 값은 FOREIGN KEY가 참조하는 컬럼의 데이터 값만 가질 수 있습니다. 복합 컬럼(composite column)으로 구성된 FOREIGN KEY도 동일합니다.

FOREIGN KEY로 지정된 컬럼과 REFERENCED KEY로 지정된 컬럼은 개수와 각 데이터 타입이 같아야 합니다.

다음은 FOREIGN KEY 제약 조건의 예입니다.

```
REFERENCED KEY = (1, 2), (2, 3), (4, 2)
FOREIGN KEY = (1, 2), (2, 3), (4, 2)
```

위와 같이 REFERENCED KEY로 지정된 컬럼 값이 `(1, 2)`, `(2, 3)`, `(4, 2)`로 존재하면 FOREIGN KEY로 지정된 컬럼 값도 `(1, 2)`, `(2, 3)`, `(4, 2)`만 가능합니다. 다른 값은 허용되지 않습니다. 다른 테이블의 컬럼을 참조하는 경우에는 해당 테이블에 대한 REFERENCE OBJECT 특권이 필요합니다.

하나의 컬럼은 여러 FOREIGN KEY 제약 조건에 참여할 수 있습니다. REFERENCED KEY는 이미 UNIQUE 또는 PRIMARY KEY로 지정된 컬럼이어야 합니다.

REFERENCED KEY는 같은 테이블의 컬럼일 수도 있고 다른 테이블의 컬럼일 수도 있습니다. 같은 테이블의 컬럼을 참조하는 경우 테이블 이름은 생략할 수 있습니다. REFERENCED KEY의 PRIMARY KEY 값과 UNIQUE 값을 삭제하면 참조 무결성이 깨질 수 있으므로, 이를 보장하기 위해 FOREIGN KEY도 함께 처리해야 합니다.

Tibero는 FOREIGN KEY 제약 조건이 지정된 컬럼에 인덱스를 생성하지 않습니다.

FOREIGN KEY를 지정할 때 설정할 수 있는 옵션은 다음과 같습니다.

<table><thead><tr><th width="179">옵션</th><th>설명</th></tr></thead><tbody><tr><td>ON DELETE</td><td>references_clause의 ON DELETE 옵션을 사용하여 참조된 컬럼 값이 삭제될 때 참조하는 컬럼 값의 동작을 설정</td></tr><tr><td>CASCADE</td><td>참조되는 컬럼 값이 삭제될 때 참조하는 컬럼 값도 함께 삭제</td></tr><tr><td>SET NULL</td><td>참조되는 컬럼 값이 삭제될 때 참조하는 컬럼 값을 NULL로 변경</td></tr></tbody></table>

#### **CHECK**

CHECK 제약 조건은 `expr`로 표현한 조건이 항상 참이 되도록 유지합니다. 테이블에 DML이 있을 때마다 조건을 평가하며, 조건을 만족하지 못하면 에러가 발생합니다.

`inline_constraint`의 CHECK 제약 조건에서는 해당 컬럼 하나만 조건 수식에 포함할 수 있습니다. `out_of_line_constraint`의 CHECK 제약 조건에서는 제약 조건이 선언된 테이블의 모든 컬럼을 사용할 수 있습니다. 다른 테이블의 컬럼은 조건 수식에 포함할 수 없습니다.

{% hint style="info" %}
**참고**

UNIQUE, PRIMARY KEY, FOREIGN KEY가 포함할 수 있는 컬럼 수는 최대 32개입니다. UNIQUE, PRIMARY KEY 제약 조건은 구성 컬럼으로 인덱스를 사용하므로 컬럼 전체 길이가 인덱스를 생성할 수 있는 최대 길이를 넘을 수 없습니다. 같은 컬럼으로 구성된 UNIQUE와 PRIMARY KEY를 동시에 설정할 수 없습니다.

LONG, LONG RAW는 UNIQUE, PRIMARY KEY, FOREIGN KEY 제약 조건의 키 컬럼에 포함될 수 없습니다.
{% endhint %}

### Constraint\_state

Constraint\_state는 제약 조건을 활성화하거나 비활성화하고, 이미 삽입된 데이터가 제약 조건을 만족하는지 검증하는 역할을 합니다. Constraint\_state는 테이블이 처음 생성될 때나 컬럼이 새로 추가될 때처럼 제약 조건이 생성되기 전에 사용할 수 있습니다. 또한 테이블이 생성된 뒤 제약 조건을 추가로 설정할 때도 사용할 수 있습니다.

Constraint\_state의 세부 내용은 다음과 같습니다.

* **문법**

<div align="left"><figure><img src="https://content.gitbook.com/content/evqs7Ne3nMyXQFkBSQWR/blobs/sEMO0Gx51TLyyzEKI6Cz/constraint_state.png" alt="" width="563"><figcaption></figcaption></figure></div>

* **구성요소**

– constraint\_state

<table><thead><tr><th width="171">구성요소</th><th>설명</th></tr></thead><tbody><tr><td>ENABLE</td><td><ul><li>새로 삽입될 데이터에 제약 조건을 적용</li><li>처음 제약 조건이 생성될 때 ENABLE이나 DISABLE을 지정하지 않으면 ENABLE이 기본값으로 설정</li><li>DISABLE 상태의 제약 조건에 ENABLE을 적용하면 앞으로 삽입될 데이터에 다시 제약 조건을 적용할 수 있음</li><li>UNIQUE나 PRIMARY KEY 제약 조건에 ENABLE을 적용하면 이미 존재하는 UNIQUE 인덱스를 사용</li><li>UNIQUE 인덱스가 없으면 새로 UNIQUE 인덱스를 생성</li><li>FOREIGN KEY 제약 조건의 경우 비유일 인덱스에 대해 같은 동작을 수행</li></ul></td></tr><tr><td>DISABLE</td><td><ul><li>새로 삽입될 데이터에 제약 조건을 적용하지 않음</li><li>UNIQUE, PRIMARY KEY, FOREIGN KEY 제약 조건을 DISABLE로 설정하면 관련 인덱스를 삭제</li><li>DISABLE로 설정된 UNIQUE나 PRIMARY KEY를 참조하는 FOREIGN KEY는 ENABLE로 설정할 수 없음</li><li>제약 조건 생성 시 함께 만들어진 인덱스가 아니라 기존 인덱스를 사용하는 경우에는 인덱스를 삭제하지 않음</li></ul></td></tr><tr><td>VALIDATE</td><td><ul><li>이미 테이블에 삽입된 데이터가 제약 조건을 만족하는지 검사하고 보장</li><li>VALIDATE로 설정했는데 데이터가 제약 조건을 만족하지 못하면 에러를 반환하며, VALIDATE가 포함된 DDL 문장은 실행에 실패</li><li>DISABLE VALIDATE 상태는 기존 데이터의 완전성은 보장하지만 이후 삽입될 데이터는 보장하지 않음을 의미하므로, 이 상태의 제약 조건이 존재하는 테이블에서는 데이터 삽입, 삭제, 갱신을 할 수 없게 됨</li></ul></td></tr><tr><td>NOVALIDATE</td><td>이미 테이블에 삽입된 데이터에 대해 제약 조건 만족 여부를 검사하지 않음</td></tr><tr><td>using_index_clause</td><td><ul><li>UNIQUE나 PRIMARY KEY를 설정할 때 사용할 인덱스를 지정하거나 생성하여 사용할 수 있음</li><li>schema.index_name으로 이미 존재하는 인덱스를 사용할 수도 있고, create_index로 인덱스를 생성하여 사용할 수도 있음</li><li>create_index와 index_attributes는 <strong>CREATE INDEX</strong>를 참고</li></ul></td></tr></tbody></table>

– using\_index\_clause

<table><thead><tr><th width="177">구성요소</th><th>설명</th></tr></thead><tbody><tr><td>schema</td><td><ul><li>사용할 인덱스가 속한 스키마를 명시</li><li>생략하면 현재 사용자의 스키마로 인식</li></ul></td></tr><tr><td>index_name</td><td>사용할 인덱스 이름을 명시</td></tr><tr><td>create_index</td><td><ul><li>인덱스를 새로 생성하여 사용할 때 명시</li><li>자세한 내용은 <strong>CREATE INDEX</strong>를 참고</li></ul></td></tr><tr><td>index_attributes</td><td><ul><li>인덱스 속성을 설정할 때 사용</li><li>자세한 내용은 <strong>CREATE INDEX</strong>를 참고</li></ul></td></tr></tbody></table>

– atbl\_con\_alterstate\_cl

<table><thead><tr><th width="268">구성요소</th><th>설명</th></tr></thead><tbody><tr><td>ENABLE</td><td>구성요소 설명 중 constraint_state를 참고</td></tr><tr><td>DISABLE</td><td>구성요소 설명 중 constraint_state를 참고</td></tr><tr><td>VALIDATE</td><td>구성요소 설명 중 constraint_state를 참고</td></tr><tr><td>NOVALIDATE</td><td>구성요소 설명 중 constraint_state를 참고</td></tr><tr><td>PRIMARY KEY</td><td>PRIMARY KEY 제약 조건을 설정</td></tr><tr><td>UNIQUE column_name</td><td><ul><li>UNIQUE 제약 조건을 설정</li><li>column_name에는 UNIQUE 제약 조건을 지정할 컬럼 이름을 명시</li></ul></td></tr><tr><td>CONSTRAINT constraint_name</td><td>상태를 변경할 제약 조건 이름을 명시</td></tr><tr><td>using_index_clause</td><td>구성요소 설명 중 constraint_state를 참고</td></tr><tr><td>CASCADE</td><td><ul><li>참조된 UNIQUE나 PRIMARY KEY 제약 조건을 비활성화할 때 관련된 FOREIGN KEY까지 함께 비활성화하기 위해 사용</li><li>FOREIGN KEY가 존재하는 제약 조건을 비활성화하는 경우 반드시 포함해야 함</li></ul></td></tr><tr><td>KEEP INDEX</td><td><ul><li>제약 조건을 비활성화하면서 제약 조건에서 사용한 인덱스를 제거하지 않고 유지하고자 할 때 명시</li><li>기본값이므로 생략 가능</li></ul></td></tr><tr><td>DROP INDEX</td><td>제약 조건을 제거할 때 해당 제약 조건에서 사용한 인덱스도 함께 제거하고자 할 때 명시</td></tr></tbody></table>

### Deferrable\_option

제약 조건을 매 DML마다 검사하지 않고, COMMIT 시점에 마지막 COMMIT 이후 변경된 데이터에 대해 제약 조건을 확인하도록 하는 기능입니다. COMMIT 시점에 수행되는 제약 조건을 통과하지 못하면 데이터는 마지막 COMMIT 시점으로 모두 ROLLBACK됩니다. FOREIGN KEY를 제외한 제약 조건에서 사용할 수 있습니다.

Deferrable\_option의 세부 내용은 다음과 같습니다.

* **문법**

<div align="left"><figure><img src="https://content.gitbook.com/content/evqs7Ne3nMyXQFkBSQWR/blobs/u79x1BJfz4pb1DmySGck/deferrable_option.png" alt="" width="355"><figcaption></figcaption></figure></div>

* **구성요소**

– deferrable\_option

<table><thead><tr><th width="328">구성요소</th><th>설명</th></tr></thead><tbody><tr><td>DEFERRABLE (INITIALLY (IMMEDIATE))</td><td><ul><li><code>Deferrable constraint</code> 기능을 사용하는 제약 조건 생성문</li><li><code>Deferrable constraint</code> 기능은 사용하지만, 일반 제약 조건과 마찬가지로 DML마다 즉시 조건을 검사할 때 사용</li><li>INITIALLY 또는 IMMEDIATE를 생략해도 의미는 같음</li></ul></td></tr><tr><td>DEFERRABLE INITIALLY DEFERRED</td><td><code>Deferrable constraint</code> 기능을 사용하며 제약 조건을 COMMIT 시점에만 검사할 때 사용</td></tr><tr><td>INITIALLY DEFERRED DEFERRABLE</td><td><code>Deferrable constraint</code> 기능을 사용하며 제약 조건을 COMMIT 시점에만 검사할 때 사용</td></tr></tbody></table>

### Sgmt\_attr

저장 공간의 물리적인 성질과 테이블스페이스 등을 지정하기 위한 구문입니다.

Sgmt\_attr의 세부 내용은 다음과 같습니다.

* **문법**

<div align="left"><figure><img src="https://content.gitbook.com/content/evqs7Ne3nMyXQFkBSQWR/blobs/DjCeURLPrJ8WjHFjOLwj/sgmt_attr.png" alt="" width="305"><figcaption></figcaption></figure></div>

* **구성요소**

<table><thead><tr><th width="282">구성요소</th><th>설명</th></tr></thead><tbody><tr><td>TABLESPACE tablespace_name</td><td><ul><li>데이터가 저장되는 테이블스페이스를 지정할 수 있음</li><li>지정하지 않으면 사용자의 디폴트 테이블스페이스를 사용</li><li>임시 테이블의 경우 디폴트로 지정된 임시 테이블스페이스를 사용</li><li>tablespace_name에 테이블스페이스 이름을 명시</li></ul></td></tr><tr><td>PCTFREE unsigned_integer</td><td><ul><li>데이터를 디스크 블록에 저장할 때 크기 증가에 대비해 얼마만큼의 영역을 예비로 남겨둘지 설정하는 값</li><li>1 ~ 99 사이의 값을 설정할 수 있으며, 지정하지 않으면 기본값은 10</li><li>unsigned_integer에 해당 값을 명시</li></ul></td></tr><tr><td>INITRANS unsigned_integer</td><td><ul><li>디스크 블록마다 transaction entry를 위한 공간을 몇 개 확보할지 나타냄</li><li>transaction entry는 블록에 공간이 남아 있으면 필요할 때 확장</li><li>따라서 미리 큰 값을 설정할 필요는 없음</li><li>최솟값은 1이며 최댓값은 디스크 블록 크기에 따라 다름</li><li>지정하지 않으면 기본값은 2</li><li>unsigned_integer에 해당 값을 명시</li></ul></td></tr><tr><td>LOGGING / NOLOGGING</td><td><ul><li>Direct-Path Loading을 이용하는 경우 Redo 로그를 남기지 않음</li><li>단, Archive Mode를 사용할 경우에는 로그를 남김</li><li>지정하지 않으면 기본값은 LOGGING</li><li>현재 파티션 테이블별 LOGGING 옵션 설정은 지원하지 않음</li></ul></td></tr><tr><td>storage_clause</td><td><ul><li>세그먼트의 세부 속성을 정의</li><li>자세한 내용은 <strong>Storage_clause</strong>를 참고</li></ul></td></tr></tbody></table>

### Storage\_clause

세그먼트의 세부적인 속성을 정의하기 위한 구문입니다.

Storage\_clause의 세부 내용은 다음과 같습니다.

* **문법**

<div align="left"><figure><img src="https://4150084347-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fevqs7Ne3nMyXQFkBSQWR%2Fuploads%2Fgit-blob-ca8d0101b2dfa48d100ec3bf0844eb5bce489141%2Finput_storage_clause.png?alt=media" alt="" width="445"><figcaption></figcaption></figure></div>

* **구성요소**

<table><thead><tr><th width="191">구성요소</th><th>설명</th></tr></thead><tbody><tr><td>MAXSIZE</td><td>세그먼트에 할당되는 최대 크기 지정</td></tr><tr><td>SIZE</td><td>제한할 세그먼트 크기를 명시</td></tr><tr><td>UNLIMITED</td><td><ul><li>세그먼트 크기를 제한하지 않음</li><li>지정하지 않으면 기본값은 UNLIMITED</li></ul></td></tr><tr><td>INITIAL</td><td><ul><li>세그먼트의 최초 생성 크기를 지정</li><li>지정하지 않으면 _SGMT_INITIAL_EXTSIZE 파라미터에 설정된 크기로 생성</li></ul></td></tr><tr><td>BUFFER_POOL</td><td>해당 세그먼트의 데이터 블록을 어떤 <code>Buffer Pool</code>에 넣을지 지정</td></tr><tr><td>KEEP</td><td><ul><li>세그먼트 블록을 KEEP <code>Buffer Pool</code>에 넣어 메모리에 보존하도록 함</li><li>이로써 I/O 연산 시간을 줄일 수 있음</li><li>$TB_SID.tip 파일에 DB_KEEP_CACHE_SIZE 파라미터가 설정되어 있어야 Buffer 캐시에 KEEP <code>Buffer Pool</code>이 설정됨</li><li>DB_KEEP_CACHE_SIZE 파라미터가 설정되어 있지 않으면 BUFFER_POOL KEEP 지정은 의미가 없음</li></ul></td></tr><tr><td>RECYCLE</td><td><ul><li>세그먼트 블록을 RECYCLE <code>Buffer Pool</code>에 넣어 DEFAULT <code>Buffer Pool</code>이 불필요한 버퍼 캐시를 저장하지 않도록 함</li><li>$TB_SID.tip 파일에 DB_RECYCLE_CACHE_SIZE 파라미터가 설정되어 있어야 Buffer 캐시에 RECYCLE <code>Buffer Pool</code>이 설정됨</li><li>DB_RECYCLE_CACHE_SIZE 파라미터가 설정되어 있지 않으면 BUFFER_POOL RECYCLE 지정은 의미가 없음</li></ul></td></tr><tr><td>DEFAULT</td><td>DEFAULT로 지정하거나 BUFFER_POOL 옵션을 지정하지 않으면 DEFAULT <code>Buffer Pool</code>을 사용</td></tr></tbody></table>
