데이터베이스가 처음인가요? 핵심만 보기로 읽고 실습을 마친 후 심화 섹션을 확인하세요.

ACE AI 스타트업 부트캠프 · Day 3 보충 가이드

데이터 정규화, ERD & 변경 영향도 분석
— 코드 한 줄 없이 이해하기

Day 1에서 화면을 그렸고, Day 2에서 흐름을 그렸습니다. 오늘은 두 영역 밑에 위치하는 데이터의 뼈대를 구축합니다. 세션 시작 전 15분 동안 읽고 실습 동안 곁에 두세요.

Day 3 한 문장 요약: 머릿속 서비스 아이디어를 나중에 서로 모순을 일으키지 않는 테이블 모음으로 변환하는 것.

00왜 이 학습이 필요한가요?

목적이 명확하지 않은 정규화는 암기해야 할 규칙에 불과합니다.

집을 짓는 과정에 비유해 봅시다.

코딩은 Day 6에 시작됩니다. 만약 그때 배선 도면이 틀려 있다면, 이미 만든 모든 화면과 API를 다시 허물어야 합니다. 10일 부트캠프에서 이는 치명적입니다. 오늘 이 작업을 수행하는 이유입니다.

오늘 완성할 3가지 산출물 ① 테이블 목록과 연결 관계 (ERD) · ② 온 팀이 합의하는 표준 용어 사전 · ③ 테이블 수정 시 영향을 받는 항목 목록.
다른 모든 개념(1NF/2NF/3NF, 관계 기호)은 이 3가지를 얻기 위한 도구입니다. 도구 자체를 외우기보다 3가지 산출물 완성에 집중하세요.

01병목 ①: 정규화 — "모든 것을 망치는 엑셀 시트 하나"

어려운 정의 대신 현실의 데이터 통증에서 출발해 봅시다.

1-0. 멀쩡해 보이는 엑셀 시트

온라인 강의 플랫폼을 만든다고 가정합시다. 처음에는 시트 하나로 모든 것을 기록합니다.

표 A. 수강 신청 시트 (첫날에는 완벽해 보임)
#수강생수강생 연락처수강 과목강사명강사 연락처수강료 (원)
1김철수010-1111-1111AI 기획, 데이터 분석이영희010-9999-99991,200,000
2박민수010-2222-2222AI 기획이영희010-9999-9999600,000
3김철수010-1111-1112프롬프트 엔지니어링최성민010-8888-8888900,000

이 시트는 이미 3가지 사고(이상 현상, Anomaly)를 예약해 두었습니다.

삽입 이상 (Insert Anomaly)

새 과목 "AI 윤리"를 개설했는데 아직 수강생이 없습니다. → 기록할 방법이 없습니다. 수강생이 없으면 행을 만들 수 없습니다.

수정 이상 (Update Anomaly)

김철수가 번호를 변경했습니다. → 김철수가 포함된 모든 행을 일일이 수정해야 합니다. 3행만 수정하면 1행과 불일치가 생깁니다. 어느 것이 진짜인가요?

삭제 이상 (Delete Anomaly)

박민수가 환불하여 2행을 삭제합니다. → "AI 기획"의 유일한 수강생 행이 지워지면서 과목 정보 자체가 함께 사라집니다.

정규화의 정의는…

한 시트를 목적별 전용 테이블로 분리하여 이 3가지 사고가 일어나지 않게 만드는 것입니다. 1NF/2NF/3NF는 테이블을 잘라내는 3단계 체크리스트입니다.

기억해야 할 단 하나의 원칙 "모든 사실은 단 한 곳에만 기록한다." — 같은 사실이 두 곳에 존재하는 순간 언젠가 불일치가 발생합니다. 1NF, 2NF, 3NF는 이 문장을 실천하기 위한 질문들입니다.

1-1. 1NF — "셀 하나에는 값 하나만"

확인할 질문: 쉼표로 여러 값을 구겨 넣은 셀이 있는가?

표 A에서 수강 과목: "AI 기획, 데이터 분석"이 바로 그 사례입니다. "AI 기획 수강생이 몇 명인가?"를 집계하려면 텍스트를 쪼개야 하므로 관리가 복잡해집니다.

