데이터베이스 기초
데이터베이스란 무엇인가
데이터베이스(DB)는 데이터를 체계적으로 모아 둔 저장소, DBMS는 그 데이터를 저장·조회·수정·삭제하도록 관리하는 소프트웨어입니다. 우리가 쓸 MySQL과 MongoDB가 DBMS입니다.
DBMS는 서버-클라이언트 구조로 동작합니다. 데이터를 지키는 서버가 떠 있고, 우리가 클라이언트(터미널·GUI·게임)로 접속해 요청합니다. 로컬 DB 서버란 이 서버를 내 PC에서 돌리는 것이며, 오늘 실습의 무대입니다.
① SQL·NoSQL 차이를 설명한다 → ② MySQL·MongoDB를 설치·실행한다 → ③ 시각화 도구로 구조를 눈으로 이해하며 CRUD를 한다 → ④ API 서버를 만들어 → ⑤ Unreal에서 그 데이터를 실제로 읽고 쓴다.
그냥 파일에 저장하면 안 되나?
데이터가 많아지고 여럿이 동시에 다루면 한계가 옵니다. DBMS는 동시성·무결성·질의(조건 검색을 순식간에)·확장·복구를 대신 해결해 줍니다.
SQL vs NoSQL — 두 가지 세계관
DB는 데이터를 표(테이블)에 담는 관계형(SQL)과, 문서·키값처럼 자유로운 형태로 담는 비관계형(NoSQL)으로 나뉩니다. 우열이 아니라 성격이 다른 도구입니다.
관계형 · SQL
- 데이터를 테이블(행·열)에 저장
- 스키마를 미리 정의(고정)
- 테이블 관계를 JOIN으로 연결
- 강력한 ACID 트랜잭션
- 표준 질의어 SQL
- 예: MySQL, PostgreSQL
비관계형 · NoSQL
- 데이터를 문서(JSON형)·키값으로 저장
- 스키마가 유연(문서마다 달라도 OK)
- 관련 데이터를 문서 안에 품기
- 수평 확장에 강함
- 제품별 API·쿼리
- 예: MongoDB, Redis
| 기준 | SQL (MySQL) | NoSQL (MongoDB) |
|---|---|---|
| 데이터 구조 | 테이블 · 행 · 열 | 컬렉션 · 문서(JSON/BSON) |
| 스키마 | 사전 정의(고정) | 유연(문서마다 다를 수 있음) |
| 관계 표현 | JOIN | 임베딩 또는 $lookup |
| 확장 방식 | 주로 수직 확장 | 수평 확장에 유리 |
| 트랜잭션 | 강력한 ACID | 문서 단위 + 다중 문서 지원 |
| 잘 맞는 곳 | 정형 · 복잡한 관계 · 정확성 | 유연 · 대량 · 빠른 변경 |
"NoSQL은 트랜잭션이 없다"는 옛말입니다. MongoDB도 다중 문서 트랜잭션을 지원합니다. "NoSQL이 무조건 빠르다"도 틀립니다 — 데이터 모양과 접근 패턴에 맞는 쪽이 빠릅니다. 그래서 둘 다 경험해 봅니다.
용어 정리 — 같은 개념, 다른 이름
두 DB는 비슷한 개념을 다른 단어로 부릅니다. 이 표를 외워 두면 이후 실습이 쉬워집니다.
| 개념 | MySQL | MongoDB |
|---|---|---|
| 최상위 묶음 | Database | Database |
| 데이터 그릇 | Table (테이블) | Collection (컬렉션) |
| 데이터 한 건 | Row / Record (행) | Document (문서) |
| 한 건의 항목 | Column / Field (열) | Field (필드) |
| 고유 식별자 | Primary Key | _id (자동) |
| 구조 규칙 | Schema (고정) | (유연 · 강제 안 됨) |
MySQL의 "테이블 속 한 행"이 곧 MongoDB의 "컬렉션 속 한 문서"입니다. 이름만 다를 뿐 "데이터 한 건"이라는 뜻은 같습니다.
로컬 DB 구축 · 시각화 · 사용
MySQL 로컬 서버 구축
가장 쉬운 길은 MySQL Installer for Windows입니다. 서버·워크벤치(GUI)·셸을 한 번에 설치합니다. 이 워크벤치가 뒤(08장)에서 배울 시각화 도구입니다.
설치 파일 받기
dev.mysql.com/downloads/installer에서 MySQL Installer를 받습니다(로그인 없이 가능).
Developer Default로 설치
Server·Workbench·Shell이 함께 깔립니다.
서버 설정
Config는 Development Computer, 포트 3306.
root 비밀번호 설정
반드시 기록. 실습·API 연결에서 매번 씁니다.
Windows 서비스 등록
as a Windows Service 체크 → 자동 실행. Execute→Finish.
접속 확인
Workbench에서 Local instance MySQL에 root로 접속되면 성공.
- root 비밀번호 분실 → 처음부터 메모.
- 포트 3306 충돌 → 설정에서 변경.
- 연결 실패 → services.msc에서 서비스 실행 확인.
MySQL 기본기 — 첫 SQL 쿼리
Workbench 쿼리 창에서 순서대로 실행합니다. 관계형은 먼저 표 구조(스키마)를 정의하고 데이터를 넣습니다.
-- DB 생성 & 선택 CREATE DATABASE school; USE school; -- 스키마 정의 CREATE TABLE students ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, email VARCHAR(100) UNIQUE, grade INT ); -- Create / Read / Update / Delete INSERT INTO students (name,email,grade) VALUES ('김민수','minsu@example.com',1); SELECT * FROM students WHERE grade=1 ORDER BY name; UPDATE students SET grade=2 WHERE name='김민수'; DELETE FROM students WHERE id=1;
CREATE TABLE을 직접 치는 대신, 왼쪽 스키마에서 Tables → Create Table로 폼을 채워 열·타입·키를 정의할 수 있습니다. 결과는 표(그리드)로 보고 셀을 직접 편집도 가능합니다. SQL과 GUI는 같은 일을 두 방식으로 하는 것 — 08장에서 깊이 다룹니다.
UPDATE·DELETE에서 WHERE를 빠뜨리면 테이블 전체가 바뀌거나 지워집니다.
MongoDB 로컬 서버 구축
MongoDB는 서버·GUI(Compass)·셸(mongosh)이 나뉩니다. 가장 큰 함정: 서버 설치 파일에 셸이 없습니다. 따로 받아야 합니다. Compass는 설치 때 함께 깔 수 있고, 08장의 핵심 시각화 도구입니다.
Community Server 받기
mongodb.com/try/download/community에서 Windows .msi(8.0 계열).
Complete + 서비스 등록
Complete 설치, Install as a Service 체크 → 자동 실행(포트 27017).
Compass 함께 설치
Install MongoDB Compass(기본 체크) → GUI 툴.
⚠️ mongosh 별도 설치
mongodb.com/try/download/shell에서 mongosh를 받아 설치하고 PATH 추가.
접속 확인
mongosh 실행 또는 Compass에서 mongodb://localhost:27017 연결.
- "mongosh 없음" → 셸 미설치 / PATH 미등록.
- 연결 안 됨 → services.msc에서 MongoDB 서비스 확인.
- WSL 미지원 → Windows 네이티브로 설치.
MongoDB 기본기 — 첫 문서 다루기
mongosh(또는 Compass)에서 실행합니다. SQL과 달리 미리 컬렉션을 만들 필요가 없습니다 — 넣는 순간 생깁니다.
// DB 선택 (없으면 자동 생성) use school // Create — 문서마다 구조가 달라도 OK > db.students.insertOne({ name:"김민수", email:"minsu@example.com", grade:1 }) > db.students.insertMany([{ name:"이서연", grade:2, clubs:["미술"] }]) // Read / Update / Delete > db.students.find({ grade:1 }).sort({ name:1 }) > db.students.updateOne({ name:"김민수" }, { $set:{ grade:2 } }) > db.students.deleteOne({ name:"이서연" })
insertOne을 치는 대신 ADD DATA → Insert Document 버튼으로 문서를 넣고, Schema 탭에서 이 컬렉션의 구조를 그래프로 볼 수 있습니다. 이서연에게만 있는 clubs 필드가 "몇 %의 문서에 존재하는지"까지 눈에 보입니다 — 08장에서 실습합니다.
시각화 도구로 직관적으로 배우기
쿼리를 외우기 전에 데이터를 눈으로 보면 개념이 훨씬 빨리 잡힙니다. 다행히 두 DB 모두 공식 GUI가 설치 때 함께 깔렸습니다 — MySQL Workbench와 MongoDB Compass. 문법을 몰라도 클릭으로 데이터를 다루고, 그 과정에서 문법을 자연스럽게 익히게 됩니다.
MySQL Workbench관계를 그림으로
Workbench의 백미는 EER 다이어그램입니다. 테이블을 상자로, 테이블 사이 관계를 선으로 그려 주므로, 추상적인 JOIN과 "관계"가 한눈에 들어옵니다. 기존 DB를 Reverse Engineer하면 자동으로 다이어그램이 만들어집니다.
그 밖에도 학생들이 반가워할 기능들이 있습니다.
- 비주얼 테이블 편집기 — CREATE TABLE SQL을 치지 않고 폼으로 열·타입·PK를 정의.
- 결과 그리드 — 조회 결과를 엑셀처럼 보고 셀을 직접 편집.
- Visual EXPLAIN — 쿼리 실행 계획을 그림으로 보여줘 성능 감을 잡게 함.
- Forward Engineer — 다이어그램으로 설계 → SQL을 자동 생성. "그림 → SQL" 흐름이 직관적.
학생에게 먼저 다이어그램으로 테이블을 설계하게 한 뒤 Forward Engineer로 SQL을 뽑아 보여주면, "이 상자·선이 이 SQL이 되는구나"를 스스로 연결합니다. 관계형의 핵심인 관계를 가장 직관적으로 가르치는 방법입니다.
MongoDB Compass문서를 눈으로
문서형 DB는 중첩·배열·유연한 스키마 때문에 터미널만으로는 파악이 어렵습니다. Compass는 이걸 대시보드처럼 보여줍니다. 특히 두 기능이 강력합니다.
① 스키마 분석 — "유연한 스키마"를 눈으로
컬렉션을 샘플링해 필드별 타입·존재 비율·값 분포를 막대·그래프로 보여줍니다. 어떤 문서에만 있는 필드, 타입이 섞인 필드를 바로 발견할 수 있어 "문서마다 구조가 다를 수 있다"는 NoSQL의 개념이 그림으로 이해됩니다.
② 애그리게이션 파이프라인 빌더 — 데이터가 변형되는 걸 실시간으로
Compass의 최강 기능입니다. $match(거르기) → $group(묶기) → $sort(정렬) 같은 단계를 하나씩 추가하면, 각 단계의 결과를 즉시 미리보기로 보여줍니다. 문법을 외우지 않아도 데이터가 어떻게 가공되는지 눈으로 따라가며 배우고, 완성되면 코드(Node·Python 등)로 내보낼 수 있습니다.
count: {$sum:1}
이 밖에 문서 브라우저(중첩 JSON을 펼쳐 보고 CRUD), 쿼리 바(필터를 시각적으로), 인덱스·Visual Explain도 제공합니다. 기본이 읽기 전용이라 실수로 데이터를 바꿀 걱정도 적습니다.
mongosh가 부담되는 학생은 Compass로 시작하게 하세요. GUI로 문서를 넣고 필터를 만들다 보면 자연스럽게 문법이 익습니다. "이 클릭이 이 쿼리"라는 대응을 셸과 나란히 보여주면 학습이 빨라집니다.
다른 선택지도 알아두기
공식 도구(Workbench·Compass)면 수업엔 충분하지만, 상황에 따라 이런 대안도 있습니다.
| 도구 | 대상 DB | 특징 |
|---|---|---|
| MySQL Workbench | MySQL | 공식·설치 포함. EER 다이어그램 있는 유일한 무료 툴 |
| DBeaver (Community) | 다중 (80+) | 무료·오픈소스, ER 다이어그램(읽기), 여러 DB를 한 툴로 |
| HeidiSQL | MySQL 등 | Windows 네이티브, 매우 가볍고 빠름, 무료 |
| Beekeeper Studio | 다중 | 깔끔한 UI, 학습곡선이 가장 완만 — 완전 초보에 적합 |
| MongoDB Compass | MongoDB | 공식·설치 포함. 스키마 분석 + 애그리게이션 빌더 |
| Studio 3T | MongoDB | 비주얼 쿼리 빌더, SQL↔Mongo 변환, 코드 생성(유료) |
정답은 둘 다, 나란히입니다. 개념·탐색은 GUI로 "보여주고", 반복·자동화·연동은 CLI/쿼리로 "굳힙니다." 이 가이드가 각 CRUD 챕터에 "🖱️ GUI로도 해보기" 콜아웃을 넣은 이유입니다. 학생이 같은 작업을 두 방식으로 해보면 이해가 입체적으로 잡힙니다.
나란히 보기 — 같은 작업, 두 방식
| 작업 | MySQL (SQL) | MongoDB |
|---|---|---|
| Create | INSERT INTO students VALUES (...) | db.students.insertOne({...}) |
| Read | SELECT * FROM students WHERE grade=1 | db.students.find({grade:1}) |
| Update | UPDATE students SET grade=2 WHERE ... | db.students.updateOne({...},{$set:{...}}) |
| Delete | DELETE FROM students WHERE id=1 | db.students.deleteOne({...}) |
| 구조 준비 | 먼저 CREATE TABLE | 불필요(자동 생성) |
| 시각화 도구 | Workbench (EER 다이어그램) | Compass (스키마·애그리게이션) |
구조가 분명하고 정확성이 중요하면 SQL(MySQL), 형태가 유연하고 양이 많으면 NoSQL(MongoDB). 다음 Part 3에서 이 두 DB를 Unreal에 똑같은 방식으로 연결합니다.
Unreal 연동
왜 DB에 직접 연결하지 않는가
"Unreal에서 바로 MySQL에 붙으면 안 되나?" 가능하긴 하지만(C++ 드라이버), 표준은 중간에 API 서버를 두는 3계층 구조입니다.
- 보안 — DB 비밀번호가 게임에 박히면 누구나 뜯어봅니다. API가 대신 감춥니다.
- 이식성 — Unreal은 HTTP로 JSON만 주고받으므로, DB를 MySQL↔MongoDB로 바꿔도 게임 코드는 그대로.
- 단순함 — Unreal에 DB 드라이버·DLL 링크가 불필요. 내장 HTTP면 충분.
Unreal은 DB를 모른다. API 서버에게 HTTP로 부탁하고, 서버가 DB에서 꺼내 JSON으로 답합니다. HTTP·JSON이 세 계층의 공통 언어입니다.
| 계층 | 무엇으로 | 포트 |
|---|---|---|
| 게임 클라이언트 | Unreal Engine 5 | — |
| API 서버(중개) | Node.js + Express | 3000 |
| SQL DB | MySQL | 3306 |
| NoSQL DB | MongoDB | 27017 |
넷 다 localhost에서 돌지만 포트가 다릅니다. 이 지도를 외우면 문제 해결이 빨라집니다.
API 서버 만들기 (Node.js)
가운데 다리를 먼저 놓습니다. Node.js와 Express로 몇 줄이면 DB 앞에 REST 창구가 생깁니다.
> npm init -y > npm install express mysql2 mongodb
const express = require("express"); const mysql = require("mysql2/promise"); const app = express(); app.use(express.json()); const pool = mysql.createPool({ host:"localhost", port:3306, user:"root", password:"내_비밀번호", database:"school" }); // READ app.get("/students", async (req,res)=>{ const [rows] = await pool.query("SELECT * FROM students"); res.json(rows); }); // CREATE app.post("/students", async (req,res)=>{ const {name,email,grade} = req.body; const [r] = await pool.query( "INSERT INTO students (name,email,grade) VALUES (?,?,?)",[name,email,grade]); res.json({ id:r.insertId, name, email, grade }); }); app.listen(3000, ()=>console.log("API on http://localhost:3000"));
const { MongoClient } = require("mongodb"); const client = new MongoClient("mongodb://localhost:27017"); let students; client.connect().then(()=>{ students = client.db("school").collection("students"); }); // READ await students.find().toArray() // CREATE await students.insertOne(req.body)
node server.js 실행 후, Unreal을 켜기 전에 브라우저에서 http://localhost:3000/students를 여세요. JSON이 보이면 다리 완성. 항상 DB → API → Unreal 순으로 확인하면 문제 계층을 바로 좁힐 수 있습니다.
Unreal에서 요청 보내기
이제 Unreal이 그 창구에 HTTP로 말을 겁니다. 학생들에겐 블루프린트 경로를 먼저 권합니다.
A. 블루프린트 (권장)
- C++ 없이 노드로 완성
- HTTP+JSON 플러그인 사용
- 초보·빠른 프로토타입
B. C++ (심화)
- 엔진 내장 HTTP·Json 모듈
- 플러그인 불필요
- 성능·대용량에 유리
A. 블루프린트 경로
JSON 플러그인 켜기
내장 Json Blueprint Utilities를 Edit→Plugins에서 활성화·재시작(기본 꺼짐).
HTTP 요청 플러그인
순수 BP로 HTTP를 보내려면 VaRest(Fab, HTTP+JSON) 또는 HttpBlueprintAPI(GitHub, 무료).
GET → 파싱 → 표시
키 이벤트에서 :3000/students로 GET, 완료 콜백에서 응답을 Load Json from String으로 파싱해 화면에 뿌립니다.
B. C++ 경로 (요약)
// Build.cs: PublicDependencyModuleNames += { "HTTP","Json","JsonUtilities" } auto Request = FHttpModule::Get().CreateRequest(); Request->SetURL("http://localhost:3000/students"); Request->SetVerb("GET"); Request->SetHeader("Content-Type","application/json"); Request->OnProcessRequestComplete().BindUObject(this,&AMyActor::OnResponse); Request->ProcessRequest(); // OnResponse에서 FJsonSerializer로 파싱
응답은 즉시 오지 않습니다. 반드시 완료 콜백/이벤트 안에서 처리하세요. 큰 JSON을 게임 스레드에서 파싱하면 순간 멈춤(hitch)이 생기니, 대용량은 C++ 백그라운드를 고려합니다.
왕복 테스트
읽기: 게임에서 G를 누르면 GET → API가 DB 조회 → 학생 목록이 화면에 뜹니다. 앞서 DB에 넣은 김민수·이서연이 게임 안에 보이면 성공.
쓰기: 버튼/폼에서 POST로 새 학생 JSON을 보냅니다. 다시 GET으로 새로고침하면 추가된 학생이 보이고, Workbench(또는 Compass)로도 실제 저장을 시각적으로 확인합니다.
// Content-Type: application/json 헤더 필수 { "name":"최유나", "email":"yuna@example.com", "grade":1 }
① 브라우저에서 API가 JSON을 준다 · ② Unreal이 그 JSON을 받아 화면에 뿌린다 · ③ Unreal에서 보낸 데이터가 DB에 남는다(Compass/Workbench로 확인). 세 가지가 되면 Unreal ↔ DB 연동 완성입니다.
마무리 — 문제 해결 · 로드맵 · 과제
막힐 때 — 어느 계층에서 끊겼나
연동에서 막히면 대부분 어느 계층에서 끊겼는지를 못 찾아서입니다. 이 표로 범위를 좁히세요. GUI 도구(Workbench·Compass)로 데이터를 눈으로 확인하면 진단이 빨라집니다.
| 증상 | 주로 이 계층 | 확인 |
|---|---|---|
| Workbench/Compass 연결 실패 | DB | services.msc에서 서비스 실행? |
| 브라우저에서 JSON 안 뜸 | API ↔ DB | 비밀번호·DB명·포트 맞음? GUI로 데이터 존재 확인 |
| 브라우저는 되는데 Unreal만 실패 | Unreal ↔ API | URL 오타, 완료 콜백 사용? |
| Connection refused | API | node server.js 실행 중? |
| 빈 값 / 파싱 실패 | Unreal | 필드 대소문자·타입 일치? |
| localhost 연결 안 됨 | OS | 127.0.0.1, 방화벽 허용 |
실무 팁 & 보안
MySQL · Workbench
- root 비밀번호 처음부터 기록
- UPDATE/DELETE엔 항상 WHERE
- EER 다이어그램으로 설계 먼저
MongoDB · Compass
- 셸(mongosh) 별도 설치 + PATH
- Schema 탭으로 구조 점검
- 애그리게이션은 빌더로 먼저
API 서버
- DB 포트와 겹치지 않는 3000
- 브라우저로 먼저 검증
- 비밀번호는 환경변수로
Unreal
- HTTP는 비동기 → 콜백 처리
- 큰 JSON은 C++ 백그라운드
- Content-Type 헤더 확인
지금 만든 건 연습용 로컬 시스템입니다. 배포 시엔 API에 인증(토큰), DB 비밀번호는 환경변수, 통신은 HTTPS가 기본입니다.
학습 로드맵 & 최종 과제
개념에서 게임 연동까지, 한 단계씩 결과물을 남기며 나아가는 통합 커리큘럼입니다.
개념
- DB·DBMS 이해
- SQL vs NoSQL
- 용어 대응표
MySQL + Workbench
- 서버 구축
- EER 다이어그램
- 테이블 CRUD
MongoDB + Compass
- 서버+셸 설치
- 스키마 분석·빌더
- 문서 CRUD
API 서버
- Express 구축
- GET/POST
- 브라우저 검증
Unreal GET
- JSON 플러그인
- HTTP 요청
- 목록 표시
Unreal POST
- JSON 전송
- 재조회 반영
- 미니 앱
Unreal 화면에 버튼 두 개를 만들어, 불러오기는 DB의 학생 목록을 GET으로 표시하고, 추가는 입력한 학생을 POST로 저장합니다. 저장 결과는 Workbench/Compass로 시각적으로 확인하고, 여유가 되면 API의 DB를 MySQL→MongoDB로 바꿔 Unreal 코드는 안 바뀐다는 걸 확인해 제출합니다.
- MySQL·MongoDB 서비스가 실행되는가?
- Workbench·Compass로 데이터를 눈으로 확인했는가?
- 양쪽 DB에서 CRUD를 모두 해봤는가?
- 브라우저에서 :3000/students가 JSON을 주는가?
- Unreal의 HTTP 요청을 완료 콜백에서 처리했는가?
- Unreal에서 보낸 데이터가 DB에 실제로 남는가?