본문으로 건너뛰기
2026. 7. 12·약 12분

데이터베이스 기본 개념과 용어, 한 번에 정리하기

데이터베이스 원통에서 세 갈래가 나와 각각 한 줄짜리 카드로 들어가는 그림

데이터베이스를 공부하다 보면 테이블, 스키마, 키, 트랜잭션, 인덱스, 정규화, ACID, 샤딩처럼 알 듯 모를 듯한 용어들이 끝없이 쏟아집니다. 하나하나 검색하면 그때는 이해되는데, 돌아서면 서로 어떻게 연결되는지가 다시 흐릿해집니다.

필요할 때마다 흩어진 글을 뒤지는 대신, 한 번 쭉 읽으면 전체 지도가 그려지는 정리가 있으면 좋겠다고 생각했습니다.

데이터베이스를 다루기 위해 알아야 할 기본 개념과 용어는 무엇이고, 서로 어떻게 이어질까요?


이 글에서 다루는 내용​

DBMS와 관계형 모델에서 시작해 SQL·정규화·트랜잭션·인덱스를 설명하고, NoSQL과 분산 확장 용어까지 정리합니다. 특정 제품(MySQL·PostgreSQL 등)의 세부 문법보다 여러 제품에 공통으로 적용되는 개념에 초점을 둡니다.





데이터베이스와 DBMS​

데이터베이스(Database) 는 여러 사람이 함께 쓰기 위해 구조화하여 저장한 데이터의 모음입니다. 그런데 우리가 흔히 "DB를 쓴다"고 할 때 실제로 다루는 것은 데이터 그 자체가 아니라, 그 데이터를 관리하는 소프트웨어입니다. 이 소프트웨어를 DBMS(Database Management System) 라고 부릅니다.

DBMS는 저장·조회·수정·삭제, 동시성 제어, 권한, 백업 기능을 제공합니다. 파일에 직접 데이터를 쓰지 않고 DBMS를 거치는 이유가 여기에 있습니다.

DBMS는 데이터를 어떤 모델로 표현하느냐에 따라 갈립니다. 그중 가장 널리 쓰이는 것이 데이터를 표(table) 형태로 다루는 관계형 데이터베이스 관리 시스템(RDBMS, Relational DBMS)입니다.

  • RDBMS: MySQL, PostgreSQL, Oracle, SQL Server, SQLite 등. 데이터를 행과 열로 이루어진 테이블에 담고, 테이블 사이의 관계로 표현합니다. 이 글의 2~6장이 주로 다루는 대상입니다.
  • NoSQL: MongoDB, Redis, Cassandra 등. 표가 아닌 다른 구조(문서·키값·그래프 등)로 데이터를 다룹니다. 관계형을 넘어서에서 살펴봅니다.



관계형 데이터베이스의 구성요소​

관계형 데이터베이스에서 데이터는 테이블(table) 에 담깁니다. 테이블은 스프레드시트 한 장과 비슷하게 생겼습니다.

  • 행(row, 레코드/튜플): 가로 한 줄. 하나의 데이터 항목입니다. 예를 들어 사용자 한 명.
  • 열(column, 필드/속성): 세로 한 칸. 데이터의 속성입니다. 예를 들어 이메일, 이름.
  • 스키마(schema): 테이블이 어떤 열들로, 각 열이 어떤 자료형(정수·문자열·날짜 등)으로 이루어지는지에 대한 설계도. 데이터가 지켜야 할 틀입니다.

키(Key): 행을 구별하는 기준​

