본문 바로가기

데이터베이스/이론

왜 데이터베이스를 사용해야 하는가?

요즘 웹 서비스를 개발할 때는 거의 모든 경우 데이터베이스를 사용할 것이다. 그런데 이런 데이터를 서버에 그냥 텍스트나 json 파일로 저장해서 읽고 쓰는 것과 어떤 차이가 있기 때문에 사용하는 걸까? 앞으로 백엔드 분야로 취업을 희망하고 있는 만큼 데이터베이스에 대해서도 공부를 좀 해보려고 한다.

데이터베이스?

먼저 데이터베이스에 대한 위키피디아의 정의는 다음과 같다.

여러 사람이 공유하고 사용할 목적으로 통합 관리되는 정보의 집합이다. 논리적으로 연관된 하나 이상의 자료의 모음으로 그 내용을 고도로 구조화함으로써 검색과 갱신의 효율화를 꾀한 것이다. 즉, 몇 개의 자료 파일을 조직적으로 통합하여 자료 항목의 중복을 없애고 자료를 구조화하여 기억시켜 놓은 자료의 집합체라고 할 수 있다.

단순히 파일에 데이터를 저장한다면 구조화라고 해봤자 디렉터리 별로 분류하거나 파일 이름 규칙일 뿐인데 이는 검색과 갱신의 효율화라고 보긴 어려울 것이다. 그래서 고도로 구조화된 형태로 데이터를 구축하고 효율적인 검색, 갱신, 중복 제거 등 추가적인 기능을 제공하는 자료의 집합체를 데이터베이스라 할 수 있을 것이다.

일반 파일과 비교

물론 데이터를 파일에 그냥 한줄한줄 쓰지 않고 나름 사전형 구조를 갖춘 json 파일을 사용하면 읽고 쓰기도 편하고 SQL 쿼리 같은 것을 사용할 필요도 없기 때문에 편하지 않나?라고 생각할 수 있지만 데이터의 관계가 복잡해지고 그 크기가 늘어난다면 언젠가 단순한 json 파일로는 감당할 수 없을 때가 올 것이다.

 

그리고 한 파일에 두 사용자가 동시에 읽고 쓰는 레이스 컨디션(동시성 문제)에 대한 해결책이나 서버 크기 확장, 서버 다운 시 백업 플랜, 롤백 등 다양한 비즈니스 요구사항에 부응하기 위해서는 직접 프로그램을 작성하기보다 데이터베이스가 제공하는 기능을 활용하는 게 훨씬 효율적이기 때문에 데이터베이스를 활용하는 것이다.

 

웃기지만 데이터베이스에 저장되는 자료들도 결국 서버의 드라이브 어딘가에 저장되기 때문에 어떻게 보면 중간에 많은 과정이 있을 뿐 결국 파일에 저장하는 것과 마찬가지다.

데이터베이스의 기능

파일에 저장하지 않고 데이터베이스를 사용할 경우 얻을 수 있는 장점들은 다음과 같다.

  • 데이터를 조회(query)할 수 있다. 즉 단순 탐색이 아니라 질문을 할 수 있다.

  • JOIN 명령어를 사용하여 다른 곳에 있는 데이터를 합칠 수 있다.

  • 대용량의 데이터를 쉽게 갱신, 탐색할 수 있다.

  • 장애를 허용(fault-tolerant)한다.

  • 데이터의 중복을 최소화하고 무결성을 유지할 수 있다.

  • 쉽게 확장할 수 있다.

  • 여러 사용자가 접근할 수 있으며 동시성을 보장한다.

  • ACID 원칙을 보장한다.

이 중 제일 중요한 것이 동시성, ACID 원칙이다. ACID는 데이터베이스 트랜잭션이 일어날 때 시스템 에러나 전력 공급 중단 등의 문제가 발생해도 보장되어야 하는 4가지 원칙이다. 즉 트랜잭션이란 이 ACID 원칙을 만족하며 동시성 제어(동시에 수행되는 트랜잭션 제어), 회복 제어(데이터베이스 업데이트 중 장애 발생 시 복구) 모듈을 갖춘 데이터베이스 연산(추가, 조회, 삭제 등)의 모임이다. 이 원칙은 다음과 같다.

  • Atomicity: 하나의 트랜잭션에 포함된 여러 쿼리(statement)는 전체가 실패하거나 성공해야 한다. 즉 한 트랜잭션은 여러 트랜잭션으로 분리될 수 없는 원자성(atomic)을 가진다.

  • Consistency: 한 트랜잭션이 실행된 후 데이터베이스는 유효한(valid) 상태를 유지하고 있어야 한다. 트리거나 다른 요소에 의해 현재 데이터베이스가 유효하지 않다고 판단될 경우 해당 트랜잭션을 취소(rollback) 해야 한다.

  • Isolation: 여러 트랜잭션이 가해질 때 데이터베이스에서는 한 번에 하나의 트랜잭션만 처리해야 한다.

  • Durability: 트랜잭션이 실행(commit)되면 그 결과는 시스템 장애가 발생해도 유지되어야 한다. 즉 데이터를 비휘발성 메모리에 저장해야 한다는 것이다.

