1부 · 왜 데이터베이스이고, 왜 SQL인가
← 목차로 · 다음: 2부 테이블과 데이터 타입 →
이 부에서 우리는 "데이터베이스가 왜 필요한가"를 엑셀의 한계에서 출발해 이해하고, 설치랄 게 거의 없는 SQLite로 첫 데이터베이스를 만들어 첫 질문을 던집니다. 이론은 짧게, 손은 빨리.
전체 그림에서 보면 이 부는 출발선입니다.
flowchart LR
A[테이블 구조 정하기] --> C[행 추가]
C --> E[묻기 · SELECT]
E --> done[결과를 본다!]
classDef ddl fill:#e8d5f2,stroke:#9b59b6,color:#000
classDef dml fill:#d5e8f2,stroke:#3498db,color:#000
classDef query fill:#d5f2e0,stroke:#27ae60,color:#000
classDef goal fill:#fff3a0,stroke:#f1c40f,color:#000,stroke-width:2px
class A ddl
class C dml
class E query
class done goal
이번 1부에서는 이 전체 흐름을 아주 작은 규모로 한 바퀴 돌려 봅니다. 깊은 설명은 2부부터입니다.
1.1 엑셀로는 왜 부족한가
스프레드시트(엑셀, 구글 시트)는 훌륭한 도구입니다. 많은 데이터 작업은 시트로 충분하고, 시트로 시작하는 게 옳을 때도 많습니다. 문제는 데이터가 자라기 시작할 때 생깁니다.
작은 서점을 예로 들어 봅시다. 처음엔 시트 하나에 책 목록을 적습니다.
| 책 제목 | 저자 | 가격 | 주문한 사람 | 고객 이메일 | 주문일 |
|---|---|---|---|---|---|
| 모비딕 | 허먼 멜빌 | 15000 | 김하나 | hana@mail.com | 2026-01-03 |
| 모비딕 | 허먼 멜빌 | 15000 | 이두리 | duri@mail.com | 2026-01-05 |
| 데미안 | 헤르만 헤세 | 12000 | 김하나 | hana@mail.com | 2026-01-05 |
겉보기엔 멀쩡하지만, 여기엔 여러 문제가 숨어 있습니다.
중복(redundancy). "모비딕 / 허먼 멜빌 / 15000"이 주문될 때마다 통째로 반복됩니다. 김하나의 이메일도 주문할 때마다 다시 적힙니다. 같은 정보를 여러 곳에 베껴 두는 셈입니다.
불일치(inconsistency). 모비딕 가격이 오르면 모든 행을 일일이 고쳐야 합니다. 한 군데라도 빠뜨리면 같은 책이 두 가격을 갖게 됩니다. 김하나가 이메일을 바꾸면? 마찬가지입니다.
질문하기 어려움. "이번 달 가장 많이 팔린 책은?", "김하나가 쓴 총액은?", "한 번도 안 팔린 책은?" 같은 질문에 답하려면 시트를 정렬하고, 필터 걸고, 손으로 세어야 합니다. 데이터가 만 줄이 되면 사실상 불가능합니다.
동시 작업·안전성. 여러 사람이 동시에 같은 시트를 고치면 충돌이 나거나 누군가의 작업이 덮어쓰입니다. 실수로 한 행을 지워도 되돌릴 안전장치가 약합니다.
이 모든 문제의 뿌리는 하나입니다. 서로 다른 종류의 정보(책 / 고객 / 주문)를 한 표에 욱여넣었다는 것. 데이터베이스의 첫 번째 아이디어는 이걸 여러 표로 쪼개고, 표들을 연결하는 것입니다.
flowchart TB
bad["하나의 거대한 시트<br/>책+고객+주문이 뒤섞임"]
bad --> books["📚 books<br/>책 정보만"]
bad --> customers["👤 customers<br/>고객 정보만"]
bad --> orders["🧾 orders<br/>누가 무엇을 언제 샀나"]
orders -.연결.-> books
orders -.연결.-> customers
classDef problem fill:#f5c6cb,stroke:#c0392b,color:#000
classDef data fill:#e8d5f2,stroke:#9b59b6,color:#000
class bad problem
class books,customers,orders data
책 정보는 books에 한 번만, 고객 정보는 customers에 한 번만 적습니다. 주문은 "몇 번 책을, 몇 번 고객이, 언제 샀다"라는 연결 정보만 orders에 담습니다. 가격이 바뀌면 books의 한 줄만 고치면 끝입니다. 이것이 관계형 데이터베이스(relational database) 의 핵심 발상입니다.
1.2 데이터베이스와 SQL, 한 줄 정의
데이터베이스는 데이터를 구조화해서 저장하고, 안전하게 유지하며, 빠르게 꺼낼 수 있게 해 주는 시스템입니다. 그중 데이터를 위 그림처럼 표(테이블) 여러 개로 나누고 서로 관계 지어 저장하는 방식을 관계형 데이터베이스라고 합니다. 우리가 배우는 SQLite, 그리고 실무의 PostgreSQL·MySQL이 모두 여기에 속합니다.
이 데이터베이스에게 "이런 표를 만들어라", "이 데이터를 넣어라", "이 조건에 맞는 행을 보여 달라"고 말하는 언어가 SQL입니다. SQL은 다음과 같이 영어 문장에 가깝습니다.
SELECT title FROM books WHERE price < 13000;
거의 그대로 읽힙니다: "books에서(FROM books) 가격이 13000 미만인(WHERE price < 13000) 책들의 제목을(SELECT title) 골라라." SQL이 초보에게 친절한 이유가 여기 있습니다.
용어 정리. SQL은 "Structured Query Language(구조화 질의 언어)"의 약자입니다. 읽을 때는 "에스큐엘" 또는 "시퀄"이라고 합니다. 표준이 ANSI/ISO로 정해져 있어서, 기초 문법(SELECT,WHERE,JOIN,GROUP BY)은 거의 모든 데이터베이스에서 똑같이 통합니다. 입문자가 배우는 내용의 대략 90%는 다른 DB로 그대로 옮겨 갑니다.
SQL이 다른 프로그래밍 언어와 다른 점
파이썬 같은 언어는 "어떻게(how) 할지"를 한 단계씩 적습니다. 반면 SQL은 "무엇을(what) 원하는지"만 적고, 어떻게 찾을지는 데이터베이스가 알아서 합니다. 이런 방식을 선언형(declarative) 이라고 합니다. "13000원 미만 책을 줘"라고만 하면, 데이터베이스가 알아서 효율적인 방법으로 찾아옵니다. 이 덕분에 초보도 강력한 질문을 짧게 쓸 수 있습니다.
1.3 왜 SQLite로 시작하는가
데이터베이스 제품은 많습니다. 그중 입문에 SQLite를 고른 이유는 분명합니다.
설치가 없습니다. PostgreSQL이나 MySQL은 별도 서버 프로그램을 설치하고 실행해 둬야 합니다. SQLite는 그런 서버가 없습니다. 데이터베이스 전체가 파일 하나(예: bookstore.db)에 통째로 담깁니다. 그 파일을 열면 곧 데이터베이스이고, 복사하면 백업이며, 친구에게 보내면 그대로 공유됩니다.
이미 깔려 있습니다. 파이썬에는 SQLite를 다루는 기능이 표준으로 내장돼 있어, 파이썬만 있으면 추가 설치 없이 바로 됩니다. (스마트폰, 웹브라우저, 수많은 앱이 내부적으로 SQLite를 씁니다. 세상에서 가장 널리 쓰이는 데이터베이스 엔진입니다.)
개념은 그대로 옮겨 갑니다. SQLite로 배운 SELECT·JOIN·GROUP BY는 PostgreSQL에서도 거의 똑같습니다. 입문의 진입장벽만 낮추는 것이지, 배우는 내용이 "장난감"인 게 아닙니다.
솔직한 한계. SQLite는 한 번에 한 명만 쓰기(write)할 수 있어, 수백~수천 명이 동시에 데이터를 바꾸는 대형 서비스의 중심 DB로는 적합하지 않습니다. 그런 곳엔 PostgreSQL·MySQL이 쓰입니다. 다만 읽기 위주 작업, 로컬 분석, 앱 내장 저장소로는 지금도 실무에서 광범위하게 쓰입니다. "입문용일 뿐"이 아니라 "쓰임이 다른" 도구입니다. 우리는 7부에서 언제 다른 DB로 넘어가야 하는지 다룹니다.
이 안내서의 SQLite 버전 기준은 파이썬에 내장된 3.45 계열이며, 우리가 쓰는 기능은 더 옛 버전에서도 동일하게 동작합니다. (SQLite 최신 정식 버전은 2026년 6월 기준 3.53.x입니다.)
1.4 실습 환경 갖추기
실습하는 길은 두 가지입니다. 둘 다 안내하되, 완전초보에게는 GUI 도구(DB Browser) 를 1차로 권합니다. 결과를 표로 바로 보여 주어 학습이 빠릅니다.
방법 A — DB Browser for SQLite (클릭으로, 추천)
DB Browser for SQLite는 SQLite 데이터베이스를 마우스로 열고, 쿼리를 입력하면 결과를 표로 보여 주는 무료 프로그램입니다.
sqlitebrowser.org에서 운영체제(Windows/macOS/Linux)에 맞는 버전을 내려받아 설치합니다.- 실행 후 상단의 New Database(새 데이터베이스)를 눌러
bookstore.db라는 이름으로 저장합니다. 이게 우리 서점 데이터베이스 파일입니다. - 테이블을 만들라는 창이 뜨면 일단 Cancel(취소)합니다. 우리는 SQL로 직접 만들 거예요.
- Execute SQL(SQL 실행) 탭으로 갑니다. 여기에 SQL을 입력하고 ▶ 버튼(또는 F5/Ctrl+Enter)을 누르면 실행됩니다. 결과는 아래 표에 나옵니다.
입력한 데이터를 파일에 영구 저장하려면 변경 후 Write Changes(변경 사항 쓰기) 버튼을 눌러야 합니다. 깜빡하면 닫을 때 사라질 수 있으니 습관을 들이세요.
방법 B — 파이썬으로 (코드로 다루고 싶다면)
파이썬이 깔려 있다면 아무 설치 없이 바로 됩니다. 아래 코드를 try_sqlite.py로 저장하고 python try_sqlite.py로 실행하세요.
# try_sqlite.py — 파이썬 표준 라이브러리만 사용, 추가 설치 불필요 import sqlite3 # bookstore.db 파일에 연결한다(없으면 자동 생성). conn = sqlite3.connect("bookstore.db") cur = conn.cursor() # SQLite 엔진 버전을 물어본다. cur.execute("SELECT sqlite_version();") print("SQLite 버전:", cur.fetchone()[0]) conn.close()
예상 출력(버전 숫자는 환경마다 다를 수 있습니다):
SQLite 버전: 3.45.1
이 코드가 실행됐다면 준비 끝입니다. conn = sqlite3.connect(...)이 연결을 열고, cur.execute(...)이 SQL을 보내고, conn.close()가 연결을 닫습니다. 7부에서 이 패턴을 깊이 다루니 지금은 "이렇게 되는구나"만 보면 됩니다.
이후 챕터의 SQL은 도구에 상관없이 동일합니다. DB Browser의 Execute SQL 칸에 붙여 넣어도 되고, 파이썬 cur.execute()에 문자열로 넣어도 됩니다. 본문에서는 SQL 자체에 집중하기 위해 SQL만 보여 주겠습니다.
1.5 손으로 만드는 가장 단순한 데이터베이스
이제 전체 흐름(설계 → 입력 → 질의)을 가장 작게 한 바퀴 돌려 봅니다. 책 몇 권만 담는 단일 테이블입니다. 아래 SQL을 한 줄씩 실행해 보세요(DB Browser면 전부 붙여 넣고 한 번에 실행해도 됩니다).
① 표 만들기 — CREATE TABLE
CREATE TABLE books ( id INTEGER PRIMARY KEY, title TEXT, author TEXT, price INTEGER );
"books라는 표를 만들어라. 칸은 id(정수, 각 행을 구분하는 고유 번호), title(글자), author(글자), price(정수)로." PRIMARY KEY는 "이 칸이 각 행을 구별하는 대표 번호"라는 뜻입니다. 자세한 건 2부에서 다룹니다.
② 데이터 넣기 — INSERT
INSERT INTO books (title, author, price) VALUES ('모비딕', '허먼 멜빌', 15000); INSERT INTO books (title, author, price) VALUES ('데미안', '헤르만 헤세', 12000); INSERT INTO books (title, author, price) VALUES ('1984', '조지 오웰', 11000); INSERT INTO books (title, author, price) VALUES ('노인과 바다', '헤밍웨이', 9000);
id는 적지 않았는데, INTEGER PRIMARY KEY로 지정한 칸은 SQLite가 1, 2, 3, … 으로 자동으로 번호를 매겨 줍니다.
③ 묻기 — SELECT
전부 보기:
SELECT * FROM books;
*는 "모든 칸"이라는 뜻입니다. 결과:
id title author price -- ---------- ---------- ----- 1 모비딕 허먼 멜빌 15000 2 데미안 헤르만 헤세 12000 3 1984 조지 오웰 11000 4 노인과 바다 헤밍웨이 9000
이제 진짜 질문을 던져 봅시다. 12000원 이하인 책만:
SELECT title, price FROM books WHERE price <= 12000;
결과:
title price ---------- ----- 데미안 12000 1984 11000 노인과 바다 9000
가격이 싼 순으로 정렬:
SELECT title, price FROM books ORDER BY price ASC;
결과:
title price ---------- ----- 노인과 바다 9000 1984 11000 데미안 12000 모비딕 15000
방금 여러분은 데이터베이스를 만들고, 데이터를 넣고, 두 가지 질문에 답을 받았습니다. 시트였다면 필터와 정렬을 클릭했을 일을, 한 줄짜리 문장으로 했습니다. 데이터가 1만 권이어도 이 문장은 그대로입니다. 이것이 SQL의 힘입니다.
pandas를 안다면:SELECT title, price FROM books WHERE price <= 12000은 pandas의df.loc[df['price'] <= 12000, ['title', 'price']]에 해당합니다.ORDER BY price는df.sort_values('price')입니다. 같은 발상을, 디스크에 저장된 데이터에 대고, 표준 언어로 하는 셈입니다.
1.6 정리
이 부에서 본 것을 압축하면:
- 데이터가 자라면 시트는 중복·불일치·질문의 어려움에 부딪힌다. 데이터베이스는 정보를 여러 표로 쪼개고 연결해 이를 해결한다.
- 그 표들을 만들고, 채우고, 묻는 공용 언어가 SQL이다. SQL은 "무엇을 원하는지"만 적는 선언형 언어라 짧고 읽기 쉽다.
- SQLite는 데이터베이스가 파일 하나에 담기고 설치가 사실상 없어 입문에 이상적이다. 배우는 개념은 다른 DB로 그대로 옮겨 간다.
- 가장 단순한 한 바퀴:
CREATE TABLE(만들기) →INSERT(넣기) →SELECT(묻기).
다음 부에서는 이 books 표를 제대로 설계합니다. 데이터 타입은 무엇을 골라야 하는지, 기본키란 정확히 무엇인지, 빈 값(NULL)은 어떻게 다루는지 — 표를 짓는 기초 공사를 합니다.
직접 해 보기
위의 books 테이블을 만든 상태에서 풀어 보세요. 막히면 2부 초반과 부록을 참고하세요.
- 가격이 10000원 이상인 책의 제목과 가격을 골라 보세요. (힌트:
>=) - 모든 책을 제목 가나다순으로 정렬해 보세요. (힌트:
ORDER BY title) INSERT로 좋아하는 책 한 권을 더 추가하고, 다시SELECT * FROM books;로 잘 들어갔는지 확인해 보세요.
← 목차로 · 다음: 2부 테이블과 데이터 타입 →