- ADD COLUMN — 테이블에 새 컬럼을 추가합니다.
- DROP COLUMN — 컬럼을 삭제합니다.
- RENAME COLUMN — 기존 컬럼의 이름을 변경합니다.
- CLEAR COLUMN — 컬럼 값을 초기화합니다.
- COMMENT COLUMN — 컬럼에 텍스트 주석을 추가합니다.
- MODIFY COLUMN — 컬럼의 유형, 기본 표현식, TTL 및 컬럼 설정을 변경합니다.
- MODIFY COLUMN REMOVE — 컬럼 속성 중 하나를 제거합니다.
- MODIFY COLUMN MODIFY SETTING - 컬럼 설정을 변경합니다.
- MODIFY COLUMN RESET SETTING - 컬럼 설정을 재설정합니다.
- MATERIALIZE COLUMN — 컬럼이 없는 파트에서 컬럼을 구체화합니다. 이러한 작업은 아래에서 자세히 설명합니다.
ADD COLUMN
name, type, codec, default_expr를 사용해 테이블에 새 컬럼을 추가합니다(기본 표현식 섹션 참조).
IF NOT EXISTS 절이 포함되어 있으면 해당 컬럼이 이미 존재하더라도 쿼리는 오류를 반환하지 않습니다. AFTER name_after(다른 컬럼의 이름)를 지정하면 테이블 컬럼 목록에서 지정한 컬럼 다음에 새 컬럼이 추가됩니다. 테이블의 맨 앞에 컬럼을 추가하려면 FIRST 절을 사용하십시오. 그렇지 않으면 컬럼은 테이블의 끝에 추가됩니다. 일련의 작업에서는 name_after에 이전 작업 중 하나에서 추가된 컬럼의 이름을 지정할 수 있습니다.
컬럼을 추가하더라도 데이터 자체에는 아무 작업도 수행되지 않으며, 테이블 구조만 변경됩니다. ALTER 후에도 데이터는 디스크에 기록되지 않습니다. 테이블을 읽을 때 해당 컬럼의 데이터가 없으면 기본값으로 채워집니다(기본 표현식이 있으면 이를 적용하고, 없으면 0 또는 빈 문자열을 사용합니다). 컬럼은 데이터 파트가 머지된 후 디스크에 나타납니다(MergeTree 참조).
이 방식은 기존 데이터의 양을 늘리지 않고도 ALTER 쿼리를 즉시 완료할 수 있게 해줍니다.
예시:
DROP COLUMN
name인 컬럼을 삭제합니다. IF EXISTS 절을 지정하면 해당 컬럼이 존재하지 않더라도 쿼리에서 오류를 반환하지 않습니다.
파일 시스템에서 데이터를 삭제합니다. 전체 파일을 삭제하므로 쿼리가 거의 즉시 완료됩니다.
예시:
COLUMN 이름 변경
name의 이름을 new_name으로 변경합니다. IF EXISTS 절을 지정하면 해당 컬럼이 존재하지 않아도 쿼리에서 오류를 반환하지 않습니다. 이름 변경은 실제 데이터를 수정하지 않으므로 쿼리는 거의 즉시 완료됩니다.
참고: 테이블(table)의 키 표현식에 포함된 컬럼(ORDER BY 또는 PRIMARY KEY로 지정된 컬럼)은 이름을 변경할 수 없습니다. 이러한 컬럼의 이름을 변경하려고 하면 SQL Error [524]가 발생합니다.
예시:
CLEAR COLUMN
IF EXISTS 절을 지정하면 컬럼이 존재하지 않더라도 쿼리에서 오류를 반환하지 않습니다.
예시:
COMMENT COLUMN
IF EXISTS 절을 지정하면 컬럼이 존재하지 않아도 쿼리에서 오류를 반환하지 않습니다.
각 컬럼에는 주석을 하나만 지정할 수 있습니다. 컬럼에 이미 주석이 있으면 새 주석이 기존 주석을 덮어씁니다.
주석은 DESCRIBE TABLE 쿼리에서 반환되는 comment_expression 컬럼에 저장됩니다.
예시:
MODIFY COLUMN
name 컬럼의 다음 속성을 변경합니다:
- 유형
- 기본 표현식
- 압축 코덱
- TTL
- 컬럼 수준 설정
IF EXISTS 절이 지정되면 해당 컬럼이 존재하지 않아도 쿼리는 오류를 반환하지 않습니다.
유형을 변경할 때는 값에 toType 함수가 적용된 것처럼 변환됩니다. 기본 표현식만 변경하는 경우 쿼리는 복잡한 작업을 수행하지 않으며 거의 즉시 완료됩니다.
예시:
FIRST | AFTER 절을 사용해 컬럼 순서도 변경할 수 있습니다. 자세한 내용은 ADD COLUMN 설명을 참조하십시오. 다만 이 경우에는 컬럼 유형을 반드시 지정해야 합니다.
예시:
ALTER 쿼리는 원자적으로 처리됩니다. MergeTree 테이블에서는 잠금 없이 수행됩니다.
컬럼을 변경하는 ALTER 쿼리는 복제됩니다. 변경 지시 사항은 ZooKeeper에 저장된 다음, 각 레플리카가 이를 적용합니다. 모든 ALTER 쿼리는 동일한 순서로 실행됩니다. 이 쿼리는 다른 레플리카에서 해당 작업이 완료될 때까지 대기합니다. 그러나 복제된 테이블의 컬럼을 변경하는 쿼리는 중간에 중단될 수 있으며, 모든 작업은 비동기적으로 수행됩니다.
널 허용(Nullable) 컬럼을 Non-Nullable로 변경할 때는 특히 주의하십시오. 해당 컬럼에 NULL 값이 없는지 반드시 확인해야 합니다. 그렇지 않으면 해당 컬럼을 읽을 때 문제가 발생합니다. 이런 경우에는 뮤테이션을 중지하고 컬럼을 다시 Nullable 타입으로 되돌리는 방식으로 대응할 수 있습니다.
MODIFY COLUMN REMOVE
DEFAULT, ALIAS, MATERIALIZED, CODEC, COMMENT, TTL, SETTINGS.
구문:
MODIFY COLUMN MODIFY SETTING
max_compress_block_size를 1MB로 변경합니다:
MODIFY COLUMN RESET SETTING
max_compress_block_size를 기본값으로 재설정합니다:
MATERIALIZE COLUMN
DEFAULT 또는 MATERIALIZED 값 표현식이 있는 컬럼을 구체화합니다. ALTER TABLE table_name ADD COLUMN column_name MATERIALIZED를 사용해 구체화된 컬럼을 추가할 때, 구체화된 값이 없는 기존 행은 자동으로 채워지지 않습니다. MATERIALIZE COLUMN SQL 문은 DEFAULT 또는 MATERIALIZED 표현식을 추가하거나 업데이트한 뒤 기존 컬럼 데이터를 재작성하는 데 사용할 수 있습니다(이 작업은 메타데이터만 업데이트하며 기존 데이터는 변경하지 않음). 정렬 키에 포함된 컬럼을 구체화하는 작업은 정렬 순서를 깨뜨릴 수 있으므로 유효하지 않습니다.
뮤테이션으로 구현됩니다.
새로 추가되었거나 업데이트된 MATERIALIZED 값 표현식이 있는 컬럼의 경우, 모든 기존 행이 재작성됩니다.
새로 추가되었거나 업데이트된 DEFAULT 값 표현식이 있는 컬럼의 경우, 동작은 ClickHouse 버전에 따라 달라집니다:
- ClickHouse < v24.2에서는 모든 기존 행이 재작성됩니다.
- ClickHouse >= v24.2에서는
DEFAULT값 표현식이 있는 컬럼의 행 값이 삽입될 때 명시적으로 지정되었는지, 아니면DEFAULT값 표현식으로 계산되었는지를 구분합니다. 값이 명시적으로 지정된 경우 ClickHouse는 해당 값을 그대로 유지합니다. 값이 계산된 경우 ClickHouse는 이를 새로 추가되었거나 업데이트된MATERIALIZED값 표현식으로 변경합니다.
- PARTITION을 지정하면 해당 컬럼은 지정된 파티션에만 구체화됩니다.
제한 사항
ALTER 쿼리를 사용하면 중첩 데이터 구조의 개별 요소(컬럼)는 생성 및 삭제할 수 있지만, 중첩 데이터 구조 전체는 생성하거나 삭제할 수 없습니다. 중첩 데이터 구조를 추가하려면 name.nested_name과 같은 이름과 Array(T) 유형을 가진 컬럼을 추가하면 됩니다. 중첩 데이터 구조는 점 앞의 접두사가 같은 이름을 가진 여러 배열 컬럼과 동일합니다.
이름에 점이 포함된 컬럼의 이름 변경은 부분적으로만 지원됩니다. 점은 Nested 하위 컬럼 접근용으로 예약되어 있으므로, 접두사(상위 이름)는 그대로 유지되어야 합니다. 접미사(하위 컬럼 이름)만 변경할 수 있습니다. 예를 들어 a.b는 a.c로 이름을 바꿀 수 있지만, Nested 상위 접두사가 바뀌므로 a.b를 b.d로 바꾸는 것은 허용되지 않습니다.
프라이머리 키 또는 샘플링 키(ENGINE 표현식에 사용되는 컬럼)의 컬럼 삭제는 지원되지 않습니다. 프라이머리 키에 포함된 컬럼의 유형 변경은 해당 변경으로 데이터가 수정되지 않는 경우에만 가능합니다(예를 들어 Enum에 값을 추가하거나 DateTime 유형을 UInt32로 변경하는 것은 허용됩니다).
필요한 테이블 변경을 수행하기에 ALTER 쿼리만으로 충분하지 않다면, 새 테이블을 만들고 INSERT SELECT 쿼리를 사용해 데이터를 복사한 다음, RENAME 쿼리로 테이블을 전환하고 기존 테이블을 삭제할 수 있습니다.
ALTER 쿼리는 해당 테이블에 대한 모든 읽기 및 쓰기를 차단합니다. 즉, ALTER 쿼리 실행 시점에 오래 실행 중인 SELECT가 있다면 ALTER 쿼리는 그것이 완료될 때까지 기다립니다. 동시에 같은 테이블에 대한 모든 새 쿼리도 이 ALTER가 실행되는 동안 대기합니다.
자체적으로 데이터를 저장하지 않는 테이블(Merge, Distributed 등)의 경우, ALTER는 테이블 구조만 변경하며 하위 테이블의 구조는 변경하지 않습니다. 예를 들어 Distributed 테이블에 대해 ALTER를 실행할 때는 모든 원격 서버의 테이블에도 ALTER를 실행해야 합니다.