3-6 연습 문제 — CREATE TABLE 을
읽고 검토합니다
오늘도 문법을 외우게 하지 않습니다. 대신 이미 만들어진 CREATE TABLE 을 읽고 — 무엇을 정하고 있는지, 순서가 맞는지, 빠진 규칙은 없는지 찾아내는 연습을 합니다. AI 가 만든 테이블을 검토하는 일이 바로 이 작업이에요.
섹션 3 에서의 위치
완료 ✓
강의 완료 ✓
지금 여기
ALTER · DROP
2-4에서 만든 AI 과외 선생님 세션을 그대로 쓰세요. 다만 이번엔 특히 조심해야 합니다 — “이 CREATE TABLE 고쳐줘” 라고 하면 AI 가 답을 다 만들어버려서 검토 연습이 사라집니다. 대신 기준을 물어보세요. “CREATE TABLE 을 검토할 때 놓치기 쉬운 항목이 뭐야? 답은 알려주지 말고 항목만.” 다 푼 뒤에 내가 찾은 문제 목록을 붙여넣고 빠진 게 있는지 확인받는 게 가장 남습니다.
문제 1. 이 CREATE TABLE 은 무엇을 정하고 있나요
아래는 우리 shop DB 의 orders 테이블을 만든 실제 문장입니다.
CREATE TABLE orders (
order_id INT NOT NULL AUTO_INCREMENT,
member_id INT NOT NULL,
ordered_at DATE NOT NULL,
PRIMARY KEY (order_id),
CONSTRAINT fk_orders_member
FOREIGN KEY (member_id) REFERENCES members(member_id)
);강의에서 배운 다섯 가지 체크리스트 항목별로 이 문장이 무엇을 정하고 있는지 답해보세요.
| # | 확인 항목 | 이 문장에서는? |
|---|---|---|
| ① | 테이블 이름 | ? |
| ② | 컬럼과 타입 | ? |
| ③ | 필수값과 기본값 | ? |
| ④ | 기본키 | ? |
| ⑤ | 외래키 | ? |
각 컬럼 줄은 왼쪽부터 이름 → 타입 → 규칙 순서로 읽습니다. 괄호 안 마지막
두 덩어리(PRIMARY KEY · FOREIGN KEY)는 컬럼이 아니라 규칙 선언이에요.
정답 보기
| # | 확인 항목 | 이 문장에서는 |
|---|---|---|
| ① | 테이블 이름 | orders — 주문을 담는 표 |
| ② | 컬럼과 타입 | order_id INT · member_id INT · ordered_at DATE |
| ③ | 필수값과 기본값 | 세 컬럼 모두 NOT NULL, DEFAULT 는 설정된 것이 없음 |
| ④ | 기본키 | order_id — 주문 하나를 정확히 가리키는 값 |
| ⑤ | 외래키 | member_id 가 members 의 member_id 를 참조 |
②에서 ordered_at DATE 가 핵심입니다. 주문일을 VARCHAR 가 아니라 DATE 로 담았기 때문에 2025-13-40 같은 없는 날짜가 들어올 수 없고, 두 날짜의 순서와 간격을 계산할 수 있습니다 (3-3 복습).
③의 NOT NULL 세 개도 의미가 있습니다. 회원이 누구인지 모르는 주문, 언제 들어왔는지 모르는 주문은 애초에 저장되지 못하게 막아둔 거예요.
⑤가 3-5 에서 배운 연결입니다. 이 한 줄 덕분에 존재하지 않는 회원 번호로 주문을 만들 수 없습니다. 우리 shop 에는 회원 20명이 있고 20번 백서윤 님은 주문이 아직 없는데 — 반대로 21번 회원의 주문은 만들려고 해도 데이터베이스가 거부합니다.
보너스 — AUTO_INCREMENT 는 규칙이라기보다 편의 옵션입니다. 주문 번호를 사람이 직접 세지 않아도 1씩 자동으로 붙습니다.
문제 2. 만드는 순서를 정하세요
어떤 사람이 shop DB 를 처음부터 다시 만들려고 CREATE TABLE 문 다섯 개를 아래 순서로 실행했습니다.
| 실행 순서 | 만들려는 테이블 | 이 테이블이 참조하는 테이블 |
|---|---|---|
| 1번째 | order_items | orders · products |
| 2번째 | products | categories |
| 3번째 | orders | members |
| 4번째 | categories | 없음 |
| 5번째 | members | 없음 |
두 가지에 답해보세요.
- 1번째 문장이 왜 실패하는지 한 문장으로 설명하세요.
- 올바른 생성 순서로 다섯 테이블을 다시 배열하세요.
정답 보기
1. 왜 실패하는가
order_items 는 orders 와 products 를 외래키로 참조하는데, 그 두 테이블이 아직 존재하지 않기 때문입니다. 외래키는 참조할 부모 테이블이 먼저 있어야 걸 수 있어요. MySQL 은 이럴 때 Failed to open the referenced table 이라며 생성 자체를 거부합니다.
2. 올바른 순서
| 순서 | 테이블 | 참조하는 테이블 | 이 시점에 준비돼 있어야 할 것 |
|---|---|---|---|
| ① | members | 없음 | — |
| ② | categories | 없음 | — |
| ③ | products | categories | ② 완료 |
| ④ | orders | members | ① 완료 |
| ⑤ | order_items | orders · products | ③ ④ 완료 |
정답이 하나만 있는 건 아닙니다. members 와 categories 는 아무도 참조하지 않는 부모라서 둘의 순서는 바뀌어도 됩니다. products 와 orders 의 순서도 서로 바뀔 수 있고요. 반드시 지켜야 하는 건 이 관계뿐입니다.
categories가products보다 먼저members가orders보다 먼저orders와products가order_items보다 먼저
order_items 는 언제나 마지막입니다. 부모가 둘이니까요.
테이블 목록을 받으면 먼저 “누가 누구를 참조하나”를 그려보세요. 화살표를 받기만 하는 테이블이 먼저 만들어지고, 화살표를 보내는 테이블이 나중입니다.
문제 3 (도전). AI 가 만들어준 이 테이블, 어디가 잘못됐나요
상품 리뷰를 저장하고 싶어서 AI 에게 이렇게 부탁했습니다.
“회원이 상품에 남긴 리뷰를 저장할 테이블을 만들어줘. 리뷰 번호, 작성한 회원, 어떤 상품인지, 별점, 리뷰 내용, 작성일이 필요해.”
AI 가 이런 CREATE TABLE 을 만들어줬습니다.
CREATE TABLE reviews (
review_id INT,
member_phone INT,
product_id INT,
rating INT,
content VARCHAR(500),
written_at DATE,
CONSTRAINT fk_reviews_product
FOREIGN KEY (product_id) REFERENCES product(product_id)
);다섯 가지 체크리스트로 검토해서 문제점을 모두 찾아내세요. 모두 다섯 개가 있습니다.
reviews 테이블은 우리 shop 스키마에 없습니다. 검토 연습을 위해 만든
가상의 테이블이에요. 다만 리뷰가 연결돼야 할 members · products 는 실제
테이블입니다.
체크리스트를 순서대로 훑으세요 — 이름 · 컬럼과 타입 · 필수값 · 기본키 · 외래키. 특히 3-3(타입)과 3-5(외래키)에서 배운 내용을 떠올려 보세요.
정답 보기
| # | 문제 | 체크리스트 항목 | 복습할 강의 |
|---|---|---|---|
| ① | 기본키가 없다 | ④ 기본키 | 3-4 |
| ② | 작성자를 전화번호로, 그것도 INT 로 담았다 | ② 컬럼과 타입 | 3-3 |
| ③ | members 를 참조하는 외래키가 없다 | ⑤ 외래키 | 3-5 |
| ④ | 존재하지 않는 테이블 product 를 참조한다 | ⑤ 외래키 | 3-6 |
| ⑤ | 모든 컬럼에 NOT NULL 이 빠졌다 | ③ 필수값 | 3-2 |
① 기본키가 없습니다. review_id 컬럼은 있지만 PRIMARY KEY (review_id) 선언이 없어요. 이대로면 같은 리뷰가 두 번 들어가도 막지 못하고, “3번 리뷰만 수정해줘” 라고 정확히 가리킬 수도 없습니다. AUTO_INCREMENT 도 없어서 번호를 사람이 직접 챙겨야 하고요.
② member_phone INT — 두 겹으로 잘못됐습니다.
- 전화번호를
INT로 담으면 3-3 에서 봤듯 맨 앞의 0 이 사라집니다.01012345678이1012345678이 돼요. 하이픈이나 국가번호도 넣을 수 없고요. 계산할 값이 아니니 애초에 숫자 타입일 이유가 없습니다. - 더 큰 문제는 작성자를 전화번호로 식별한다는 설계입니다. 회원이 번호를 바꾸면 리뷰와 회원의 연결이 끊어져요. 회원을 가리킬 때는
members의 기본키인member_id를 써야 합니다 (3-4 · 3-5).
③ members 를 참조하는 외래키가 아예 없습니다. 요구사항에 “회원이 상품에 남긴 리뷰” 라고 했는데, 회원 쪽 연결이 통째로 빠졌어요.
④ REFERENCES product(product_id) — 그런 테이블은 없습니다. 우리 테이블 이름은 products 입니다. 단수·복수 하나 틀렸을 뿐이지만 이 문장은 실행 자체가 실패합니다. 참조하는 테이블 이름과 컬럼 이름이 실제로 존재하는지 는 체크리스트 ⑤번의 질문이었죠.
⑤ NOT NULL 이 하나도 없습니다. 별점 없는 리뷰, 내용이 빈 리뷰, 작성일을 모르는 리뷰가 전부 저장됩니다. 여섯 컬럼 모두 리뷰가 성립하려면 반드시 있어야 하는 값이에요.
고친 버전은 이렇습니다.
CREATE TABLE reviews (
review_id INT NOT NULL AUTO_INCREMENT,
member_id INT NOT NULL,
product_id INT NOT NULL,
rating INT NOT NULL,
content VARCHAR(500) NOT NULL,
written_at DATE NOT NULL,
PRIMARY KEY (review_id),
CONSTRAINT fk_reviews_member
FOREIGN KEY (member_id) REFERENCES members(member_id),
CONSTRAINT fk_reviews_product
FOREIGN KEY (product_id) REFERENCES products(product_id)
);마지막으로 생성 순서도 확인하세요. 이 테이블은 members 와 products 를 참조하므로 두 부모가 모두 만들어진 뒤에 실행해야 합니다.
AI 는 문법적으로 완벽해 보이는 SQL 을 아주 빠르게 만들어줍니다. 하지만 기본키를 빠뜨리고, 엉뚱한 컬럼으로 연결하고, 테이블 이름을 하나 틀립니다. 만드는 건 도구가 하고, 맞는지 확인하는 건 사람이 합니다.
다 풀었다면
낯선 CREATE TABLE 을 봤을 때 “이름 · 컬럼과 타입 · 필수값 · 기본키 · 외래키” 다섯 항목으로 자동으로 분해되고 — 빠진 항목이 눈에 걸린다면 오늘 목표는 달성입니다. 문법을 외웠는지는 중요하지 않습니다.
DBeaver 좌측 트리에서 shop → Tables → order_items 를 더블클릭한 뒤 아래쪽
DDL 탭을 열어보세요. 이 테이블을 만든 CREATE TABLE 문 전체가 그대로
나옵니다. 복합 기본키 PRIMARY KEY (order_id, product_id) 와 외래키 두 줄을
직접 확인해 보세요. products · orders 도 같은 방식으로 읽어보면 좋습니다.
이제 테이블을 만드는 문장을 읽을 수 있게 됐습니다. 그런데 이미 데이터가 쌓인 테이블에 컬럼을 하나 더 넣어야 한다면요? 잘못 만든 테이블을 없애려는데 다른 테이블이 그걸 참조하고 있다면요? 다음 강의에서 다룹니다.