# 26강. 테이블 작성, 삭제, 변경
대표적인 데이터베이스 객체인 테이블을 작성, 삭제, 변경하는 방법에 대해 알아본다.

**`테이블의 작성, 삭제, 변경`**
```
CREATE TABLE 테이블명 (열 정의1, 열 정의2, ...)
DROP TABLE 테이블명
ALTER TABLE 테이블명 하부명령
```

- `SELECT`, `INSERT`, `DELETE`, `UPDATE`는 SQL 명령 중에서도 `DML`로 분류된다.
- `DML`은 데이터를 조작하는 명령이다. 한편, `DDL`은 데이터를 정의하는 명령으로, 스키마 내의 객체를 관리할 때 사용한다.

---

## 1. 테이블 작성
- `DDL`은 모두 같은 문법을 사용한다.
- `CREATE`로 작성, `DROP`으로 삭제, `ALTER`로 변경할 수 있다.
- 뒤이어 어떤 객체를 작성, 삭제, 변경할지를 지정한다.
- 예를 들어 테이블을 작성한다면 `CREATE TABLE`, 뷰를 작성한다면 `CREATE VIEW`와 같이 지정하면 된다.
- `RDBMS`에서 데이터베이스 상에 제일 먼저 만드는 객체 중 하나가 바로 테이블이다.
- 이때 `CREATE TABLE` 명령을 사용한다.
- `CREATE TABLE`에 이어서 작성하고 싶은 테이블의 이름을 지정한다.
- 테이블명 뒤에서는 괄호로 묶어 열을 정의할 수 있으며, 열을 정의할 때는 테이블에 필요한 열을 `콤마(,)`로 구분하여 연속해 지정한다.

**`CREATE TABLE`**
```
CREATE TABLE 테이블명 (
    열 정의1,
    열 정의2,
    ...
)
```

- 열명은 열에 붙이는 이름이며, 명명규칙에 맞게 이름을 붙여준다.
- 자료형은 `INTEGER`나 `VARCHAR` 등을 지정한다.
- 특히 `CHAR`나 `VARCHAR`와 같은 문자열형으로 지정할 때는 최대길이를 괄호로 묶어줘야 한다.
- 기본값을 설정할 때는 `DEFAULT`로 지정하되 자료형에 맞는 리터럴로 기술하며, 기본값은 생략할 수 있다.
- 마지막으로 열이 `NULL`을 허용할 것인지를 지정한다.
- `NULL`을 명시적으로 지정하거나 생략했을 경우는 `NULL`을 허용한다.
- 한편 `NOT NULL`이라고 지정하면 제약이 걸리면서 `NULL`이 허용되지 않는다.

**`열 정의`**
```
열명 자료형 [DEFAULT 기본값] [NULL|NOT NULL]
```

##### CREATE TABLE로 테이블을 작성할 수 있다!

---

## 2. 테이블 삭제
- 필요 없는 테이블은 삭제할 수 있는데, 이때 `DROP TABLE` 명령을 사용한다.

**`DROP TABLE`**
```
DROP TABLE 테이블명
```

- `DROP TABLE`에서 지정하는 것은 테이블명 뿐이다. 이때 주의할 점은 많은 데이터베이스가 SQL 명령을 실행할 때 확인을 요구하지 않는다는 것이다.
- `OS`의 경우(제품에 따라 다르기는 하지만) 삭제 명령으로 파일을 모두 삭제하려 하면 `정말 삭제하겠습니까?`라는 메시지가 표시된다.
- 하지만 SQL 명령의 경우 사용자에게 이와 같은 확인은 하지 않는다. 실수로 테이블을 삭제하지 않도록 신중하게 `DROP TABLE`을 실행해야 한다.

##### DROP TABLE로 테이블을 삭제할 수 있다!

