프로젝트 과제 제출이 있어서 오늘은 처음으로 09~17시 실시간으로 zep 캠을 키고 프로젝트를 진행하였다.
이 과정을 블로그에 정리해간 걸 TIL에 써내려가면 좋을 것같아서 해보려한다!
프로젝트1. ERD 설계
우선 나는 ERD 설계가 처음이라 기초부터 공부해 나가보려 한다.
ChatGPT에게 ERD 설계 튜토리얼을 물어봤고, 이에 대해 공부해 나가며 과제를 진행해 나가보려고 한다.
과제조건은 간단하게 테이블 설계하고, 실선만 연결하면되는데
SQLD 시험준비하면서 erd 개념은 들은 적이 있어서 더 깊게 탐구하고,
dbdiagram.io를 사용해서 화살표로 연결하는 것 까지 해보고자한다.
ERD(Entity Relationship Diagram
: 데이터베이스 구조를 그림으로 표현한 설계도 ➡️ 프로젝트 전에 DB를 먼저 설계하는 단계!
- Entity : 테이블
- Attribute : 칼럼
- Relationship : 테이블 간 관게
1️⃣ 주제부터 명확히 정하기
기능 중심이 아니라, 데이터 중심으로 생각해야하기 때문에 "무슨 데이터가 필요한지" 를 정해야함.
이 과제에서는 사이트 화면이 주어지고, 그 화면에서 데이터를 뽑아내서 만들어 내는 거였기 때문에, 이는 정해져 있다 생각해도 무방했다.
1️⃣ 각 엔터티의 속성 구하기
- PK(Primary Key) 무조건 필요
- 하나의 컬럼에는 하나의 값만
- 배열/리스트 형태 X
[메인 페이지]
공연 - 공연이미지 / 공연 날짜 / 공연명 / 공연 가격
[공연1 상세 페이지]
공연1 - 공연이미지 / 공연 날짜 / 공연명 / 공연 가격 / 수량? / 공연 소개
[로그인]
사용자 - 이메일 / 비밀번호
[회원가입]
사용자 - 이메일 / 비밀번호 / 이름
[주문 내역]
예매 번호 / 예매 일자 / 예매자 이름, 예매자 이메일 / 예매 수량 / 총 예매 가격
우선 사이트에서 필요한 데이터를 나열해보았다.
우선 확실한건 공연 / 사용자로 테이블 2개는 꼭 나올 것같고,
고민인 건 주문내역이나 상세페이지 같은 경우에 테이블을 또 만들어놔야하나? 이다.. 약간 감이 안와서 힌트를 요청했다.
테이블을 만드는 기준
1. DB에 저장돼야 하나?
2. 나중에 다시 써야 하나?
3. 여러 개가 쌓일 수 있나?
👉 3개 중 2개 이상 YES면 테이블 후보
오 이렇게 생각하니까 감이 오기 시작했다!
- 우선 메인페이지 / 공연 상세 페이지는 그냥 공연 정보 테이블을 뿌리면 될 것같고
- 로그인도 새롭게 쌓이는게 없으니까 테이블 하나,
- 그런데 주문내역이 중요!! 사용자가 구매한 공연 정보를 저장해야하고 / 나중에 다시 써야하고 / 여러개가 쌓일 수 있다!
그럼
우선 user / 공연정보 / 주문정보
이렇게 3개의 테이블을 만들자.

헉스. 벌써 뭔가 대단한 거 한느낌?
근데 그냥 막 적는 것보다도 서로 연결을 동시에 하면서 생각나는 대로 수정하는게 편했던 것같다.
예를 들어 order화면에서 예매자 이름, 예매자 이메일을 출력해야됐어서 order 테이블 안에서도 이 두가지가 있어야된다고 생각했는데,
이 테이블을 user과 연결하기 위해서는 독립적인 PK인 user_id로 연결하는게 맞았다.
안그래도 지피티가 다음 단계로 관계 연결을 추천했다
4️⃣ 관계(Relationship) 연결하기
1. A 하나에 B 여러 개 가능?
2. B 하나에 A 여러 개 가능?
3. 중간 테이블 필요한가?
👉 그래서 게시글에 user_id
👉 댓글에 user_id, post_id
예시를 보니까 더 확 와닿았다. 댓글 같은게 있으면 erd가 연결이 길어져서 확실히 복잡해질 수 있겠다 싶었다.
내가 봤을 때는 지금까지 한 것이 괜찮은 것같아서, GPT에게 정답을 알려주지 말고 생각할 수 있는 피드백을 부탁했다.
"현재 상태에서는 order테이블이 주문내역의 전체를 하나로 가지고 있어서, order 테이블이 너무 많은 걸책임지고 있다" 는 걸 알 수 있었다. 또한 이렇게 가면 한 주문에서 공연을 두개 이상 예매가 불가능하다.
👉🏻
그래서 주문의 개념을 분해해서 주문 자체 / 주문에 포함된
order는 “주문 1건”만 표현하고 공연 정보는 따로 분리하는 게 더 좋은 설계다.
1. 현재 나의 order
- 누가 샀는지
- 언제 샀는지
- 총 얼마인지
- 주문번호
=> 하나의 주문만 가능
2. order을 간단하게 떼어냄
- 어떤 공연을
- 몇장
- 얼마에
=> order을 여러개 합쳐서 가져와서 한번에 주문할 수 있음
그리하여 2번을 order_detail로 두고 전체주문내역을 orders 테이블로 또 하나 두었다.

그리하여 나온 두번째 버전..
그런데 솔직히 id 관계가 감이 안와서 확신을 가지지는 못했다.
역시나 order_detail에 order의 FK가 있어야한다는 피드백을 받았다.
“1:N 관계에서
N 쪽 테이블에는
반드시 1 쪽의 FK가 있어야 한다."
테이블이 여러개가 될 수 있는 관계에서는 여러개가 될 수 있는 테이블에 상위 테이블의 FK가 꼭 있어야한다는 것이다.
자식이, 부모를 알고있어야된다는 말이다.
주문 = 책 / 주문 상세 = 책의 페이지라고 할 때,
지금 구조는
책에 페이지번호 가 있고,
페이지에 어느 책인지 정보가 없는 것!!
그리고 이 시점에서 과제제출 파일의 예시 ERD를 다시 확인했는데, 공연이미지처럼 파일인 것은 따로 테이블을 마련하는 것같아서 이점도 알아봤다.
파일 저장방법
이미지와 같은 '파일' 자체는 보통 DB 테이블에 저장하지 않는다.
대신 파일에 대한 “정보(메타데이터)”만 테이블로 만든다.
이미지는 보통 용량 큼 / 수정 거의 없음 / 조회는 자주 됨
=> 그런데 DB는 대용량 파일 스트리밍 / 이미지를 직접 제공하는 걸 어려워함
👉 파일 저장소 + DB 분리
예외적으로 아이콘/ 작은 썸네일 등만 DB에 넣음
그리하여!!! 완성한 ERD!!
최종!

// Use DBML to define your database structure
// Docs: https://dbml.dbdiagram.io/docs
Table user {
id varchar [primary key]
email varchar
username varchar
password varchar
}
Table shows {
id varchar [primary key]
name varchar
description varchar
show_at timestamp
price integer
}
Table show_img {
id varchar [primary key]
show_id varchar [not null]
path varchar
}
Table orders {
id varchar [primary key]
user_id varchar [not null]
total_price integer
order_at timestamp
}
Table order_detail {
id varchar [primary key]
order_quantity integer
show_id varchar [not null]
order_id varchar [not null]
}
Ref: "user"."id" < "orders"."user_id"
Ref: "shows"."id" < "order_detail"."show_id"
Ref: "order_detail"."order_id" < "orders"."user_id"
Ref: "show_img"."show_id" < "shows"."id"
공연의 이미지는 여러개 일 수도 있을 것같아서 아까 배운거 바로 생각해서 show_id로 부모 테이블을 연결해줬다! 우하하 사실 과제파일에서 제시된 예시랑 너무 똑같긴한 거같은데,, 배운게 확실하게 있으니까 !! 뿌듯하구만
- 그리고 show와 order은 SQL 예약어로, 오류가 발생해서 shows와 orders로 수정하였다.
실제 SQL 실습
데이터베이스 생성
ShowTicketing을 이름으로 한 데이터베이스 생성

데이터베이스 입장
USE ShowTicketing
테이블 생성
CREATE TABLE user (
id VARCHAR(30) PRIMARY KEY,
email VARCHAR(30),
username VARCHAR(30),
password VARCHAR(30)
);
CREATE TABLE show (
id VARCHAR(30) PRIMARY KEY,
name VARCHAR(30),
description VARCHAR(30),
show_at TIMESTAMP,
price INT
);
CREATE TABLE show_img (
id VARCHAR(30) PRIMARY KEY,
show_id VARCHAR(30),
path VARCHAR(30)
);
CREATE TABLE orders (
id VARCHAR(30) PRIMARY KEY,
user_id VARCHAR(30),
total_price INT,
order_at TIMESTAMP
);
CREATE TABLE order_detail (
id VARCHAR(30) PRIMARY KEY,
order_quantity INT,
show_id VARCHAR(30),
order_id VARCHAR(30)
);

컬럼 조회
SELECT * FROM shows;

테이블 전체 조회
컬럼 입력
INSERT INTO shows (id, name, description, show_at, price) VALUES ('show_006', '어쿠스틱 라이브', '잔잔한 어쿠스틱 무대 공연', '2026-05-10 19:30:00', 40000);

'show_006', '어쿠스틱 라이브', '잔잔한 어쿠스틱 무대 공연', '2026-05-10 19:30:00', 40000 값 입력
컬럼 수정
UPDATE shows SET name = '어쿠스틱 스페셜 라이브',price = 48000 WHERE id = 'show_006';

id가 show_006인 값의 name과 price 수정
조건에 따른 컬럼 조회
SELECT * FROM shows WHERE price >= 50000;

가격이 50000원보다 비싼 값을 조회
'Devcourse' 카테고리의 다른 글
| <프로그래머스 데브코스 풀스택> 1차 역량평가 준비 (0) | 2026.01.20 |
|---|---|
| <프로그래머스 데브코스 풀스택>2026-01-19 TIL (0) | 2026.01.19 |
| [프로그래머스 데브코스 풀스택] 2026-01-14 TIL(1) node.js / npm (0) | 2026.01.14 |
| <프로그래머스 데브코스 풀스택>2026-01-13 TIL (0) | 2026.01.13 |
| <프로그래머스 데브코스 풀스택> 2026-01-12 TIL Docker / MariaDB / SQL 기초 (1) | 2026.01.12 |