어찌 보면 당연한 원칙이고 실제로도 쉽게 구현할 수 있는 요구사항이 아닌가 싶지만 수많은 사용자들이 매우 빠르게 그리고 거의 동시에 트랜잭션 요청을 보낼 때 이 원칙들이 확실하게 지켜지는지 보장하는 것은 쉬운 일이 아닐 것이다.

 

특히 데이터를 그냥 파일로 저장할 때는 이 중요한 원칙들이 보장되리란 확신이 없다. 수많은 사용자가 접속해서 동시에 파일을 수정하는 트랜잭션을 보내면 분명 하나의 파일에 여러 트랜잭션이 거의 동시에 가해지는 경우도 발생할 수 있는데 이때 동시성을 보장하지 못하면 원치 않는 결과가 발생할 수도 있기 때문이다. 예를 들어 어떤 은행 계좌에서 예금을 인출하는 예를 들어보자.

10000원이 있는 계좌에서 3000원씩 인출한다면 일반적으로는 1000원만 남았을 때 3000원 인출이 불가능해야 한다. 즉 트랜잭션이 실패해야 할 것이다. 하지만 만약에 거의 동시에 두 사용자가 3000원씩 인출한다면 어떨까?

이 경우 위처럼 불가능한 인출(4000원에서 6000원을 인출)이 발생할 수 있다. 이것이 발생하는 이유는 다음과 같다.

파일 또는 데이터베이스에 저장된 계좌의 잔액(4000)에서 3000원을 인출하려면 파일에서 계좌의 잔액 값을 읽어서 3000을 빼서 다시 파일에 저장하는 방법을 사용한다고 하자. 그런데 Transaction1, 즉 한 사용자가 3000원을 인출하고 있는 로직 중간에 Transaction2, 즉 다른 사용자가 3000원을 인출하려고 하면 어떻게 될까? 

 

Transaction1에서는 3000원을 인출한 후 잔액인 1000원을 아직 파일에 저장하지 않았기 때문에 Transaction2에서는 Transaction1이 3000원을 인출하기 전의 계좌 값인 4000을 읽어 아직 계좌에 4000원이 남아있다고 판단하여 자기도 3000원을 인출하려고 시도하게 되는 것이다. 이 경우 둘 다 자기는 계좌에 4000원이 남아있다고 읽었으니 3000원을 인출해도 문제가 없다고 판단하게 되어 두 번의 3000원 인출이 발생하게 된다. 이는 ACID 원칙 충 Isolation에 위배된다.

 

그렇다면 트랜잭션이 발생할 때 다른 트랜잭션이나 파일이 자신과 같은 데이터에 접근 중일 경우 좀 기다렸다가 수행하거나 아니면 트랜잭션 자체를 취소하면 되지 않을까? 하지만 현재로서는 트랜잭션이 다른 트랜잭션에 대한 정보를 얻을 수 있는 방법이 없다. 그렇기 때문에 ACID 원칙을 준수하여 이 트랜잭션들을 관리하고 한 번에 하나의 트랜잭션만 발생할 수 있도록 조정해주는 데이터베이스가 필요해지는 것이다.

 

물론 데이터베이스도 그리 쉬운 것은 아니기 때문에 데이터베이스 전문가(DBA)가 필요하고 비용 부담이라던가 백업, 복구의 문제가 있으니 정말 사소한 데이터만 다루는 경우 SQLite 같은 가벼운 데이터베이스나 그냥 파일로 저장하는 방법을 고려하는 것도 괜찮을 것이다.

 

이는 학부 시절에 듣던 운영체제 수업에서 발생할 수 있는 문제(레이스 컨디션 환경에서 메모리 상의 데이터 접근)를 기반으로 든 예시다.

 

 

물론 데이터베이스의 기능이 이것만 있는 게 아니지만 제일 이해하기 쉬운 기능을 예로 들어서 포스트를 작성해보았다. 다음에는 데이터베이스에 어떤 종류가 있고 어떤 상황에 어떤 데이터베이스를 사용해야 하는지 조사해보겠다.

 

[참고 | softwareengineering.stackexchange.com/questions/190482/why-use-a-database-instead-of-just-saving-your-data-to-disk]

[참고 | en.wikipedia.org/wiki/ACID]

[참고 | ko.wikipedia.org/wiki/데이터베이스]