### 데이터 행 삭제
- `DROP TABLE` 명령은 데이터베이스에서 테이블을 삭제한다. 이때 테이블에 저장된 데이터도 함께 삭제된다.
- 한편 테이블 정의는 그대로 둔채 데이터만 삭제할 때는 `DELETE` 명령을 사용한다.
- 이때 `DELETE` 명령에 `WHERE` 조건을 지정하지 않으면 테이블의 모든 행을 삭제할 수 있다.
- 하지만 `DELETE` 명령은 행 단위로 여러 가지 내부처리가 일어나므로 삭제할 행이 많으면 처리속도가 상당히 늦어진다.
- 이런 경우에는 `DDL`로 분류되는 `TRUNCATE TABLE` 명령을 사용한다.
- `TRUNCATE TABLE` 명령은 삭제할 행을 지정할 수 없고 `WHERE` 구를 지정할 수도 없지만, 모든 행을 삭제해야 할 때 빠른 속도로 삭제할 수 있다.

**`TRUNCATE TABLE`**
```
TRUNCATE TABLE 테이블명
```

---

## 3. 테이블 변경
- 테이블을 작성해버린 뒤에도 열 구성은 얼마든지 변경할 수 있다. 이때 테이블 변경은 `ALTER TABLE` 명령을 통해 이루어진다.

**`ALTER TABLE`**
```
ALTER TABLE 테이블명 변경명령
```

- 테이블을 작성한 뒤에도 열을 추가하거나 데이터 최대길이를 변경하는 등 구성을 바꿔야 하는 경우가 종종 생기는데, 이때 테이블이 비어있다면 `DROP TABLE`로 테이블을 삭제하고 나서 변경할 테이블 구조에 맞추어 `CREATE TABLE`을 실행해 테이블을 변경할 수 있다.
- 하지만 테이블에 데이터가 이미 존재하는 경우라면 `DROP TABLE`로 테이블을 삭제하는 순간 기존 데이터도 모두 삭제된다.
- 이때 `ALTER TABLE` 명령을 사용하면 테이블에 저장되어 있는 데이터는 그대로 남긴 채 구성만 변경할 수 있다.
 
`ALTER TABLE`로 할 수 있는 일은 크게 다음과 같이 두 가지로 분류할 수 있다.

- 열추가, 삭제, 변경
- 제약 추가, 삭제

### 열 추가
- `ALTER TABLE`에서 열을 추가할 때는 `ADD 하부명령`을 통해 실행할 수 있다.

**`열 추가`**
```
ALTER TABLE 테이블명 ADD 열 정의
```

- 여기에서의 열 정의는 `CREATE TABLE`의 경우와 동일하다.
- 즉, 열 이름과 각 자료형을 지정하고 필요에 따라 기본값과 `NOT NULL` 제약을 지정하면 된다. 물론 열의 이름이 중복되면 열을 추가할 수 없다.

`ALTER TABLE sample62 ADD newcol INTEGER;`

##### ALTER TABLE ADD로 테이블에 열을 추가할 수 있다!

- `ALTER TABLE ADD`로 열을 추가할 때, 기존 데이터행이 존재하면 추가한 열의 값이 모두 `NULL`이 된다.
- 물론 기본값이 지정되어 있으면 기본값으로 데이터가 저장된다.
- 한편 `NOT NULL` 제약을 붙인 열을 추가하고 싶다면 먼저 `NOT NULL`로 제약을 건 뒤에 `NULL` 이외의 값으로 기본값을 지정할 필요가 있다.

##### NOT NULL 제약이 걸린 열을 추가할 때는 기본값을 지정해야 한다!

### 열 속성 변경
- `ALTER TABLE`로 열 속성을 변경할 경우에는 다음과 같이 `MODIFY 하부명령`을 실행한다.

**`열 속성 변경`**
```
ALTER TABLE 테이블명 MODIFY 열 정의
```

- 이때도 열 정의는 `CREATE TABLE`의 경우와 동일하다.
- `MODIFY`로 열 이름은 변경할 수 없지만, 자료형이나 기본값, `NOT NULL` 제약 등의 속성은 변경할 수 있다.

**`ALTER TABLE로 열 속성 변경하기`**
```
ALTER TABLE sample62 MODIFY newcol VARCHAR(20);
```

