> [!abstract] Introduction
> 우리가 사는 현실에는 참 많은 일들이 일어납니다. 편의점에서 끼니를 때울 때도 있고, 카페에서 커피를 마실 때도 있고, 마트에서 장을 볼 때도 있죠. 우리에게는 일상의 한 순간일 뿐이겠지만, 편의점, 카페, 마트, 카드사의 입장에서는 반드시 기록으로 남겨두어야 할 순간들입니다. 기업은 수많은 고객에 대한 데이터를 수집해 그 데이터를 바탕으로 의사결정을 내리고, 이를 위해서는 수천만 개에 달하는 대규모의 데이터를 다를 방법이 필요합니다. 이번 글에서는 대규모의 데이터를 다루기 위한 도구인 데이터베이스 관리 시스템*Database-Management System, DBMS*를 소개합니다.
# DBMS와 DB
과거부터 기업이나 정부는 다수의 이용자들에게 정보를 제공하거나 내부에서 필요로 하는 정보를 체계적으로 보관할 필요가 있었다. 이 과정에서 대규모의 데이터를 다룰 도구가 필요했고, 데이터베이스 관리 시스템*Database-Management System, DBMS*는 이러한 수요에 따라 탄생하였다.
데이터베이스 관리 시스템는 서로 연관되어 있는 데이터와 그 데이터를 관리하는 프로그램의 집합으로 정의된다. 크게 두 부분으로 나눌 수 있는데, 서로 연관된 데이터의 집합인 데이터베이스*Database*와 데이터베이스에 보관된 데이터를 다룰 수 있는 프로그램의 집합으로 나눌 수 있다. 데이터베이스는 그 자체만으로는 아무것도 할 수 없는 데이터의 모음집일 뿐이고, 이 데이터베이스를 다룰 프로그램이 있어야 비로소 진가를 발휘한다. 이 프로그램들은 사용자가 데이터베이스에서 필요한 정보를 효율적으로 찾거나 저장할 수 있도록 하는 여러 핵심적인 기능을 제공한다.
## 굳이 DBMS를 쓰는 이유
그런데 이 시점에서 이런 의문을 가질 수 있다.
> [!question]
> 어차피 정보를 저장하는 건데 그냥 파일 쓰면 되지 않나?
물론 우리는 일상적으로 파일 시스템을 사용하고, 오늘날 통용되는 DBMS가 등장하기 전까지는 기업이나 정부에서도 파일 시스템 기반의 데이터베이스 시스템을 사용했다. 그러나 데이터베이스를 다루는 응용 프로그램이 파일 시스템 바로 위에 있다 보니 여러가지 문제가 발생하게 되었다.
### Data Redundancy & Inconsistency
오늘날 파일 시스템에서 텍스트로 된 정보를 저장하는 방식은 매우 다양하다. PDF로 저장해도 되고, 텍스트 파일로도 저장해도 되고, 워드 파일이나 한글 파일로도 저장할 수 있다. 그러나 데이터베이스의 관점에서 보면 이러한 상황은 매우 치명적인데, 같은 데이터여도 다른 형식으로 저장될 수 있고, 서로 내용을 공유하지 않는다는 것을 의미하기 때문이다. 같은 데이터가 반복되는 상황*Data Redundancy*과 같은 정보여도 저장된 곳이 달라 서로 동기화되지 않는 상황*Data Inconsistency*는 데이터베이스에서는 반드시 피해야 할 상황이다.
### 데이터 접근의 어려움
파일 시스템 기반의 데이터베이스 시스템에서는 데이터에 접근하기 위해 특정 언어를 사용한다는 개념 자체가 없었다. 파일 관리자를 쓰거나 터미널에서 `ls`를 쓰는 것처럼 직접 파일을 찾아야 했고, 이렇게 찾은 파일을 해석하는 일은 그 파일의 포맷을 지원하는 응용프로그램에 달려 있었다.
### Data Isolation
또다른 문제는 여러 파일에 분산되어 있는 정보를 찾아야 할 때다. 파일 시스템에서 파일에 담긴 데이터는 기본적으로 파일에 귀속되어 있어 여러 파일에 흩어져 있는 정보를 하나로 모으기 위해서는 우선 각 파일에 접근해서 정보를 가져와야 하는데, 이러한 상황을 데이터 고립*Data Isolation*이라 부른다. 파일 시스템 기반의 데이터베이스 시스템을 설계할 때 고려하지 않은 방향으로 데이터를 검색하게 되면, 데이터 고립 상황에서 분산된 데이터를 모아 원하는 데이터를 만들기 위한 프로그램을 새롭게 설계해야 한다. 그리고 그 작업은 새로운 유형의 검색을 할 때마다 반복된다.
그래서 파일 시스템 기반의 데이터베이스에서는 데이터를 바꿀 때도 문제가 많다. 원하는 작업이 데이터베이스의 파일 구조와 맞지 않을 경우, 검색할 때와 마찬가지로 분산된 정보를 찾아다니며 수정하는 과정을 거쳐야 한다. 특정 데이터에 제약 조건을 추가하고 적용하거나 관련된 데이터를 바꾸는 이러한 작업은 데이터베이스의 크기가 커질 수록 어려워진다.
### Atomicity
파일 시스템 기반 데이터베이스에서 생기는 또 하나의 문제는 바로 동시성*Concurrency*과 관련된 문제다. 데이터베이스는 기본적으로 다수의 사용자가 동시에 이용하는 것이 일반적이다. 그래서 작업이 겹치거나 시스템에 문제가 생기면 작업 도중에 데이터베이스와의 연결이 끊어질 수도 있다. 이러한 상황을 대비하려면 데이터베이스에서 이루어지는 모든 작업에 원자성*Atomicity*를 보장해야 한다. 모든 작업은 끝까지 이루어지거나 아예 실행되지 않은 상태여야 하며, 작업 과정에서 다른 사용자가 간섭하지 못하도록 접근을 막아야 한다.
### 권한
다수의 사용자가 동시에 데이터베이스를 이용할 때 생기는 또 하나의 고민거리는 바로 권한이다. 예를 들어, 고객의 개인정보처럼 민감한 데이터는 특정 사용자만 볼 수 있도록 설정해야 하는데, 파일 시스템에서 이렇게 같은 데이터에 대해 사용자마다 권한을 다르게 설정하는 일은 상당히 까다롭다.
## DBMS의 특징
DBMS는 앞서 나열한 문제들을 해결하기 위해 등장하였으며, 주요 특징은 다음과 같다.
### 데이터 모델
데이터베이스 시스템의 기본은 데이터 모델*Data Model*이다. 데이터 모델은 데이터베이스에 저장되어 있는 데이터와 데이터의 관계, 데이터의 표현 방식, 그리고 데이터에 대한 일관성 제약 조건*Consistency Constraint*를 포괄하는 개념이다. 대표적인 데이터 모델로는 관계형 모델*Relational Model*, E-R 모델*Entity-Relationship Model*, 반구조화 데이터 모델*Semi-structured Data Model*. 객체 기반 데이터 모델*Object-Based Data Model* 등이 있다.
### 추상화
![[databaseAbstraction.svg]]
이러한 데이터 모델의 공통적인 특징 중 하나는 데이터의 추상화*Data Abstraction*다. 사용자의 편의를 위해 데이터베이스에서 데이터의 추상화는 물리적 수준*Physical Level*과 논리적 수준*Logical Level*, 그리고 뷰 수준*View Level*에서 총 세 번 이루어진다. 물리적 수준에서의 구현과 논리적 수준에서의 구현은 분리되어 있어 사용자는 데이터베이스의 실제 구현을 고려할 필요 없이 논리적 수준에서 데이터를 다루게 된다. 그리고 이에 따라 데이터베이스의 설계 과정과 디자인 또한 물리적 수준과 논리적 수준 모두를 거치도록 하고 있다.
### Data Definition Language & Data Manipulation Language
DBMS에서 데이터를 다루는 방식은 프로그래밍 언어의 그것과 유사하다. 프로그래밍 언어가 자료형을 미리 정해놓듯 DBMS에서도 데이터 정의 언어*Data Definition Language*를 통해 데이터의 규격을 정의한다. 그리고 데이터를 조작하는 방식 또한 데이터 조작 언어*Data Manipulation Language*로 정의하고 있다. 이 과정을 통해 데이터베이스에서 원하는 데이터를 효율적으로 생성하고*Create*, 읽고*Read*, 갱신하고*Update*, 삭제*Delete*할 수 있다.
### 엄격한 데이터 관련 제약 조건
DBMS에서 데이터를 다룰 때는 제약 조건*Constraint*을 꼼꼼히 따져야 하는데, 데이터베이스에서 데이터가 고립되거나 중복되는 등의 문제를 사전에 방지하기 위해 고안된 것이 대부분이다. 대표적인 제약 조건으로는 도메인 제약 조건*Domain Constraint*, 참조 무결성 제약 조건*Referential Integrity Constraint*, 그리고 권한 부여*Authorization* 등이 있다.
도메인 제약 조건은 각 속성에 대해 가능한 값의 범위를 정하는 것으로, 가장 기본적인 형태의 무결성 제약 조건이다. 예를 들어 나이는 양의 정수여야 하고 이름은 문자열이어야 하는 것처럼, 각 속성이 받아들일 수 있는 값의 유형과 범위를 DDL에서 미리 정의해둔다.
참조 무결성 제약 조건은 한 릴레이션에서 다른 릴레이션을 참조할 때, 참조되는 값이 반드시 존재해야 한다는 규칙이다. 이 제약 조건이 없으면 존재하지 않는 데이터를 참조하는 일이 발생할 수 있고, 이는 데이터베이스의 일관성을 심각하게 훼손한다.
권한 부여는 사용자마다 데이터에 대한 접근 권한을 다르게 설정하는 것이다. 파일 시스템에서도 설명했듯이 모든 데이터가 모든 사용자에게 동일하게 공개되어서는 안 되며, DBMS는 사용자별로 읽기*Read*, 삽입*Insert*, 갱신*Update*, 삭제*Delete* 등의 권한을 세밀하게 관리할 수 있다.
### 트랜잭션
트랜잭션*Transaction*은 데이터베이스에서 하나의 논리적인 작업 단위를 나타낸다. 앞서 원자성에서 짧게 언급한 것처럼, 데이터베이스에서 이루어지는 모든 작업은 끝까지 완료되거나 아예 실행되지 않은 상태여야 한다. DBMS는 이러한 원자성*Atomicity*과 일관성*Consistency*[^acid-consistency]을 보장하기 위해 트랜잭션이라는 개념을 도입하였다.
트랜잭션은 여러 연산을 하나의 단위로 묶는다. 예를 들어 은행 계좌에서 송금하는 작업을 생각해보자. 한 계좌에서 돈을 빼고 다른 계좌에 돈을 넣는 두 연산은 반드시 함께 성공하거나 함께 실패해야 한다. 돈을 뺐는데 넣는 데 실패하면 돈이 사라지는 셈이니까. DBMS의 트랜잭션 관리 컴포넌트는 이러한 상황을 방지하고, 시스템에 장애가 발생하더라도 데이터베이스가 일관된 상태를 유지하도록 보장한다.
## 인스턴스와 스키마
데이터베이스를 이해하는 데 있어 핵심적인 구분은 인스턴스*Instance*와 스키마*Schema*의 차이다. 이 구분은 프로그래밍 언어에서 자료형과 변수의 관계와 닮아있다.
스키마는 데이터베이스의 전체적인 설계도로, 데이터베이스에 어떤 데이터가 어떤 구조로 저장되는지를 정의한다. 프로그래밍 언어의 자료형 정의에 해당하며, 자주 변경되지 않는다. 반면 인스턴스는 특정 시점에 데이터베이스에 저장되어 있는 실제 데이터의 모음으로, 변수에 담긴 실제 값에 해당한다.
앞서 데이터 추상화를 세 단계로 나누었듯이 스키마도 그에 대응하는 세 수준으로 나뉜다.
- **물리적 스키마**는 데이터가 실제로 디스크에 어떻게 저장되는지를 기술한다.
- **논리적 스키마**는 데이터베이스에 어떤 데이터가 어떤 관계로 저장되는지를 기술한다. 데이터베이스 설계에서 가장 중요한 수준이다.
- **뷰 스키마**는 특정 사용자에게 보이는 데이터의 모습을 기술한다.
물리적 스키마가 변경되더라도 논리적 스키마에는 영향을 주지 않는 성질을 물리적 데이터 독립성*Physical Data Independence*이라 부르며, 이는 DBMS의 핵심 장점 중 하나다. 응용 프로그램은 논리적 스키마에 의존하므로 물리적 저장 구조가 바뀌어도 프로그램을 수정할 필요가 없다.
## 데이터베이스 엔진
![[dbmsEngineArchitecture.svg]]
DBMS의 내부 구조는 크게 세 가지 주요 컴포넌트로 나눌 수 있다.
### 저장소 관리자
저장소 관리자*Storage Manager*는 데이터베이스에 저장된 하위 수준의 데이터와 응용 프로그램 및 질의 사이의 인터페이스를 제공하는 컴포넌트다. 운영체제의 파일 관리자와 상호작용하여 디스크에 저장된 데이터를 효율적으로 저장하고 검색하는 역할을 담당한다. 내부적으로는 권한 및 무결성 관리자, 트랜잭션 관리자, 파일 관리자, 버퍼 관리자[^buffer-manager] 등의 하위 컴포넌트로 구성되며, 데이터 파일*Data File*, 데이터 사전*Data Dictionary*, 인덱스*Index* 등의 자료구조를 관리한다.
### 질의 처리기
질의 처리기*Query Processor*는 사용자가 보낸 질의를 해석하고, 최적화하여 실행하는 컴포넌트다. DDL 인터프리터가 DDL 문을 해석하여 데이터 사전에 기록하고, DML 컴파일러가 DML 문을 질의 평가 엔진*Query Evaluation Engine*이 이해할 수 있는 하위 수준의 명령어로 변환한다. 이 과정에서 질의 최적화*Query Optimization*가 이루어지는데, 같은 결과를 내는 여러 실행 계획 중 비용이 가장 낮은 것을 선택하는 작업이다.
### 트랜잭션 관리자
트랜잭션 관리자*Transaction Manager*는 데이터베이스의 일관성을 유지하는 핵심 컴포넌트다. 동시에 여러 트랜잭션이 실행될 때 이들이 서로 간섭하지 않도록 동시성 제어*Concurrency Control*를 수행하고, 시스템 장애가 발생했을 때 데이터베이스를 장애 이전의 일관된 상태로 복구하는 회복*Recovery* 기능을 담당한다.
## 데이터베이스 설계
![[databaseDesignProcess.svg]]
데이터베이스 설계는 데이터베이스의 스키마를 만드는 과정이다. 설계의 첫 단계에서는 데이터베이스 사용자의 데이터 요구 사항을 정확히 파악해야 한다. 이를 바탕으로 개념적 설계 단계에서 데이터 모델을 선택하고, 이 모델을 사용하여 요구 사항을 데이터베이스의 개념적 스키마로 변환한다. 이 단계에서는 주로 [[Entity-Relationship Model]]이 사용된다.
개념적 설계가 완료되면 논리적 설계 단계로 넘어간다. 이 단계에서는 개념적 스키마를 DBMS가 실제로 구현할 수 있는 논리적 스키마, 예를 들어 관계형 스키마로 변환한다. 이 과정에서 [[Functional Dependency]]와 [[Decomposition]]의 개념이 활용되어 스키마가 "좋은 형태"를 갖추도록 정제된다.
마지막으로 물리적 설계 단계에서는 데이터베이스의 물리적 레이아웃을 결정한다. 파일 구성 방식과 내부 저장 구조를 설정하고, [[B+ Tree]]와 같은 인덱스 구조를 선택하여 데이터 접근 효율을 높인다.
## 데이터베이스 아키텍처
![[databaseArchitecture.svg]]
데이터베이스 시스템의 아키텍처는 데이터베이스가 운용되는 컴퓨터 시스템에 크게 영향을 받는다. 중앙 집중식*Centralized* 아키텍처에서는 하나의 서버에서 모든 것을 처리하고, 클라이언트-서버*Client-Server* 아키텍처에서는 서버가 데이터베이스 연산을 담당하고 클라이언트는 사용자 인터페이스를 담당한다.
현대의 데이터베이스 시스템은 대부분 2계층*Two-tier* 또는 3계층*Three-tier* 아키텍처를 채택하고 있다. 2계층 아키텍처에서는 응용 프로그램이 클라이언트에서 직접 데이터베이스 서버와 통신한다. 3계층 아키텍처에서는 클라이언트와 데이터베이스 서버 사이에 응용 서버*Application Server*가 위치하여 비즈니스 로직을 처리하는데, 웹 애플리케이션에서 흔히 볼 수 있는 구조다.
---
## 출처
- Silberschatz, A., Korth, H. F. & Sudarshan, S. (2020) *Database System Concepts*. 7th edn. New York: McGraw-Hill.
[^acid-consistency]: 여기서의 일관성은 데이터베이스가 트랜잭션 전후로 모든 무결성 제약 조건을 만족하는 상태를 유지해야 한다는 의미다. 데이터 불일치*Data Inconsistency*에서 말하는 일관성과는 구분된다.
[^buffer-manager]: 버퍼 관리자는 디스크와 메인 메모리 사이에서 데이터를 전송하는 역할을 담당한다. 디스크 입출력은 메모리 접근에 비해 수만 배 느리기 때문에, 버퍼 관리자가 자주 사용되는 데이터를 메모리에 캐싱하여 디스크 접근 횟수를 줄이는 것이 성능에 결정적인 영향을 미친다.