수많은 행 중에서 특정 행을 정확히 가리키려면 기준이 필요합니다. 그 기준이 키입니다.

  • 기본키(Primary Key, PK): 각 행을 유일하게 식별하는 열 또는 열의 조합. 중복될 수 없고 비어 있을 수 없습니다(NOT NULL). 테이블마다 보통 하나 둡니다. id 같은 열이 대표적입니다.
  • 외래키(Foreign Key, FK): 다른 테이블이나 같은 테이블의 기본키 또는 고유 키를 참조하는 열 또는 열의 조합. 테이블 사이를 잇는 다리 역할을 합니다. 예를 들어 주문 테이블의 user_id가 사용자 테이블의 id를 가리킵니다.
  • 후보키·복합키: 기본키가 될 수 있는 후보를 후보키(candidate key), 여러 열을 묶어 하나의 키로 삼은 것을 복합키(composite key)라 합니다.
  • 자연키 vs 대리키: 이메일처럼 업무상 의미가 있는 값을 키로 쓰면 자연키(natural key), 의미 없이 식별만을 위해 새로 만든 id를 쓰면 대리키(surrogate key)입니다. 실무에서는 대리키를 즐겨 씁니다.

제약조건(Constraint): 데이터의 규칙​

테이블에는 "이런 데이터는 허용하지 않는다"는 규칙을 걸 수 있습니다. 이를 제약조건이라 하고, DBMS가 강제로 지켜줍니다.

제약조건의미
PRIMARY KEY행을 유일하게 식별 (중복·NULL 불가)
FOREIGN KEY다른 테이블의 키를 참조, 참조 무결성 보장
UNIQUE값이 중복되지 않도록 강제
NOT NULL값이 비어 있을 수 없음
CHECK특정 조건을 만족하는 값만 허용 (예: 나이 ≥ 0)
DEFAULT값을 지정하지 않으면 쓰이는 기본값

여기서 NULL은 "값이 없음/알 수 없음"을 뜻하는 특별한 상태입니다. 숫자 0이나 빈 문자열과는 다르며, NULL을 다루는 방식은 종종 미묘한 버그의 원인이 되므로 개념을 정확히 잡아두는 것이 좋습니다.




SQL: 데이터베이스와 대화하는 언어​

관계형 데이터베이스와 대화할 때 쓰는 언어가 SQL(Structured Query Language) 입니다. SQL 명령은 역할에 따라 몇 갈래로 나뉩니다.

분류이름대표 명령하는 일
DDL데이터 정의어CREATE, ALTER, DROP테이블·스키마 구조를 만들고 바꿈
DML데이터 조작어INSERT, UPDATE, DELETE데이터를 넣고 바꾸고 지움
DQL데이터 질의어SELECT데이터를 조회함
DCL데이터 제어어GRANT, REVOKE권한을 부여·회수함
TCL트랜잭션 제어어COMMIT, ROLLBACK트랜잭션을 확정·취소함 (5장)

데이터를 다루는 가장 기본적인 네 가지 동작(생성·조회·수정·삭제)을 흔히 CRUD(Create, Read, Update, Delete)라 부르며, 각각 INSERT·SELECT·UPDATE·DELETE에 대응됩니다.


SELECT로 조회하기​

가장 자주 쓰는 것은 조회(SELECT)입니다. 기본 형태는 다음과 같습니다.

-- users 테이블에서 나이가 20 이상인 행의 이름과 이메일을, 이름 순으로 조회
SELECT name, email
FROM users
WHERE age >= 20
ORDER BY name;
  • SELECT: 어떤 열을 가져올지
  • FROM: 어떤 테이블에서
  • WHERE: 어떤 조건의 행만
  • ORDER BY: 어떤 순서로
  • GROUP BY / HAVING: 특정 열 값으로 묶어 집계(합계·개수 등)하고, 집계 결과를 다시 거를 때

JOIN으로 테이블 연결하기​

관계형 데이터베이스는 데이터를 여러 테이블에 나눠 담기 때문에, 조회할 때 이들을 다시 이어붙일 일이 많습니다. 이때 쓰는 것이 JOIN입니다.

-- 주문(orders)과 그 주문을 한 사용자(users)를 이어서 조회
SELECT orders.id, users.name
FROM orders
JOIN users ON orders.user_id = users.id;
JOIN 종류결과
INNER JOIN양쪽 모두에 매칭되는 행만
LEFT (OUTER) JOIN왼쪽 테이블은 전부, 오른쪽은 매칭되는 것만(없으면 NULL)
RIGHT (OUTER) JOIN오른쪽 테이블은 전부, 왼쪽은 매칭되는 것만
FULL (OUTER) JOIN양쪽 모두 전부, 매칭 안 되는 쪽은 NULL
CROSS JOIN두 테이블의 모든 조합(곱집합)