해결책: 행을 분리합니다. 한 셀에 하나의 값만 넣습니다 (김철수 행을 2개로 분리).

기획자가 자주 하는 실수 태그, 관심 분야, 첨부파일 등을 한 셀에 A,B,C 형태로 넣는 것입니다. 기획 문서에서는 자연스러워 보이지만 대표적인 1NF 위반입니다. 둘 이상의 값을 가질 수 있는 항목은 별도 테이블로 분리합니다.

1-2. 2NF — "이름표 전체가 결정하는 정보만 남기기"

1NF 적용 후 각 행은 (수강생 + 과목)이라는 2 부분 조합 이름표(식별자)로 구분됩니다.

확인할 질문: 이 셀의 값을 결정할 때 이름표 두 쪽이 모두 필요한가, 아니면 한 쪽만 필요한가?

컬럼명값을 알기 위해 필요한 정보판단 결과
수강 신청일수강생 과목 — 둘 다 필요현재 테이블 유지
수강생 연락처수강생만 알면 됨 (과목 무관)분리 → 수강생 테이블로 이동
과목명 / 수강료과목만 알면 됨 (수강생 무관)분리 → 과목 테이블로 이동

2NF = "이름표 절반만으로 결정되는 컬럼은 그 절반을 따라 별도 테이블로 이동한다." 이 과정을 통해 수정 이상이 해결됩니다 (수강생 테이블에서 연락처를 한 번만 수정하면 끝).

1-3. 3NF — "옆 컬럼이 결정하는 정보는 따로 빼기"

분리된 과목 테이블을 봅시다: 과목ID, 과목명, 강사명, 강사연락처.

확인할 질문: 이 컬럼은 이름표(과목ID)가 결정하는가, 아니면 옆에 있는 다른 컬럼이 결정하는가?

해결책: 강사 테이블을 새로 만들고 과목 테이블에는 강사ID만 남겨둡니다.

3줄 요약 — 실습 때 이것만 기억하세요 1NF 한 셀에 값 하나만 (쉼표 목록 금지).
2NF 이름표 절반에 종속된 컬럼은 분리.
3NF 옆 컬럼에 종속된 정보는 분리.
비개발자 팀에게 3NF 달성은 완벽한 점수입니다. BCNF나 4NF까지 고민할 필요 없습니다.
Deep dive — 개발 경험이 있는 팀원을 위한 팁

정규화가 항상 정답일까요? 아닙니다. 정규화는 쓰기 일관성을 얻는 대신 읽기 성능을 일부 양보합니다. 5개 테이블로 쪼개면 화면 하나를 그릴 때 5번의 JOIN이 발생합니다.

02병목 ②: ERD & 카디널리티 — "테이블 노선도"

기호 자체는 어렵지 않습니다. 어떤 기호를 선택해야 할지 결정하는 기준을 배우는 것이 핵심입니다.

2-1. ERD는 지하철 노선도입니다

ERD (Entity Relationship Diagram)란 쉽게 말해 "무엇이 존재하고 어떻게 연결되어 있는지 보여주는 그림"입니다.

2-2. 관계 수량성 결정법: 양방향으로 2번 질문하기

