콘텐츠로 이동

01. 데이터베이스: 영구적인 창고 (The Persistent Memory)

"변수는 전원을 끄면 사라지지만, 데이터는 영원해야 합니다."

1. Why: 휘발성(RAM) vs 영속성(Disk)

우리가 파이썬에서 users = [] 리스트를 만들어 데이터를 넣는 건, 컴퓨터의 작업대(RAM)를 쓰는 것입니다. 작업대는 빠르지만, 퇴근할 때(컴퓨터 끌 때) 그 위를 싹 치워야 합니다.

비즈니스에서 고객의 정보가 사라지면 안 되겠죠? 그래서 우리는 금고(Hard Disk)에 장부를 보관해야 합니다. 이 디지털 금고가 바로 데이터베이스(DB)입니다.

구분 RAM (메모리) Disk (데이터베이스) 비유
특징 전원 끄면 삭제됨 전원 꺼도 유지됨 머릿속 단기 기억 vs 노트 필기
용도 현재 계산 중인 값 회원가입 정보, 주문내역 요리 도마 vs 냉장고
속도 엄청 빠름 (KTX) 상대적으로 느림 (자전거) 변수(Variable) vs 파일(File)

핵심 용어: 영속성 (Persistence) "전원이 꺼져도 데이터가 사라지지 않고 남아있는 특성"을 개발 용어로 영속성이라고 합니다. DB를 배우는 것은 곧 우리 프로그램에 영속성을 부여하는 과정입니다.

1-5. Where: 데이터베이스의 위치 (Backend의 금고)

데이터베이스는 브라우저(Frontend)가 직접 접근할 수 없습니다. (보안상 매우 위험!) 반드시 우리가 4부에서 만든 API 서버(FastAPI)를 통해서만 대화해야 합니다.

graph LR
    Client["💻 브라우저 (React)"] <-->|"1. 요청 (JSON)"| API["👨‍🍳 API 서버 (FastAPI)"]
    API <-->|"2. 조회 (SQL)"| DB[("🗄️ 데이터베이스")]

    style API fill:#ff9,stroke:#333,stroke-width:2px
    style DB fill:#bbf,stroke:#333,stroke-width:2px

해석: API 서버는 손님의 주문(Request)을 받아 주방(DB)에서 재료를 꺼내오고 요리해서 내주는 쉐프(Chef) 역할을 합니다.

2. What: DB는 '스마트한 엑셀'이다

데이터베이스(RDBMS)는 어렵지 않습니다. 그냥 "규칙이 아주 엄격한 엑셀(Excel)"이라고 생각하면 됩니다.

엑셀(Excel) 용어 DB 용어 설명
시트 (Sheet) 테이블 (Table) 데이터의 주제 (예: 회원표, 주문표)
열 (Column) 컬럼 / 필드 데이터의 항목 (예: 이름, 나이, 이메일)
행 (Row) 레코드 (Record) 실제 데이터 한 줄 (예: 철수의 정보)
주민번호 PK (Primary Key) 데이터를 구분하는 고유 번호 (중복 불가)

그럼 그냥 엑셀 쓰면 안 되나요?

안 됩니다. 엑셀은 100만 명이 동시에 접속하면 터집니다. DB는 100만 명이 동시에 접속해도 끄떡없는 초고성능 엑셀입니다.


🕰️ 잠깐 상식: 데이터 저장소의 진화 (History)

데이터베이스도 시대의 요구에 따라 진화해왔습니다. 우리는 현재 가장 표준적인 2세대(RDBMS)를 배웁니다.

세대 이름 특징 대표 선수 비유
1세대 File System 단순히 텍스트 파일에 저장. 검색이 느리고 관리가 힘듦. memo.txt 종이 서류철
2세대 RDBMS
(Relational Database Management System)
[현재 표준] 표(Table) 형태로 정리. 데이터의 정합성(규칙)을 중시. Oracle, MySQL, SQLite 잘 정리된 엑셀
3세대 NoSQL 빅데이터 시대. 규칙은 좀 느슨해도, 엄청난 양의 데이터를 빠르게 처리. MongoDB, Firebase 자유로운 포스트잇

💡 Tip

MySQL은 서버용 RDBMS이고, 우리가 쓸 SQLite는 파일용 RDBMS입니다. 문법(SQL)은 99% 똑같습니다.


3. Speed: 인덱스(Index), 데이터의 '찾아보기'

DB가 엑셀보다 수백 배 빠른 결정적인 이유는 바로 인덱스(Index)에 있습니다.

1) 인덱스란 무엇인가?

우리가 두꺼운 전공 서적에서 특정 단어를 찾을 때, 첫 페이지부터 끝까지 다 읽지 않습니다. 책 뒷부분의 '찾아보기(색인)' 페이지를 보고 해당 내용이 있는 페이지로 바로 건너뛰죠.

  • 인덱스가 없을 때 (Full Table Scan): 데이터를 찾기 위해 처음부터 끝까지 모든 행을 다 뒤집니다. (데이터가 1억 개면 1억 번 확인)
  • 인덱스가 있을 때 (Index Scan): 정렬된 목차를 보고 데이터가 있는 '주소'로 바로 점프합니다. (데이터가 1억 개라도 단 몇 번만에 찾음)
ID (Index) 저장 위치 (Address)
... ...
1054 A-Sector-05
1055 B-Sector-12 👈 (여기 있네! 점프)
1056 A-Sector-99

2) PK(기본키)와 인덱스의 관계

우리가 테이블을 만들 때 PK(Primary Key)를 설정하면, DB는 자동으로 이 PK를 기준으로 인덱스를 생성합니다.

  • 학생 ID(PK)로 검색할 때: 0.001초 만에 찾음 (인덱스 사용)
  • 학생 이름(인덱스 없음)으로 검색할 때: 학생 수가 많아질수록 점점 느려짐