관계와 정규화​

관계형의 "관계"는 수학의 릴레이션(relation)에서 온 말로, 데이터를 튜플의 집합으로 표현한다는 뜻입니다. 테이블끼리 연결되어서 붙은 이름은 아닙니다. 이와 별개로 테이블의 행 사이에는 다음과 같은 연관 관계(relationship)를 설계할 수 있습니다.

  • 1:1 (일대일): 한 행이 상대 테이블의 한 행과만 대응. 예: 사용자 ↔ 사용자 상세정보.
  • 1:N (일대다): 한 행이 상대 테이블의 여러 행과 대응. 가장 흔합니다. 예: 사용자 한 명 ↔ 주문 여러 건.
  • N:M (다대다): 양쪽 모두 여러 행과 대응. 예: 학생 ↔ 수강 과목. 이 관계는 보통 중간에 연결 테이블(join table)을 두어 두 개의 1:N으로 풀어냅니다.

정규화(Normalization): 중복을 줄이는 설계​

정규화는 데이터의 중복과 이상 현상을 줄이기 위해 테이블을 나누는 설계 과정입니다. 예를 들어 주문마다 고객의 현재 전화번호를 함께 저장했다고 해봅시다.

주문 ID고객 ID고객 전화번호
1017010-1111-2222
1027010-1111-2222

7번 고객이 번호를 바꾸면 두 행을 모두 고쳐야 합니다. 하나만 고치면 같은 고객의 현재 번호가 두 개가 되는 갱신 이상이 생깁니다. 고객 테이블에 고객 ID·전화번호를 두고 주문에는 주문 ID·고객 ID만 남기면, 번호는 고객 테이블의 한 행에서 관리할 수 있습니다. 주문과 함께 번호를 조회할 때는 JOIN을 씁니다. 이 예제는 현재 연락처를 다루며, 주문 당시의 연락처를 보관하려는 경우와는 목적이 다릅니다.

무엇을 기준으로 나눌지에 따라 정규화의 단계(정규형, Normal Form)를 구분합니다.

  • 제1정규형(1NF): 각 칸에는 더 쪼갤 수 없는 하나의 값만. (한 칸에 여러 값을 콤마로 넣지 않기)
  • 제2정규형(2NF): 1NF를 만족하고, 복합키의 일부에만 의존하는 열이 없도록 분리.
  • 제3정규형(3NF): 2NF를 만족하고, 기본키가 아닌 열이 다른 일반 열에 의존(이행적 종속)하지 않도록 분리.

위 예제에서는 고객 ID로 결정되는 전화번호를 주문에서 분리했습니다. 3NF에서 다루는 이행적 종속을 제거하는 예입니다. 처음에는 정규형 이름보다 "한 사실을 바꿀 때 몇 행을 고쳐야 하는가"를 먼저 보면 이해하기 쉽습니다.

실무에서는 보통 3NF 정도까지를 기본으로 삼습니다. 조회에 필요한 JOIN이 성능 문제가 되면 일부 정보를 중복 저장하는 반정규화(denormalization) 를 검토하기도 합니다. 그 경우에는 원본이 바뀔 때 복사된 값도 맞춰야 합니다.




트랜잭션과 ACID​

트랜잭션(transaction) 은 "하나의 논리적 작업으로 묶여, 전부 성공하거나 전부 실패해야 하는 여러 연산의 묶음"입니다. 계좌 이체가 고전적인 예입니다. A에서 돈을 빼고 B에 넣는 두 작업은 반드시 함께 성공해야 합니다. 하나만 성공하면 돈이 사라지거나 복제됩니다.

BEGIN; -- 트랜잭션 시작
UPDATE accounts SET balance = balance - 1000 WHERE id = 'A';
UPDATE accounts SET balance = balance + 1000 WHERE id = 'B';
COMMIT; -- 둘 다 성공하면 확정. 문제가 생기면 ROLLBACK으로 전부 취소

