데이터베이스, 관계형 모델, SQL의 역할
1강. 데이터베이스, 관계형 모델, SQL의 역할
1. 이번 강의에서 해결할 문제
플레이어, 경기, 캐릭터 통계를 한 파일에 반복 저장하면 이름 변경과 집계가 불안정해집니다. 데이터를 서로 관련된 테이블로 나누는 이유부터 정리합니다.
2. 학습 목표
3. 핵심 개념
관계형 데이터베이스는 같은 종류의 행을 테이블에 저장하고 키로 테이블 사이 관계를 표현합니다. SQLite와 PostgreSQL은 DBMS이며 SQL은 구조 정의, 조회, 변경, 트랜잭션 제어에 사용하는 언어입니다.
프로그램은 종료된 뒤에도 플레이어 이름과 점수, 경기 기록을 기억해야 합니다. 이를 텍스트 파일 하나에 계속 덧붙일 수도 있지만, 여러 사용자가 동시에 수정하거나 특정 플레이어의 기록만 찾을 때 규칙을 직접 만들어야 합니다. 데이터베이스는 데이터를 일정한 구조로 보관하고, DBMS는 그 데이터를 안전하게 찾고 바꾸도록 관리합니다.
먼저 알아야 할 용어
| 용어 | 초보자 관점의 뜻 | 랭킹 서비스 예 |
|---|---|---|
| 데이터베이스 | 관련 데이터를 조직해 둔 전체 저장소 | game_ranking.db |
| DBMS | 데이터베이스를 만들고 조회·수정하는 프로그램 | SQLite, PostgreSQL |
| 테이블 | 같은 종류의 대상을 행과 열로 모은 구조 | players |
| 행(row) | 한 대상 또는 한 사건의 기록 | 한 플레이어의 계정 |
| 열(column) | 모든 행이 공통으로 갖는 항목 | 이름, 지역, 가입일 |
| 기본 키 | 각 행을 겹치지 않게 식별하는 값 | player_id |
| 외래 키 | 다른 테이블의 행을 가리키는 값 | 경기 결과의 player_id |
| SQL | DBMS에 구조·조회·변경을 요청하는 언어 | SELECT, INSERT |
스프레드시트처럼 보이지만 테이블은 단순한 화면 표가 아닙니다. 열마다 허용할 값과 필수 여부를 정하고, 키와 제약 조건으로 잘못된 상태를 거부할 수 있습니다.
players 1 ── N match_results N ── 1 games
│
└── character_stats
이 그림에서 플레이어 한 명은 여러 경기 결과를 가질 수 있으므로 players 1 ── N match_results로 표시합니다. 경기 하나에도 여러 플레이어가 참가할 수 있으므로 games와도 일대다 관계입니다. match_results가 두 테이블의 중간 기록이 되어 "누가 어느 경기에 참가했는가"를 표현합니다.
SQL 명령은 무엇을 바꾸는가
| 분류 | 대표 명령 | 하는 일 |
|---|---|---|
| DDL | CREATE TABLE, ALTER TABLE | 저장 구조를 정의하거나 변경 |
| DML | INSERT, UPDATE, DELETE | 행을 추가·수정·삭제 |
| DQL | SELECT | 저장된 데이터로 결과 집합 생성 |
| TCL | COMMIT, ROLLBACK | 여러 변경을 하나의 작업으로 확정하거나 취소 |
분류 이름을 외우는 것보다, 실행할 SQL이 구조, 데이터, 조회 결과, 트랜잭션 상태 중 무엇을 바꾸는지 먼저 판단하는 것이 중요합니다.
4. 단계별 SQL 예시
대상: 임시 결과 집합, 실제 테이블 변경 없음
파일 경로: C:\dev\game-ranking-db\sql\01-first-query.sql
첫 쿼리는 아직 테이블을 만들지 않습니다. 문자열 값을 직접 행으로 만들어 "어떤 테이블이 왜 필요한가"를 결과 표로 확인하는 가장 작은 연습입니다.
SELECT 'players' AS entity, '플레이어 계정' AS purpose
UNION ALL
SELECT 'games', '경기 시간과 모드'
UNION ALL
SELECT 'match_results', '플레이어별 경기 결과'
UNION ALL
SELECT 'character_stats', '경기에서 사용한 캐릭터 통계';
SQL을 한 줄씩 이해하기
- 첫
SELECT는 문자열'players'와'플레이어 계정'으로 한 행을 만듭니다. AS entity,AS purpose는 첫 번째 결과의 두 열 이름을 정합니다. 저장된 원본 이름을 바꾸는 명령이 아닙니다.UNION ALL은 위 결과와 아래 결과의 열 개수와 순서를 맞춰 세로로 이어 붙입니다.- 다음
SELECT들은 같은 두 열 구조로games,match_results,character_stats행을 만듭니다. FROM이 없는 이유는 실제 테이블을 읽지 않고 리터럴 값으로 결과를 만들기 때문입니다.
New-Item -ItemType Directory -Force C:\dev\game-ranking-db\sql
Set-Location C:\dev\game-ranking-db
sqlite3 :memory: ".read .\sql\01-first-query.sql"
SQLite가 아직 없다면 2강 설치 후 실행합니다.
예상 실행 결과
players | 플레이어 계정
games | 경기 시간과 모드
match_results | 플레이어별 경기 결과
character_stats | 경기에서 사용한 캐릭터 통계
이 결과는 메모리 데이터베이스에서 잠시 만들어졌다가 프로그램 종료와 함께 사라집니다. 파일이나 테이블을 변경하지 않는 조회이므로 여러 번 실행해도 저장 데이터가 늘어나지 않습니다.
5. 쿼리가 동작하는 이유
SELECT는 행과 열로 구성된 결과를 반환합니다. AS는 결과 열에 의미 있는 이름을 붙이고 UNION ALL은 중복 제거 비용 없이 같은 열 구조의 결과를 아래로 이어 붙입니다.
6. 자주 하는 실수와 안전한 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
다음 강의 연결
다음 강의에서는 SQLite 실행 파일을 준비하고 메모리 데이터베이스와 파일 데이터베이스의 차이를 직접 확인합니다. 2강. SQLite 설치와 CLI로 이어갑니다.
데이터베이스, 관계형 모델, SQL의 역할 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.