- 기존의 데이터 행이 존재하는 경우, 속성 변경에 따라 데이터 역시 변환된다.
- 이때 만약 자료형이 변경되면 테이블에 들어간 데이터의 자료형 역시 바뀐다.
- 다만 그 처리과정에서 에러가 발생하면 `ALTER TABLE` 명령은 실행되지 않는다.
- `ALTER TABLE`은 비교적 새로운 명령에 속한다. 표준화가 미처 이루어지지 않은 부분도 있어 데이터베이스에 따라 고유한 방언이 존재한다.
- 예를 들어 `MODIFY`는 `MySQL`과 `Oracle`에서 사용할 수 있는 `ALTER TABLE`의 하부명령이다. 다른 데이터베이스에서는 `ALTER` 하부명령으로 열 속성을 변경하기도 한다.

### 열 이름 변경
- `ALTER TABLE`로 열 이름을 변경할 때는 `CHANGE` 하부명령으로 시행할 수 있다.

**`열 이름 변경`**
```
ALTER TABLE 테이블명 CHANGE [기존 열 이름] [신규 열 정의]
```

- 열 이름을 변경할 때는 `MODIFY`가 아닌 `CHANGE`를 사용한다.
- `CHANGE`는 열 이름뿐만 아니라 열 속성도 변경할 수 있다.
- 한편, `Oracle`에서는 열 이름을 변경할 경우 `RENAME TO` 하부명령을 사용한다.

**`ALTER TABLE로 열 이름 변경하기`**
```
ALTER TABLE sample62 CHANGE newcol c VARCHAR(20);
```

### 열 삭제
- `ALTER TABLE`로 열을 삭제할 떄는 `DROP` 하부명령을 사용한다.

**`열 삭제`**
```
ALTER TABLE 테이블명 DROP 열명
```

- `DROP` 뒤에 삭제하고 싶은 열명을 지정한다. 물론, 테이블에 존재하지 않는 열이 지정되면 에러가 발생한다.

**`ALTER TABLE로 열 삭제하기`**
```
ALTER TABLE sample62 DROP c;
```

---

## 4. ALTER TABLE로 테이블 관리
여기서는 실제 업무에서 자주 사용하는 `ALTER TABLE`을 이용한 테이블 관리 예를 소개한다.

### 최대길이 연장
- 실제로 시스템을 운용하다 보면 처음에는 한 자리로 충분했던 용량이 시간이 지나면서 부족해지는 일이 많다.
- 이러한 경우 `ALTER TABLE`로 열의 자료형만 변경해 대응할 수 있다.
- 열의 자료형은 처음 `CREATE TABLE`을 실행할 때 결정된다.
- 특히 문자열형의 경우 최대길이를 지정하는데, 이 최대길이를 `ALTER TABLE`로 늘릴 수 있다.

`ALTER TABLE sample MODIFY col VARCHAR(30)`

- 반대로 저장공간을 늘리기 위해 최대길이를 줄이고 싶은 경우도 있을 것이다. 다만, 이때는 여러 가지 문제가 발생한다.
- 먼저 기존의 행에 존재하는 데이터의 길이보다 작게 지정할 수는 없다.
- 작게 지정하면 저장된 데이터의 일부가 잘려나가므로 에러가 발생하기 때문이다.
- 또한 열의 최대길이를 줄였다고 해서 실제 저장공간이 늘어나는 경우도 적다.
- 일반적으로 최대길이를 늘리는 경우는 많지만 줄이는 경우는 별로 없다.

### 열 추가
- 테이블에 열을 추가하는 일은 자주 일어난다.
- 시스템의 기능 확장 등 이유는 여러 가지가 있는데, 이때 사용하는 `ALTER TABLE` 명령은 다음과 같다.

`ALTER TABLE sample ADD new_col INTEGER`

- 보통 열을 추가하는 정도로는 시스템 쪽에 미치는 영향이 적을 것 같지만, 테이블 정의가 바뀌어버리는 일인 만큼 꽤 영향을 준다.
- 적어도, 변경한 테이블에 행을 추가하는 `INSERT` 명령은 확인해야 한다.
- 열을 추가하면 해당 열에 대해 데이터 값을 지정해야 하기 때문이다.
- 기존 시스템에서 추가한 열에 대해서는 별다른 처리를 하지 않아도 문제없다 해도 일단은 확인하는 편이 낫다.
- 만약 기존 시스템의 `INSERT` 명령에서 열 지정이 생략되어 있다면, 열을 추가한 후 그대로 실행했을 때 열의 개수가 맞지 않아 에러가 발생한다.

---