지금까지는 이미 있는 테이블의 데이터를 다뤘어요. 이번 장은 데이터가 아니라 테이블 그 자체(틀)를 만들고·바꾸고·지우는 DDL이에요. 그리고 잘못된 데이터가 못 들어오게 막는 제약조건까지 배웁니다.
CREATE TABLE로 열 이름·자료형·제약을 지정해 테이블을 만들 수 있어요.DROP TABLE(테이블 삭제)과 DELETE(행 삭제)의 차이를 설명해요.지금까지 배운 SELECT·INSERT·UPDATE·DELETE는 이미 만들어진 테이블 안의 데이터를 다뤘어요. 그런데 그 테이블은 누가, 어떻게 만들었을까요? 바로 DDL(Data Definition Language)이에요. DDL은 테이블이라는 틀 자체를 만들고·바꾸고·지우는 명령어 갈래예요.
| 명령어 | 하는 일 | 비유 |
|---|---|---|
CREATE TABLE | 새 테이블(틀)을 만든다 | 빈 표 양식을 새로 그림 |
ALTER TABLE | 기존 테이블 구조를 바꾼다 | 양식에 칸을 추가·수정 |
DROP TABLE | 테이블 자체를 없앤다 | 표 양식을 통째로 폐기 |
CREATE TABLE은 테이블 이름을 정하고, 괄호 안에 열마다 "이름 자료형 [제약]"을 쉼표로 나열해요.
INT는 정수만, VARCHAR는 문자열만 담을 수 있어요. 정해둔 종류와 안 맞는 값(예: 숫자 칸에 글자)은 저장이 거부돼요.CREATE TABLE users (
id INT PRIMARY KEY, -- 열 이름 + 자료형 + 제약
name VARCHAR(50) NOT NULL, -- 최대 50자, 빈 값 금지
age INT -- 자료형만 (제약 없음)
);
각 줄은 ① 열 이름 → ② 자료형 → ③ 제약조건(선택) 순서예요. 대표적인 자료형은 다음과 같아요.
| 자료형 | 저장하는 것 | 예시 값 |
|---|---|---|
INT | 정수 | 1, 42, -7 |
VARCHAR(n) | 가변 길이 문자열 (최대 n자) | '철수', 'a@b.com' |
CHAR(n) | 고정 길이 문자열 (항상 n자) | 'M', 'KR' |
DATE | 날짜 | '2026-07-07' |
DECIMAL(p,s) | 정확한 소수 (금액 등) | 1500.50 |
'철수'를 넣으면 딱 그만큼만 써요. 이름·이메일처럼 길이가 들쭉날쭉한 값에 알맞아요.'KR')처럼 길이가 일정한 값에 써요.
☕ 자바의 String과 비슷하지만, DB에서는 최대 길이를 미리 정해둔다는 점이 달라요.
email VARCHAR(100) NOT NULL UNIQUE는 "빈 값 금지 + 중복 금지"를 동시에 건 거예요.제약조건(constraint)은 열에 규칙을 걸어, 규칙에 어긋나는 데이터가 저장되지 못하게 막아요. 데이터의 정확성·일관성을 DB가 대신 지켜주는 셈이에요.
| 제약 | 의미 | 깨지는 예 |
|---|---|---|
PRIMARY KEY | 행을 고유하게 식별하는 열. 유일 + NOT NULL을 동시에 보장 | 같은 id가 두 번 / id가 비어 있음 |
NOT NULL | 빈 값(NULL) 금지 — 반드시 값이 있어야 함 | name 없이 행을 넣으려 함 |
UNIQUE | 그 열의 값이 중복되면 안 됨 (단, 비어 있는 건 허용) | 이미 있는 email을 또 넣음 |
DEFAULT | 값을 안 주면 넣어줄 기본값 | (막는 게 아니라 자동 채움) |
CHECK | 값이 조건을 만족해야 함 | age < 0 같은 값을 막음 |
CREATE TABLE members (
id INT PRIMARY KEY, -- 유일 + NOT NULL
email VARCHAR(100) NOT NULL UNIQUE, -- 빈 값 금지 + 중복 금지
grade VARCHAR(10) DEFAULT 'BRONZE', -- 안 주면 'BRONZE'
age INT CHECK (age >= 0) -- 음수 나이 차단
);
id는 PRIMARY KEY로, email은 (기본키는 아니지만 중복은 곤란하니) UNIQUE로 거는 조합이 흔해요.
NULL은 "값이 아직 없음/모름"을 뜻하는 특별한 상태예요. NOT NULL은 바로 그 빈 상태를 금지해서, "이 열은 반드시 채워라"라고 강제하는 제약이에요.외래 키(FOREIGN KEY)는 한 테이블의 열이 다른 테이블의 기본 키(PK)를 참조하도록 걸어, 두 테이블을 연결하는 제약이에요. 예를 들어 orders(주문) 테이블의 user_id가 users 테이블의 id를 참조하게 하면, 실제로 존재하는 사용자의 주문만 허용돼요.
| id (PK) | name |
|---|---|
| 1 | '철수' |
| 2 | '영희' |
| id (PK) | user_id (FK) | item |
|---|---|---|
| 101 | 1 | '키보드' |
| 102 | 2 | '마우스' |
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
item VARCHAR(50),
FOREIGN KEY (user_id) REFERENCES users(id) -- users.id를 참조
);
user_id = 99인 사용자가 users에 없다면, 그 주문 INSERT는 거부돼요.Order가 User를 참조(reference)하는 것과 비슷해요. 다만 DB에서는 그 참조가 실제 존재하는 행을 가리키도록 강제한다는 점이 핵심이에요.ALTER TABLE은 이미 만든 테이블의 구조를 변경해요. 열을 추가·삭제하거나 이름을 바꿀 수 있어요.
ALTER TABLE users ADD COLUMN email VARCHAR(100); -- 열 추가
ALTER TABLE users DROP COLUMN age; -- 열 삭제
DROP TABLE은 테이블 자체를 통째로 삭제해요. 데이터는 물론 구조(틀)까지 사라져요.
DROP TABLE users; -- users 테이블이 통째로 없어짐 (구조 + 데이터)
INSERT할 수 있어요.CREATE부터 해야 해요.
한 줄 정리: DELETE = 표 안의 줄을 지움 / DROP = 표 양식을 폐기. DROP은 되돌리기 어려우니 특히 조심하세요.
TRUNCATE TABLE users;도 있어요. 구조는 남기고 데이터만 전부 지운다는 점에서 결과는 DELETE와 비슷하지만, 훨씬 빠르고 되돌리기 어렵다는 차이가 있어요.CREATE·ALTER·DROP)은 대개 자동 커밋(실행하자마자 자동으로 확정·저장되는 것 — 커밋은 CH 10에서 배워요)되어 즉시 반영되고, DELETE처럼 롤백으로 되돌리기가 어렵습니다. 특히 DROP TABLE은 실행 전에 한 번 더 확인하는 습관을 들이세요.INT·VARCHAR(n)·CHAR·DATE·DECIMAL …)