DDL (Data Definition Language) 은 데이터베이스의 구조를 정의하거나 변경하는 데 사용되는 명령어입니다.
주로 테이블, 뷰, 인덱스, 스키마 등을 생성, 수정, 삭제하는 역할을 합니다.
DDL 명령어는 호출 후 롤백 할 수 없으며 자동 커밋되는 특징을 가지고 있습니다.
오라클의 경우 같은 트랜젝션 내에서 DML1 -> DML2 -> DDL 을 호출 했다면 DDL Auto Commit 으로 인해 DML1, DML2 가 자동 커밋 됩니다.
``` sql fold title:'DDL'
-- create : 생성
create table DB명.테이블명(
필드명 int auto_increment primary key
필드명 타입(사이즈) not null,
Foreign key(필드명) references 클래스(컬럼)
-- primay key (컬럼)
);
-- alter : 구조변경
alter table 테이블명 add 컬럼명 타입;
alter table 테이블명 add primay key (컬럼명);
alter table 테이블명 drop colomn 컬럼명;
alter table 테이블명 change 컬럼명 데이터타입;
-- drop : 삭제
drop table 테이블명;
-- 연관 테이블 모두 삭제
drop table 테이블명 casecade
-- truncate : 데이터 전부 삭제
truncate TABLE 테이블명;
무결성은 데이터의 정확성과 일관성을 보장하기위한 제약 조건 입니다.
모든 테이블은 기본키(PK) 를 기준으로 식별할 수 있어야 합니다.
따라서 기본키는 반드시 유일하고 null 이 될 수 없습니다.
외래키(FK) 는 존재하는 기본키를 참조해야 합니다.
CASECADE 는 테이블간 연관관계를 맺을 때 참조 무결성을 지키기 위한 설정 입니다.
참조된 부모 테이블의 PK 가 변경되거나 삭제될 때 자식 테이블도 자동으로 수정 및 삭제 되도록 하는 설정 입니다.
-- 부모 테이블 열이 삭제될 떄 연관된 자식 테이블 열도 삭제되도록 설정
alter table T
add foreign key (컬럼명) reference ParentT (id)
on delete casecade;
-- 부모 테이블 열이 삭제될 떄 연관된 자식 테이블 FK 를 null 로 설정
alter table T
add foreign key (컬럼명) reference ParentT (id)
on delete set null;
-- 부모 테이블의 PK 가 변경될 때 연관된 자식 테이블 FK가 변경되도록 설정
alter table T
add foreign key (컬럼명) reference ParentT (id)
on update casecade;
컬럼이 가질 수 있는 값의 형식과 범위를 제한하는 제약 입니다.
이는 컬럼의 데이터 타입, 범위 ,패턴, NULL 여부 등을 제안 합니다.
CREATE TABLE products (
id NUMBER PRIMARY KEY,
price NUMBER CHECK (price >= 0), -- 음수 금지
name VARCHAR2(100) NOT NULL -- 반드시 이름 있어야 함
);
뷰는 하나 이상의 테이블에 유도된 가상 테이블을 의미합니다.
보안을 강화하는 목적으로 사용될 수 있으며 실제 테이블이 변경 되더라도 영향받지 않는다는 장점을 가집니다.
뷰는 정의만을 가지고 있으며 실행 시점에 질의를 재작성하여 화면에 노출합니다.
특정 DBMS 는 실제 데이터를 저장하고 있는 뷰를 생성하는 기능을 지원하기도 합니다.
MySQL/MariaDB는 전통적으로 alter 명령 실행시 작업이 완료될 때까지 해당 테이블 전체에 락을 걸어 읽기, 쓰기 작업이 불가능 했습니다.
MySQL 5.6(MariaDB 10.0) 부터 InnoDB 테이블에 Online DDL 기능이 추가되어 테이블 락을 최소화한 테이블 수정이 가능해졌습니다. 사용자는 alter 명령 실행시 ALGORITHM, LOCK 2개 옵션을 추가로 명시해주면 테이블 락을 최소화하여 테이블 스키마를 수정하는 작업을 수행할 수 있게 되었습니다.
ALTER TABLE test
ADD COLUMN test_col VALCHAR(2) AFTER id,
ALGORITHM=INPLACE, LOCK=NONE;
COPY
변경 내역을 적용한 신규 테이블을 생성한 후 원본 테이블 데이터를 로우 단위로 복제하는 방식 입니다.
복제본을 만들어야 하기 때문에 시스템 자원을 많이 소모 합니다.
INPLACE
테이블을 복사하지 않고 기존 테이블에서 직접 작업을 수행하는 방식으로 작업을 빠르게 처리하고 시스템 자원을 적게 소모하는 특징이 있습니다.
다만 만약 MySQL 5.6 이전 버전을 사용하면서 테이블을 생성했고 이후 MySQL 5.6 으로 업그레이드 했다면 ALGORITHM=INPLACE 를 사용할 경우 ERROR 1846 (0A000) 오류가 발생합니다.
이 경우 최초 한 번은 ALGORITHM=COPY 를 사용하여 리빌드 해주어야 합니다.
INPLACE 방식은 컬럼의 데이터 타입을 변경하거나 컬럼의 순서를 변경하는 등 테이블 구조에 큰 영향을 주는 작업은 적용되지 않습니다.
INSTANT
MySQL 8.0.12(MariaDB 10.3.7) 부터 지원하는 최신 모드 입니다.
메타 데이터 변경 만으로 빠르게 변경사항을 반영하는 방식으로 속도가 빠르며 시스템 자원을 거의 소모하지 않습니다. 수정하는 테이블이 실행중인 모든 쿼리가 종료될 때 까지 기다리는 일시적인 메타데이터 잠금만 발생할 뿐 입니다.
이 모드는 LOCK 모드를 선언하지 않아도 됩니다.
공통 제약사항
대상 테이블이 FULLTEXT 인덱스를 가지면 안됩니다.
대상 테이블이 TEMPORARY 테이블이면 안됩니다.MySQL 8.0.29(MariaDB 10.6) 이전 버전 제약사항
컬럼 추가시 위치를 명시적으로 지정하면 안됩니다. (항상 마지막 컬럼 뒤에 들어갑니다)
컬럼 삭제
NONE
락을 사용하지 않습니다. 온라인 작업을 수행하며 테이블 변경시에 읽기/쓰기 작업을 할 수 있도록 허용 합니다.
SHARED
테이블을 읽을수는 있지만 데이터를 변경할 수 없습니다.
해당 모드에서 데이터 변경 (쓰기작업 등) 요청이 들어오면 해당 요청은 대기 상태가 됩니다.
EXCLUSIVE
테이블에 대한 읽기/쓰기 작업을 모두 차단합니다.
데이터 무결성을 보장하지만 서비스 중단이 발생할 수 있습니다.
INSTANT 알고리즘을 선택할 수 있는 환경과 조건이라면 INSTANT 를 사용하는게 최적의 선택 입니다.
만약 INSTANT 를 사용하지 못하는 조건(MySql 5.6 ~ 8.0 미만) 이라면 다음의 표를 참고하여 알고리즘과 Lock 을 선택하는게 좋습니다. 참고로 COPY 알고리즘은 NONE 락을 지원하지 않습니다.
| Query | Algorithm | Lock | Description |
|---|---|---|---|
| ADD COMUMN | INPLACE | NONE | 읽기/쓰기 허용 |
| ADD INDEX | INPLACE | NONE | 읽기/쓰기 허용 |
| ADD PARTITION | COPY | EXCLUSIVE | 모두 차단 |
| DROP COLUMN | INPLACE | NONE/ SHARED | 서비스 성향에 따라 결정 |
| DROP INDEX | INPLACE | SHARED | 읽기만 허용 |
| DROP PARTITION | COPY | EXCLUSIVE | 모두 차단 |
| MODIFY COLUMN | COPY | EXCLUSIVE | 모두 차단 |
| PK 추가 | COPY | EXCLUSIVE | 모두 차단 |
| UK 추가 | INPLACE | NONE / SHARED | 서비스 상황에 따라 결정 |
만약 테이블 수정시 알고리즘과 락 모드를 설정하지 않았다면
MySQL은 작업 유형에 따라 최적의 알고리즘과 락모드를 선택합니다. 선택 우선순위는 다음과 같습니다.
알고리즘 : INSTANT > INPLACE > COPY
락모드 : NONE > SHARED > EXCLUSIVE