이 두 문장을 소리 내어 말해보세요 ① "수강생 1명과목을 몇 개 수강할 수 있는가?" → 여러 개(Many)
② "과목 1개에는 수강생이 몇 명 들어올 수 있는가?" → 여러 명(Many)
양쪽 모두 "여러 개" → N:M. 한쪽만 "여러 개" → 1:N. 둘 다 "1개" → 1:1. 이것이 판단 기준의 전부입니다.
종류읽는 법예시실제 구현 방식
1:1일대일사용자 ↔ 프로필 상세보통 한 테이블로 합칩니다. 분리한다면 이유를 기록하세요.
1:N일대다 (가장 흔함)강사 1명 → 과목 여러 개"1" 쪽의 ID를 "N" 쪽 테이블에 넣습니다 (과목 테이블에 강사ID 보관).
N:M다대다수강생 ↔ 과목DB에 직접 존재할 수 없습니다. 아래 내용을 참조하세요.
Day 3 최대 함정 — N:M 관계는 물리적으로 존재할 수 없음 "수강생 ↔ 과목"은 테이블 2개만으로 표현 불가능합니다. 수강생에 과목ID를 넣자니 여러 개고, 과목에 수강생ID를 넣자니 역시 여러 개입니다.
해결책: 관계 자체가 세 번째 테이블을 탄생시킵니다. 이를 연결 테이블(Junction Table)이라 부르며, 여기서는 수강신청(ENROLMENT) 테이블이 됩니다.
연결 테이블은 단순 접착제가 아니라 관계 자체의 데이터(수강 신청일, 결제 상태, 진도율 등)가 저장되는 곳입니다. 이를 놓치면 데이터가 갈 곳을 잃고 정규화가 무너집니다.
erDiagram INSTRUCTOR ||--o{ COURSE : "teaches (1:N)" STUDENT ||--o{ ENROLMENT : "enrols in (1:N)" COURSE ||--o{ ENROLMENT : "contains (1:N)" INSTRUCTOR { int instructor_id PK "instructor ID" string name "full name" string phone "phone" } COURSE { int course_id PK "course ID" string title "course title" int price "fee" int instructor_id FK "who teaches it" } STUDENT { int student_id PK "student ID" string name "full name" string phone "phone" } ENROLMENT { int enrolment_id PK "enrolment ID" int student_id FK "who" int course_id FK "what" date applied_at "when" string pay_status "payment status" }

↑ 1개의 엑셀 시트가 4개의 정규화된 테이블로 분리되었습니다. 수강생-과목 N:M 관계가 수강신청 연결 테이블을 통해 1:N 2개로 풀린 점에 주목하세요.

2-3. 기호 읽는 법 (Crow's Foot 까마귀 발 표기법)

기호의미Mermaid 표기
||정확히 1개 (필수)||--||
o| / |o0개 또는 1개 (선택)|o--||
o{ (까마귀 발)0개 이상 (선택)||--o{
|{1개 이상 (필수)||--|{

작은 동그라미는 "비어있어도 됨(선택)"을 의미합니다. 강사가 과목을 아직 배정받지 않아도 존재할 수 있다면 ||--o{를 씁니다. 반드시 최소 1개 이상 가져야 한다면 ||--|{를 씁니다. 이 차이가 나중에 "필수 입력 항목인가?" 규칙이 됩니다.

2-4. 외래키(FK) & 참조 무결성 — "존재하지 않는 고객의 주문은 불가능하다"

오늘 팀이 결정해야 할 사항: "사용자가 계정을 탈퇴(삭제)할 때 관련 수강/결제 기록도 삭제할 것인가, 보존할 것인가?" — 이는 기술이 아닌 비즈니스 정책 문제입니다. 환불, 정산, 리포팅이 이 결정에 달려있으므로 기획자와 팀이 직접 결정해야 합니다.

Deep dive

데이터베이스는 3가지 삭제 옵션을 제공합니다: CASCADE (자식 데이터도 연쇄 삭제) / RESTRICT (자식 데이터가 있으면 삭제 거부) / SET NULL (연결만 끊고 기록 보존). 실제 서비스에서는 대부분 실제 삭제(Hard Delete)를 하지 않고 deleted_at 컬럼을 사용하는 논리 삭제(Soft Delete)를 적용합니다. 개인정보 보호법(파기 의무)과 거래 이력 보존 의무 간의 균형을 고려하여 탈퇴 시 익명화 처리할 항목과 보존할 항목을 결정하고 기록하세요.

03병목 ③: 변경 영향도 분석 — "아직 만든 것도 없는데 왜 분석하나요?"

아직 존재하지 않는 코드가 깨질 것을 상상해야 해서 어렵게 느껴집니다.

Schema (스키마) = 테이블 청사진. 어떤 컬럼이 존재하고 무슨 타입인지 정의한 데이터의 헌법입니다.

영향도 분석은 예측이 아니라 지도 읽기입니다. 한 컬럼에서 출발하여 연결선을 따라 "이 변경이 여기까지 미치는가?"를 확인하는 과정입니다.

3-1. 컬럼 하나 변경이 일으키는 도미노 효과

flowchart TD A[DB 컬럼명 변경
phone → mobile] --> B[API 응답 필드
phone 필드 소멸] B --> C[UI 컴포넌트
연락처 화면 공백 발생] B --> D[API 명세서
문서 불일치 발생] A --> E[기존 저장 데이터
마이그레이션 필요] A --> F[팀 용어 체계
용어 혼선 발생] style A fill:#fdeceb,stroke:#9b2c2c style E fill:#fdf6e3,stroke:#8a6d1c style F fill:#fdf6e3,stroke:#8a6d1c

↑ 컬럼 이름 하나 바꾸었을 뿐인데 최소 5곳이 흔들립니다. 그중 3곳은 코드가 아닌 문서와 사람입니다.

이 도미노 현상이 바로 "Task 02(용어 표준화)가 왜 중요한가?"에 대한 답입니다. 처음에 용어를 통일해 두면 이 도미노 현상 자체가 발생하지 않습니다. 용어 사전 정립은 가장 저렴하게 가입하는 보험입니다.

3-2. 변경 위험도 3단계 평가

등급변경 작업 내용이유조치 사항
안전 (Safe)선택(Null 허용) 컬럼 추가기존 코드가 새 컬럼의 존재를 몰라도 무시하므로 영향 없음즉시 진행 가능
주의 (Caution)컬럼명 변경, 필수(NotNull) 컬럼 추가읽기 코드가 전부 깨지며, 기존 행에 채울 기본값이 필요함영향도 목록 작성 후 진행
위험 (Dangerous)컬럼 삭제, 데이터 타입 변경, 테이블 분리비가역적. 실제 데이터가 소멸하거나 유실될 위험이 큼백업 + 전체 팀 합의 + 의사결정록 작성

3-3. 변경 영향도 보고서 템플릿

Task 03 산출물로 아래 표 형식을 그대로 활용할 수 있습니다.

변경 항목위험 등급영향받는 API영향받는 화면 UI기존 데이터 조치최종 의사결정 / 대안
USER.phone → mobile주의GET /users, POST /signup마이페이지, 회원가입 폼데이터 복사 후 기존 컬럼 2주간 유지즉시 삭제 대신 당분간 양쪽 병행 유지 선택
ENROLMENT에 pay_status 추가안전GET /enrolments내 수강 목록기본값 'pending' 적용원안대로 진행
막혔을 때 따라 하는 5단계 점검 순서어느 화면에 이 컬럼이 나오는가? → ② 어느 API가 그 화면에 데이터를 주는가? → ③ Day 4 API 명세서에는 어떻게 적혀있는가? → ④ 이미 저장된 데이터는 어떻게 처리하는가? → ⑤ 팀원 중에 이 항목을 다른 이름으로 부르는 사람이 있는가?

04Codex AI 효율적인 활용 프롬프트

오늘 AI는 DB 설계자가 아니라 까칠한 검토자입니다. AI 답을 검증 없이 복사하면 왜 그것이 맞는지 배울 수 없습니다.

나쁜 프롬프트

"우리 서비스 데이터베이스 설계해 줘."

맥락이 없어 뻔한 답변만 나오며, 설명할 수 없는 ERD를 얻게 됩니다.

좋은 프롬프트

"이 회의록에서 엔티티 후보를 추출하고, 각각 독립 테이블이 되어야 하는 이유를 근거와 함께 제시해 줘. 모호한 부분은 모호하다고 밝혀줘."

실습에 바로 사용하는 5가지 프롬프트

  1. [Task 01] "이 회의록에서 엔티티 및 속성 후보를 도출해 줘. '독립적으로 수량을 세고 관리할 수 있는가?'를 기준 삼아 실제 엔티티인지 단순 속성인지 타당성을 평가해 줘."
  2. [Task 01] "이 ERD 구조에서 N:M 관계를 모두 찾아줘. 각 N:M 관계별로 필요한 연결 테이블(Junction Table)과 관계 자체에 속해야 할 속성을 제안해 줘."
  3. [Task 01] "우리 테이블 구조를 1NF, 2NF, 3NF 관점에서 각각 평가해 줘. 위반 요소가 있다면 원인이 되는 함수 종속성을 지적해 줘. 수정하지 말고 진단만 해줘."
  4. [Task 02] "이 컬럼명 목록에서 의미는 같으나 표기가 다른 용어 그룹(user_name / userName / customer 등)을 묶어줘. 각 그룹별로 대표 표준 용어를 제안하고 이유를 설명해 줘."
  5. [Mission 02] "이 스키마 구조에서 참조 무결성이 깨질 수 있는 시나리오 3가지두 사용자가 동시에 같은 데이터를 수정할 때(동시성 충돌) 발생하는 문제 3가지를 찾아줘. 서비스 맥락은 ___이야."
AI가 자주 틀리는 3가지 포인트 · 회의록에 없던 컬럼(created_at, is_active 등)을 자의적으로 추가함. 필요 없는 것은 삭제하세요.
· N:M 관계를 선 하나로 대충 연결하고 연결 테이블을 누락함. 직접 확인하세요.
· 비즈니스 정책을 알 수 없음. "계정 탈퇴 후 데이터 보존 여부"는 AI가 정해줄 수 없습니다.
그렇기 때문에 Mission 01(의사결정록)이 중요합니다. 무엇을 채택하고 무엇을 거절했는지 기록하는 것이 여러분의 진짜 역량입니다.

05최종 자가 점검 (Exit Check)

모두 체크했나요? 그렇다면 Day 4(API 설계) 준비가 완료되었습니다.

06용어 요약 사전

용어쉬운 설명중요한 이유
Entity (엔티티)독립적으로 수량을 세는 핵심 데이터 개체 (테이블 1개)잘못 정의하면 테이블이 너무 많아지거나 부족해짐
Attribute (속성)엔티티의 세부 특성 (컬럼 1개)엔티티인가 속성인가 구분하는 것이 데이터 설계의 핵심
Schema (스키마)테이블 구조 청사진 (데이터의 헌법)스키마를 바꾸면 상위 모든 시스템이 영향받음
Cardinality (수량성)관계에서 몇 대 몇인지 나타내는 수량 비율1:N 관계를 반대로 맺으면 화면 조회가 불가능해짐
Primary Key (PK, 주키)각 행을 식별하는 고유 번호중복 데이터 여부를 판가름하는 기준
Foreign Key (FK, 외래키)다른 테이블을 가리키는 참조 키테이블과 테이블 사이를 연결해 주는 고리
Referential Integrity (참조 무결성)참조하는 대상이 실제 존재해야 한다는 규칙유령 데이터 및 고아 데이터 발생 방지
Normalization (정규화)각 사실을 단 한 곳에만 기록하도록 분리하는 과정데이터 간 모순과 불일치 현상 방지
Anomaly (이상 현상)정규화하지 않아 발생하는 3가지 오류(삽입/수정/삭제)정규화를 수행하는 근본적인 이유
Junction Table (연결 테이블)N:M 관계를 풀기 위해 중간에 생성하는 테이블누락할 경우 N:M 관계 표현 불가능
Migration (마이그레이션)기존 저장 데이터를 새 구조로 이전하는 작업스키마 변경 시 발생하는 실질적 작업 비용
Mermaid텍스트로 다이어그램을 그리는 툴ERD를 코드처럼 버전 관리 가능하게 함

ACE AI 스타트업 부트캠프 · Day 3 보충 가이드 — 본 자료는 정규 교육과정(Day 3 AI 강의실)을 보완하는 수강생용 참고 교안입니다.

막혔을 때는 ① 본 가이드의 해당 섹션 확인 → ② 5가지 프롬프트로 Codex AI에 질문 → ③ 튜터 및 강사에게 질문 순서로 해결하세요. 동일한 문제로 20분 이상 고민하지 마세요.