ACID: 트랜잭션이 지키는 네 가지 성질​

믿을 수 있는 트랜잭션이 갖춰야 할 성질을 머리글자로 ACID라 부릅니다.

  • 원자성(Atomicity): 전부 성공 아니면 전부 취소. 중간 상태로 남지 않습니다.
  • 일관성(Consistency): 트랜잭션 전후로 데이터가 정해진 규칙(제약조건 등)을 항상 만족합니다.
  • 격리성(Isolation): 동시에 실행되는 트랜잭션들이 서로 간섭하지 않습니다.
  • 지속성(Durability): 커밋된 결과는 시스템이 꺼져도 사라지지 않습니다.

격리 수준(Isolation Level)​

DBMS는 동시에 실행되는 트랜잭션이 서로의 변경을 어디까지 볼 수 있는지 정하는 격리 수준을 제공합니다. 강한 격리는 대기나 재시도 비용을 늘릴 수 있지만 낮은 수준이 언제나 더 빠른 것은 아닙니다. 아래는 수준을 구분할 때 쓰는 대표적인 이상 현상입니다.

  • 더티 리드(dirty read): 아직 커밋되지 않은 다른 트랜잭션의 값을 읽음.
  • 반복 불가능 읽기(non-repeatable read): 같은 행을 두 번 읽었는데 값이 달라짐.
  • 팬텀 리드(phantom read): 같은 조건으로 두 번 조회했는데 조건에 맞는 행의 집합이 달라짐.
격리 수준더티 리드반복 불가능 읽기팬텀 리드
Read Uncommitted발생발생발생
Read Committed방지발생발생
Repeatable Read방지방지발생
Serializable방지방지방지

표의 "발생"은 SQL 표준상 허용된다는 뜻이며 반드시 발생한다는 뜻은 아닙니다. 예를 들어 PostgreSQL의 Repeatable Read는 팬텀 리드도 방지합니다. 다만 이것만으로 Serializable과 같아지는 것은 아닙니다.

DBMS는 잠금(lock) 과 다중 버전 동시성 제어(MVCC) 등을 조합해 동시 접근을 제어합니다. 잠금은 한 트랜잭션이 데이터를 다루는 동안 다른 트랜잭션의 접근을 막거나 대기시키는 장치입니다. 서로가 상대의 잠금 해제를 기다려 진행할 수 없는 상황을 교착 상태(deadlock) 라 합니다. DBMS는 이를 감지하면 보통 한 트랜잭션을 중단해 풀어냅니다.




인덱스로 조회 범위 줄이기​

데이터가 수백만 건인 테이블에서 특정 행을 찾을 때, 처음부터 끝까지 전부 훑으면(풀 스캔, full scan) 느립니다. 인덱스(index) 는 이 조회를 빠르게 하기 위한 별도의 자료구조입니다. 책 뒤의 "찾아보기"와 정확히 같은 발상입니다. 원하는 단어가 몇 페이지에 있는지 미리 정렬해 둔 목록이지요.

대부분의 DBMS에서 인덱스는 B-트리(B-Tree) 계열의 자료구조로 만들어집니다. 값이 정렬된 채로 트리에 담겨 있어, 전체를 훑지 않고도 원하는 값에 빠르게(로그 시간에) 도달할 수 있습니다.


클러스터드 vs 논클러스터드​

  • 클러스터드 인덱스(clustered index): InnoDB처럼 데이터 행을 인덱스의 리프 페이지에 저장하는 구조입니다. 페이지 안의 키 순서와 디스크상의 물리적 연속 배치는 구분해야 합니다. 테이블당 하나만 가능하며, 보통 기본키가 이 역할을 합니다.
  • 논클러스터드 인덱스(non-clustered index): 데이터와 별도로 키와 행을 찾을 정보를 담습니다. InnoDB의 보조 인덱스처럼 기본키를 저장하고 다시 조회하는 방식도 있습니다. 한 테이블에 여러 개 만들 수 있습니다.

