테이블 직접 만들기
CREATE TABLE
먼저 솔직하게 말씀드립니다 — 이번 강의는 문법을 외우는 시간이 아닙니다. AI 나 DBeaver 가 대신 만들어줄 수 있으니까요. 대신 그렇게 만들어진 테이블이 내가 원한 구조가 맞는지 읽고 확인하는 힘을 기르는 시간입니다.
이번 섹션의 여정
완료 ✓
완료 ✓
지금 여기
ALTER · DROP
문법을 전부 외울 필요는 없습니다
강의를 시작하기 전에 솔직하게 말씀드릴 게 있습니다. DDL 문법을 전부 외울 필요는 없습니다.
저도 AI 가 없던 시절부터 이런 문법을 모두 외우지 않았어요. 필요할 때마다 찾아서 썼습니다. 지금은 더 편해졌습니다 — AI 에게 원하는 테이블을 설명해서 SQL 을 만들 수도 있고, DBeaver 같은 화면에서 클릭만으로 테이블을 생성할 수도 있어요.
반복 작업이나 대규모 변경이 아니라면, 긴 DDL 을 처음부터 직접 타이핑할 일은 생각보다 많지 않습니다.
문법 통암기괄호 위치와 키워드 순서를 외우기
백지에서 작성아무것도 안 보고 긴 DDL 을 쓰기
옵션 전부 암기모든 키워드를 다 알고 있기
읽기이 문장이 무엇을 정하는지 알아보기
검토AI·UI 가 만든 구조가 의도대로인지 확인
질문빠진 규칙이 없는지 스스로 짚어보기
만드는 건 도구가 대신 해줍니다 — 맞는지 확인하는 건 사람의 몫입니다.
CREATE TABLE 을 쓸 줄 아는 것이 아니라, CREATE TABLE 이 무엇을 정하는지 이해하는 것. 그래야 AI 가 만들어준 테이블을 보고 “이건 내가 원한 구조가 아닌데” 라고 말할 수 있습니다.
DDL — 데이터베이스의 구조를 만드는 명령
DDL은 테이블처럼 데이터베이스의 구조를 만들거나 바꾸는 명령을 말합니다. 그중 CREATE TABLE은 새로운 테이블을 만드는 명령이에요.
| 명령 | 하는 일 | 다루는 강의 |
|---|---|---|
| CREATE TABLE | 새 테이블을 만든다 | 3-6 (지금) |
| ALTER TABLE | 이미 있는 테이블의 구조를 바꾼다 | 3-7 |
| DROP TABLE | 테이블을 통째로 없앤다 | 3-7 |
여기서 중요한 지점 하나. CREATE TABLE은 빈 표만 만드는 명령이 아닙니다.
어떤 컬럼을 둘지, 그 컬럼에 어떤 값을 저장할지, 그리고 그 데이터가 지켜야 할 규칙까지 함께 정합니다. 지금까지 3-2 에서 배운 약속(NOT NULL · DEFAULT), 3-3 의 타입, 3-4 의 기본키, 3-5 의 외래키가 전부 이 한 문장 안에 들어갑니다.
CREATE TABLE 이 정하는 세 가지
첫 번째는 테이블 이름입니다. 무엇을 저장하는 테이블인지 이름만 봐도 알 수 있어야 해요. 상품을 담으면 products, 주문을 담으면 orders 처럼요.
두 번째는 컬럼의 이름과 데이터 타입입니다. 상품 번호는 정수, 상품 이름은 문자열 — 저장할 값에 맞는 타입을 정합니다. 3-3 에서 배운 “값에 맞는 그릇 고르기” 가 바로 여기서 결정돼요.
세 번째는 데이터 규칙입니다. 반드시 필요한 값에는 NOT NULL, 값을 생략했을 때 채워질 값이 필요하면 DEFAULT를 설정합니다. 각 행을 구별할 컬럼은 기본키로 정하고, 다른 테이블과 연결할 컬럼은 외래키로 정합니다.
실제 CREATE TABLE 을 한 줄씩 읽어봅니다
이제 우리 실습 DB 를 만든 진짜 문장을 보겠습니다. 외우려고 보지 마세요. 각 줄이 무엇을 정하는지 만 따라가면 됩니다.
가장 단순한 categories 부터 시작합니다.
CREATE TABLE categories (
category_id INT NOT NULL AUTO_INCREMENT,
category_name VARCHAR(50) NOT NULL,
PRIMARY KEY (category_id)
);| 이 줄은 | 이것을 정합니다 |
|---|---|
| CREATE TABLE categories ( | ① 테이블 이름 — 카테고리를 담는 표 |
| category_id INT NOT NULL AUTO_INCREMENT | ② 컬럼 이름 + 타입(정수) · ③ 필수값 · 번호 자동 부여 |
| category_name VARCHAR(50) NOT NULL | ② 최대 50자 문자열 + ③ 필수값 |
| PRIMARY KEY (category_id) | ③ 행을 구별하는 기준 — 기본키 |
읽는 방법은 간단합니다 — 왼쪽부터 이름 → 타입 → 규칙 순서예요. category_name VARCHAR(50) NOT NULL 은 “카테고리명이라는 칸을 두는데, 최대 50자 글자를 담고, 비워둘 수 없다” 는 뜻입니다.
이번엔 외래키가 붙은 products 입니다.
CREATE TABLE products (
product_id INT NOT NULL AUTO_INCREMENT,
product_name VARCHAR(100) NOT NULL,
price INT NOT NULL,
category_id INT NOT NULL,
PRIMARY KEY (product_id),
CONSTRAINT fk_products_category
FOREIGN KEY (category_id) REFERENCES categories(category_id)
);| 이 줄은 | 이것을 정합니다 |
|---|---|
| product_id INT NOT NULL AUTO_INCREMENT | 상품 번호 — 정수, 필수, 자동 증가 |
| product_name VARCHAR(100) NOT NULL | 상품명 — 최대 100자, 필수 |
| price INT NOT NULL | 가격 — 원 단위 정수, 필수 |
| category_id INT NOT NULL | 어느 카테고리인지 — 정수, 필수 |
| PRIMARY KEY (product_id) | 기본키 — 상품 하나를 정확히 가리키는 값 |
| FOREIGN KEY (category_id) REFERENCES categories(category_id) | 외래키 — categories 의 기본키를 가리킨다 |
맨 아랫줄이 3-5 에서 배운 외래키입니다. 영어를 그대로 읽으면 뜻이 나와요 — “category_id 라는 외래키는 categories 테이블의 category_id 를 참조한다.” 이 한 줄 덕분에 존재하지 않는 카테고리 번호를 상품에 적을 수 없게 됩니다.
실제 init.sql 에는 각 컬럼 뒤에 COMMENT '가격(원)' 같은 설명과, 맨 끝에
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 가 붙어 있습니다. 각각 컬럼 설명과
저장 방식·문자 인코딩 설정이에요. 구조를 읽는 데는 필요하지 않아서 위
예시에서는 덜어냈습니다 — 이런 것도 외울 대상이 아닙니다.
데이터 규칙 네 가지를 한 자리에서
지금까지 섹션 3 에서 하나씩 배운 규칙들이 CREATE TABLE 안에서 어떻게 쓰이는지 모아 봅니다.
| 규칙 | 뜻 | shop 에서는 | 배운 강의 |
|---|---|---|---|
| NOT NULL | 이 칸은 비울 수 없다 | products.product_name | 3-2 |
| DEFAULT | 생략하면 이 값이 저장된다 | 설정된 컬럼 없음 | 3-2 |
| PRIMARY KEY | 행을 구별하는 기준 | products.product_id | 3-4 |
| FOREIGN KEY | 다른 테이블의 기본키를 가리킨다 | products.category_id | 3-5 |
기본키를 구성하는 컬럼은 하나가 아닐 수도 있습니다. order_items 는 PRIMARY KEY (order_id, product_id) 처럼 두 컬럼이 함께 기본키 하나를 만드는 복합키를 씁니다 — 3-4 에서 짚었듯 기본키가 두 개인 게 아니에요. 한 주문에 같은 상품이 두 줄로 들어가지 못하게 막는 규칙이죠.
DEFAULT 는 우리 shop 스키마에서 실제로 쓰인 곳이 없습니다. 3-2 에서
나왔던 status DEFAULT '판매중' 은 개념 설명을 위한 가상의 컬럼이었어요. 지금
스키마에 있는 규칙은 NOT NULL · PRIMARY KEY · FOREIGN KEY 세 가지입니다.
연결된 테이블은 만드는 순서가 있습니다
외래키로 연결된 테이블은 만드는 순서도 중요합니다.
상품 테이블이 카테고리 테이블을 참조한다면 — categories 를 먼저 만들고 products 를 나중에 만듭니다. 외래키가 참조할 부모 테이블이 먼저 존재해야 하기 때문이에요.
순서를 거꾸로 하면 어떻게 될까요? 데이터베이스가 거절합니다.
우리 실습 데이터를 만든 init.sql 도 정확히 이 순서를 지키고 있습니다.
| 순서 | 테이블 | 누구를 참조하나 | 먼저 있어야 할 테이블 |
|---|---|---|---|
| ① | members | 없음 (부모) | — |
| ② | categories | 없음 (부모) | — |
| ③ | products | categories | categories |
| ④ | orders | members | members |
| ⑤ | order_items | orders · products | orders, products |
order_items 가 마지막인 이유가 보이시나요? 이 테이블은 orders 와 products 둘 다 참조하기 때문에, 두 부모가 모두 만들어진 뒤에야 생성될 수 있습니다.
부모 테이블을 먼저 만들고, 자식 테이블을 나중에 만듭니다. 참조할 대상이 없으면 외래키를 걸 수 없기 때문입니다.
AI 가 만들어준 테이블, 이 다섯 가지만 확인하세요
이제 처음 이야기로 돌아옵니다. CREATE TABLE 문법을 외우기보다 다섯 가지만 확인하세요.
각 항목을 이렇게 질문으로 바꿔 물어보면 검토가 훨씬 쉬워집니다.
| 항목 | 스스로에게 던질 질문 |
|---|---|
| 테이블 이름 | 이 표가 무엇을 저장하는지 이름만 보고 알 수 있나? |
| 컬럼과 타입 | 전화번호를 숫자로 담지는 않았나? 날짜를 글자로 담지는 않았나? |
| 필수값 | 이 값이 비어도 정말 괜찮은 컬럼인가? |
| 기본키 | 이 컬럼 값이 같으면 정말 같은 행이라고 할 수 있나? |
| 외래키 | 참조하는 테이블 이름과 컬럼 이름이 실제로 존재하나? |
AI 가 만들어준 CREATE TABLE 을 그대로 붙여넣고 — “이 문장이 정하는 걸 테이블
이름 · 컬럼과 타입 · 필수값 · 기본키 · 외래키 다섯 항목으로 정리해줘” 라고
요청해 보세요. 정리된 결과와 내가 원했던 구조를 비교하는 게 검토입니다.
AI 에게 정답을 맡기지 말고, 비교할 자료를 만들게 시키세요.
AI 나 UI 로 테이블을 만들더라도 — 이 다섯 가지가 의도한 대로 설정됐는지는 사람이 확인해야 합니다. 잘못 만들어진 구조는 나중에 데이터가 쌓인 뒤에 고치려면 훨씬 비싸지니까요.
한눈에 정리
| 확인 항목 | CREATE TABLE 의 어디를 보는가 | products 에서는 |
|---|---|---|
| 테이블 이름 | CREATE TABLE 바로 뒤 | products |
| 컬럼과 타입 | 괄호 안 각 줄의 앞 두 조각 | price INT |
| 필수값·기본값 | 타입 뒤의 NOT NULL · DEFAULT | product_name 은 NOT NULL |
| 기본키 | PRIMARY KEY (...) 줄 | PRIMARY KEY (product_id) |
| 외래키 | FOREIGN KEY ... REFERENCES 줄 | category_id 가 categories 를 참조 |
| 생성 순서 | 외래키가 가리키는 부모가 먼저 | categories 먼저, products 나중 |
문법은 찾으면 됩니다. 구조를 읽는 눈은 찾을 수 없습니다 — 그건 연습으로만 생깁니다.
그런데 이미 만들어 놓은 테이블에 컬럼을 하나 더 넣어야 한다면요? 아니면 잘못 만든 테이블을 아예 없애야 한다면요? 그 이야기가 다음 강의입니다.