3) 인덱스의 빛과 그림자

인덱스는 무조건 많이 만든다고 좋은 게 아닙니다.

장점 (PROS) 단점 (CONS)
조회(SELECT) 속도가 압도적으로 빨라짐. 용량(Storage)을 추가로 차지함 (목차 페이지가 늘어남).
시스템의 전체적인 성능이 향상됨. 쓰기/수정(INSERT/UPDATE) 속도가 미세하게 느려짐 (데이터를 넣을 때마다 목차도 업데이트해야 함).

💡 핵심 정리: 인덱스는 "자주 검색되는 조건(Column)"에 설정하는 것이 핵심입니다. 하지만 너무 남용하면 오히려 저장 공간을 낭비하고 쓰기 성능을 떨어뜨릴 수 있습니다.


4. Design: Class Diagram과 ERD의 관계 (The Mirror)

여러분이 AI에게 코딩을 시킬 때 Class Diagram(설계도)을 그려주던 것 기억나시죠? 데이터베이스 설계도인 ERD (Entity Relationship Diagram)는 Class Diagram과 이란성 쌍둥이입니다.

4-1. 객체 세상 vs 데이터 세상

  • Class Diagram: 프로그램 세상의 지도. "데이터도 있고, 동작(함수)도 있다."
  • ERD: 창고(DB) 세상의 지도. "오직 데이터만 저장한다."

이 둘은 서로 거울처럼 대응됩니다. Class Diagram에서 '함수'만 빼면 그게 바로 ERD입니다.

classDiagram
    direction LR
    class Python_Class_User {
        +int id
        +str name
        +str email
        +login()
        +logout()
    }

    class DB_Table_User {
        +int id_PK
        +varchar name
        +varchar email
    }

    note for DB_Table_User "오직 데이터만 저장!\n(No Methods ❌)"

    Python_Class_User --|> DB_Table_User : "ORM이 연결 (Mapping)"

4-2. 연결의 마법사: ORM

우리가 파이썬으로 Class를 잘 설계하면, ORM이라는 통역사가 알아서 DB에 Table(ERD)을 만들어줍니다. 즉, "Class 설계를 잘하면 DB 설계는 공짜"입니다.

참고: ORM이 통역사라면, 그가 사용하는 '진짜 언어'SQL입니다. 우리는 편하게 파이썬을 쓰지만, DB 내부에서는 SQL이 쉴 새 없이 움직이고 있다는 사실을 기억하세요.

4-3. 핵심 차이: 참조(Reference) vs 외래키(FK)

하지만 이 둘은 '관계를 맺는 방식'에서 아주 중요한 차이가 있습니다.

1) 클래스 세상: "너를 내 안에 담을게" (Reference)

객체 지향 프로그래밍에서는 한 객체가 다른 객체를 직접 참조합니다. * 특징: Course 클래스 안에 Teacher 객체 자체가 들어갑니다. (self.teacher = Teacher()) * 표현: 굳이 번호(id)를 외우지 않고, 그냥 '그 사람(객체)'을 가리킵니다.

2) 데이터 세상: "너의 번호만 기록할게" (Foreign Key)

데이터베이스는 객체를 통째로 저장할 수 없습니다. 오직 값(Value)만 저장합니다. * 특징: Course 테이블은 Teacher의 모든 정보를 갖는 대신, 주민번호 격인 teacher_id (FK)만 기록합니다. * 표현: 이 번호를 통해 나중에 Teacher 테이블에서 정보를 찾아옵니다(JOIN).

3) 비교 표: 설계할 때 주의점

구분 클래스 다이어그램 (Class) ERD (Database)
핵심 식별자 없음 (메모리 주소로 구분) PK (Primary Key) 필수!
관계 표현 객체 변수 (student_list) FK (Foreign Key) 필수!
N:M 관계 리스트나 셋(Set)으로 표현 가능 연결 테이블이 반드시 필요

💡 핵심: 파이썬 코드에서는 점(.)을 찍어서 바로 접근하지만, DB에서는 '번호표(FK)'만 가지고 있습니다. ORM이 이 번호표를 보고 실제 객체를 찾아와 주는 것입니다.

⚠️ 주의: 참조 무결성 (Reference Integrity) 번호표(FK)는 아무 번호나 적을 수 없습니다. 강사 테이블에 1, 2, 3번 강사만 있는데, 강의 테이블에 teacher_id = 99를 적으려 하면 DB 금고지기가 "그런 사람은 없어!"라며 에러를 냅니다. 이것이 데이터가 꼬이는 것을 막아주는 DB의 강력한 보호막입니다.

5. 우리의 도구: SQLite vs MySQL

우리는 상황에 맞춰 두 가지 도구를 적절히 섞어서 쓸 것입니다.

1) SQLite (가벼운 파일)

"간단한 건 파일로 해결하자!"

  • 용도: 혼자 개발할 때, 테스트용, 모바일 앱 내부 저장소.
  • 특징: 별도 서버 설치 없이 파일 하나(db.sqlite3)가 곧 엑셀 파일처럼 작동합니다. 파이썬에 내장되어 있어 간편합니다.

2) MySQL (강력한 서버)

"별도 서버가 필요할 땐 MySQL!"

  • 용도: 여러 사용자가 동시에 접속하는 서비스, 대용량 데이터 처리, 실제 배포(Production).
  • 특징: 별도의 DB 서버 프로그램(또는 클라우드)을 띄워야 합니다.

작전: 우리는 개발 단계(Local)에서는 간편한 SQLite를 쓰고, 실제 배포(Deploy) 때는 MySQL로 자연스럽게 넘어갈 것입니다. (ORM이 이걸 가능하게 해줍니다!)