이 구분과 저장 방식은 DBMS마다 다릅니다. PostgreSQL의 일반 테이블은 힙에 저장되며 CLUSTER로 한 번 정렬해도 이후 변경에서 그 순서를 자동으로 유지하지 않습니다.

인덱스의 쓰기·저장 비용​

인덱스는 조회를 빠르게 하지만 대가가 있습니다.

  • 쓰기 비용: 데이터를 넣거나 바꿀 때마다 인덱스도 함께 갱신해야 하므로 INSERT·UPDATE가 느려집니다.
  • 저장 공간: 인덱스 자체가 디스크를 차지합니다.
  • 선택도와 쿼리 형태: 카디널리티만으로 인덱스 효과를 판단할 수 없습니다. 값 분포와 선택도, 쿼리 조건, 커버링 여부를 실행 계획으로 확인합니다.

그래서 인덱스는 "많이 걸수록 좋은 것"이 아니라, 자주 조회하는 조건에 선별적으로 거는 것입니다. 조회와 쓰기 사이의 트레이드오프인 셈입니다.




관계형을 넘어서: NoSQL과 확장​

여기부터는 데이터를 어떤 형태로 저장할지, 여러 서버에 어떻게 나눌지로 범위를 넓힙니다. 먼저 NoSQL("Not Only SQL")은 관계형이 아닌 여러 저장 방식을 아우르는 이름입니다. 아래 제품들은 데이터를 다루는 형태가 서로 다릅니다.

유형데이터 형태대표 제품
키-값(Key-Value)키에 값 하나를 대응Redis
문서(Document)JSON 같은 문서 단위MongoDB
컬럼 패밀리(Wide-Column)행마다 다른 열을 가질 수 있는 대용량 테이블Cassandra
그래프(Graph)노드와 간선(관계) 중심Neo4j

문서 구조의 유연성이나 분산 확장을 이유로 NoSQL을 검토할 수 있습니다. 다만 제품마다 데이터 모델과 확장 방식이 다르고, 트랜잭션·일관성·JOIN 지원 범위도 설정에 따라 달라집니다.


CAP 정리​

분산 데이터베이스를 이야기할 때 자주 등장하는 것이 CAP 정리입니다. 여러 노드에 데이터를 나눠 담는 시스템은 다음 셋을 동시에 완벽히 만족할 수 없고, 네트워크 단절(P)이 생긴 순간 일관성과 가용성 중 하나를 택해야 한다는 원리입니다.

  • 일관성(Consistency): 어느 노드에 물어도 같은 최신 값을 답한다.
  • 가용성(Availability): 장애가 나지 않은 노드에 도달한 모든 요청이 결국 결과를 받는다. 단순한 오류 응답이나 무기한 대기로 대신하지 않는다.
  • 분단 내성(Partition tolerance): 노드 사이 통신이 끊겨도 시스템이 동작한다.

결과적 일관성(eventual consistency) 은 새 쓰기가 멈추면 복제본의 값이 결국 수렴한다는 성질입니다. BASE에서 말하는 성질 중 하나지만 BASE 전체와 동의어는 아닙니다. 관계형 여부만으로 일관성 모델이 정해지지는 않으며, ACID의 일관성(업무 규칙 유지)과 CAP의 일관성(선형화 가능성)도 서로 다른 뜻입니다.


규모를 키우는 법: 확장과 분산​

서버 한 대를 더 큰 것으로 바꾸는지, 여러 대로 늘리는지를 먼저 구분합니다. 여러 대를 쓴다면 같은 데이터를 복사할지, 나누어 담을지도 정해야 합니다.

  • 수직 확장(scale-up): 서버 한 대의 사양(CPU·메모리)을 키움. 간단하지만 한계가 있음.
  • 수평 확장(scale-out): 서버 대수를 늘려 부하를 나눔. 확장성이 좋지만 복잡함.
  • 복제(replication): 같은 데이터를 여러 서버에 복사해 둠. 읽기 부하 분산과 장애 대비에 쓰임.
  • 샤딩(sharding): 데이터를 기준에 따라 여러 서버에 쪼개어 나눠 담음. 수평 파티셔닝의 한 형태.
  • 파티셔닝(partitioning): 큰 테이블을 여러 조각으로 나눔. 행 기준(수평)·열 기준(수직)으로 나뉨.

