소프트웨어 개발

'NoSQL'에 대해 알아보자

hyunjuuun.dev 2024. 2. 12. 23:35

 

NoSQL이란?

NoSQL에 대해 알아보기에 앞서 먼저 RDB의 단점을 알아보자.
 

변경에 대한 확장성 부족

변화된 요구 사항에 맞춰서 기존 테이블에 새로운 컬럼을 추가해 주어야 하는 일이 발생한다. 이때 새로운 컬럼을 추가해 주기 위해서는 반드시 DB 스키마의 변경이 필요하다.
그런데 요구 사항에 맞춰 새로운 컬럼을 추가해 주어야 하는 테이블에 이미 쌓인 데이터가 엄청나게 많다면 어떻게 될까?
기존에 쌓인 대량의 데이터에 대해 추가된 컬럼의 데이터를 적절히 넣어주어야 하기 때문에 write 하는 시간이 많이 소요될 것이고 그만큼 DB 서버는 큰 부담을 가지게 될 것이다. (결국 어플리케이션 자체에 안 좋은 영향을 주고 장애로 이어질 수도 있을 것이다.)
이처럼 RDB는 테이블의 변경에 있어 확장성이 부족하다고 할 수 있다.
 

정규화로 인한 단점 존재

기본적으로 RDB를 설계할 때는 데이터 중복이 발생하지 않도록 정규화를 진행한다.
중복된 데이터를 최소화할 수 있는 것은 분명한 장점이지만 정규화를 하여 분리된 테이블로 만들어둔 데이터들을 함께 조회하기 위해서는 join 문이 많이 들어가게 되고 이로 인해 cpu 사용량, 응답 시간 등이 늘어나게 된다.
복잡한 join 문은 결국 조회 성능을 떨어지게 만든다.
 

대용량 트래픽이 몰려왔을 때 생기는 이슈

RDB에 많은 양의 Read/Write 요청이 몰리게 되면 scale up을 통해 디비의 성능을 향상시켜 처리할 수 있다. (더 나은 CPU/Memory 성능을 가진 서버로 대체)
레플리케이션을 이용해 처리할 수도 있다.
레플리케이션이란?
사용자의 요청을 처리하는 데이터베이스 A가 존재한다고 할 때 A의 데이터를 똑같이 복사해서 가지고 있는 데이터베이스 B,C를 구성한다.
이렇게 구성한 B,C 데이터베이스 읽기 전용(read-only) 데이터베이스로 사용하여 select 요청의 경우에는 A,B,C가 나눠서 처리할 수 있게 해주면 A가 감당해야 하는 트래픽을 분산 시켜 줄 수 있게 된다.
하지만 write 요청 트래픽이 많은 상황이라면 어떻게 될까?
B,C 데이터베이스는 읽기 전용 데이터베이스이므로 결국 A가 전체적인 부하를 모두 담당하게 될 것이다.
이외에도 multi-master, sharding 같은 방법으로도 문제를 해결할 수 있겠지만 일반적으로 RDB는 스케일 아웃에 유연한 DB가 아니다.
 

NoSQL

NoSQL이 등장하게 된 계기

NoSQL은 어떻게 등장하게 되었을까?
인터넷의 급격한 보급과 함께 SNS 등 다양한 글로벌 서비스들이 많이 등장하게 되었다.
자연스럽게 아래와 같은 사항들을 충족시켜야만 하게 되었다.
high-throughput(높은 처리량)
low-latecny(짧은 응답시간)
다양한 요구 사항에 따른 비정형 데이터의 증가
위와 같은 사항들을 충족시키기 위해 기존 RDB의 단점을 커버하기 위한 mongoDB, redis, DynamoDB와 같은 NoSQL들을 사용하게 되었다.

NoSQL의 일반적인 특징

NoSQL은 각 서비스마다의 특징을 가진다. 여기서는 각 서비스의 특징보다는 일반적인 특징에 대해 이해해 볼 것이다.

NoSQL 특징 - flexible schema

create table player (
    id int primary key,
    name varchat(20)
)

기존의 SQL 같은 경우에는 create 문으로 생성하려는 테이블의 구조를 정의한다.
 

db.createCollection("player")

반면 mongoDB에서는 컬렉션(SQL에서의 테이블)을 위와 같이 생성해 준다.
 

db.player.insertOne({
	name: "Kim"
})

데이터를 넣어주고 싶으면 위와 같이 하면 된다. (mongoDB에서는 json 형태를 사용한다.)
별도로 스키마 구조에 대해 미리 정의할 필요 없이 데이터를 자유롭게 넣어줄 수 있는 것을 확인할 수 있다.
 

db.player.insertOne({
	name: "Son"
    team: {
    	league: "epl",
        name: "tottenham"
    }
})

이전에 넣었던 정보와 다르게 별도 정보 또한 위와 같이 추가할 수 있다.
 
조회는 어떨까?

db.player.find({
	name: "Son"
})

위처럼 명령어를 수행하면 해당하는 document(SQL에서의 row)를 가져올 수 있다.
 
전체 데이터 조회까지 살펴보자.

db.student.find({})

위와 같이 수행하면 전체 도큐먼트를 조회할 수 있다.
RDB의 경우 스키마의 관리를 RDBMS에서 처리했다면 NoSQL의 경우에는 이러한 스키마의 관리를 application 레벨에서 처리해 주어야 한다.
 

NoSQL 특징 - 중복 허용

RDB는 정규화를 통해 중복된 데이터를 최대한 제거하는 방식으로 구조 설계를 진행한다.
중복된 데이터 제거라는 장점이 있지만 이로 인해 join으로 인한 성능에서의 단점이 발생한다.
반면 NoSQL의 경우에는 중복된 데이터라도 각각의 도큐먼트에 저장해 줌으로써 위와 같은 단점을 없앨 수 있다.
일반적인 SQL에서 join을 통해 필요한 정보를 가져오는 것과 달리 NoSQL에서는 필요한 정보들이 이미 도큐먼트에 담겨있으므로 한 번에 가져오면 될 것이다.
(이를 위해 application 레벨에서 중복된 데이터들이 각각 최신 데이터를 유지할 수 있도록 관리가 필요하다.)
 

NoSQL 특징 - 스케일 아웃에 유리함

NoSQL을 사용할 때는 일반적으로 서버 여러 대로 하나의 클러스터를 구성하여 사용한다.
데이터를 나누어서 저장하더라도 join이 필요하지 않으므로 각각의 도큐먼트에 있는 정보들을 활용하여 원하는 데이터 처리가 가능할 것이다.

NoSQL 특징 - ACID를 조금 포기하고 높은 처리량과 빠른 응답속도를 추구

금융 시스템과 같이 consistency가 중요한 환경에서는 사용하기가 부담스러운 측면이 있다.