서버를 늘리기 전에 애플리케이션의 DB 사용 방식도 확인해야 합니다. 연결을 매번 새로 만들고 있지 않은지, 목록 하나를 보여주려고 쿼리를 너무 많이 보내고 있지 않은지와 관련된 용어들입니다.

  • 커넥션 풀(connection pool): DB 연결은 만드는 비용이 크므로, 미리 여러 연결을 만들어 두고 돌려 쓰는 방식.
  • N+1 문제: 목록을 한 번 조회한 뒤(1번), 각 항목의 연관 데이터를 항목 수(N)만큼 개별 조회해 쿼리가 폭증하는 흔한 성능 문제. JOIN이나 일괄 조회로 해결합니다.

Recap​

NoSQL은 저장 형태가 다른 여러 방식을 묶어 부르는 이름입니다. 데이터를 여러 서버에 두면 네트워크가 끊겼을 때 어떤 응답을 할지도 정해야 합니다. 규모를 키우는 방법을 검토할 때는 데이터의 복사·분할 방식과 함께 애플리케이션의 연결·쿼리 사용량도 확인합니다.




용어 사전​

아래 표는 본문에서 사용한 용어의 짧은 정의입니다.

용어한 줄 정의
DBMS데이터베이스를 관리하는 소프트웨어
RDBMS데이터를 테이블로 다루는 관계형 DBMS
테이블 · 행 · 열데이터를 담는 표, 그 안의 한 항목(행)과 속성(열)
스키마테이블의 구조·자료형을 정의한 설계도
기본키(PK)각 행을 유일하게 식별하는 열
외래키(FK)다른 테이블의 키를 참조해 관계를 잇는 열
제약조건UNIQUE·NOT NULL·CHECK 등 데이터가 지킬 규칙
NULL"값이 없음/알 수 없음"을 뜻하는 별도 상태
SQL관계형 DB와 대화하는 언어 (DDL·DML·DQL·DCL·TCL)
CRUD생성·조회·수정·삭제, 데이터의 기본 네 동작
JOIN여러 테이블을 이어붙여 조회하는 연산
정규화중복·이상을 줄이려 테이블을 나누는 설계 (1NF~3NF)
반정규화성능을 위해 일부러 중복을 허용하는 설계
트랜잭션전부 성공 또는 전부 실패해야 하는 연산 묶음
ACID원자성·일관성·격리성·지속성
격리 수준안전성과 성능을 조절하는 트랜잭션 격리 단계
잠금(lock) · 교착 상태동시성 제어 장치와, 서로를 기다리다 멈추는 상황
인덱스빠른 조회를 위한 별도의 정렬된 자료구조 (B-트리)
카디널리티열이 가진 값의 다양성 정도
NoSQL관계형이 아닌 방식(키-값·문서·컬럼·그래프)의 총칭
CAP 정리분단 시 일관성과 가용성 중 하나를 택해야 함
복제 · 샤딩 · 파티셔닝데이터를 복사·분할해 규모를 키우는 전략
N+1 문제연관 데이터를 항목 수만큼 개별 조회해 쿼리가 폭증하는 문제



References​

기초 개념

  1. Wikipedia: Database
  2. Wikipedia: Relational model
  3. Wikipedia: SQL

트랜잭션과 정규화

  1. Wikipedia: ACID
  2. Wikipedia: Isolation (database systems)
  3. Wikipedia: Database normalization
  4. PostgreSQL: Transaction Isolation

인덱스와 확장

  1. Use The Index, Luke: SQL 인덱싱 튜토리얼
  2. Wikipedia: Database index
  3. Wikipedia: CAP theorem
  4. Wikipedia: Shard (database architecture)


좋은 사람들과 재미있는 일을 하며 열정적이고 즐겁게 살고 싶은 개발자