[Database] (쉬운 코드) NoSQL 개념
쉬운 코드 강의 「데이터베이스」 내용을 바탕으로, NoSQL 개념에 대한 내용을 정리한 포스트 입니다.
relational database 단점
NOSQL을 알아보기 전 relational database에 대해 간략히 알아보자.
relational database같은 경우 새로운 컬럼을 추가하기 위해서 schema를 변경해야한다. 하지만, 이러한 방식은 서비스가 운영중일 때 schema를 변경하면 DB 서버와 application 에도 영향을 줄 수 있어 사용자에게 불편함을 줄 수 있다.
즉, relational database는 schema가 고정되어 있어 유연성이 떨어진다.
또 다른 단점으로 중복 제거를 위해 정규화로 인해 데이터가 여러 테이블로 분리가 되기 때문에 join을 통해 데이터를 가져와야한다. 이 과정에서 성능 저하가 발생할 수 있다.
RDB는 기본적으로 한 대의 컴퓨터에 저장하기 때문에 scale up에 한계가 있다. 이러한 한계를 극복하기 위해서 replication을 사용할 수 있지만 이는 read 성능을 향상시킬 수 있지만 write 성능을 향상시킬 수 없다.
이러한 문제 해결을 위해 multi-master, sharding 같은 방법도 있지만 일반적으로 RDB는 scale-out에 유연한 DB가 아니다.
- scale up : 서버의 성능을 향상시키기 위해 하드웨어를 업그레이드하는 방식
- scale out : 서버의 수를 늘려 성능을 향상시키는 방식
transaction ACID 또한 relational database의 장점이자 단점이다. ACID를 보장하려다 보니 DB 서버의 performance에 어느 정도 영향을 미친다.
NoSQL
2000년대 초·중반에 인터넷이 엄창나게 보급되면서 SNS와 같은 서비스가 많이 등장했다. 이러한 서비스들을 기본 RDBMS로만 운영하기에는 여러 문제점이 있었다.
이떄 당시 요구되었던 데이터베이스의 특징은 다음과 같다.
- high-throughput
- low-latency
- 비정형 데이터의 증가
이러한 요구사항을 해결하기 위해 등장한 것이 NoSQL(Not Only SQL)이다.
NoSQL의 특징
flexible schema : RDB의 table과 유사한 개념인 collection을 생성하며 이때 schema를 지정하지 않는다.
아래 코드는 MongoDB를 기준으로 작성된 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
db.createCollection("student") db.student.insertOne({name: "easycode"}) db.student.insertOne({ name: "hope", address: { country: "Korea", state: "Seoul", city: "Gangnam-gu" street: "blurblur" }, certificate: ["AWS solution architect"] }) db.student.fine({name: "easycode"}) """ { "_id": ObjectID("631231231231231231231231"), "name": "easycode" } """ # 전체 데이터 조회 db.student.find({})
- MongoDB는 데이터를 추가/조회할 때
JSON형식을 사용한다. _id는 각 데이터에 자동적으로 부여되는 고유한 값이다.- 조회해서 나온 출력값을 row가 아닌
document라고 부른다. - RDB는 스키마를 RDBMS에서 관리하지만 NoSQL은 application에서 관리한다.
- MongoDB는 데이터를 추가/조회할 때
- 중복 허용
- join을 회피하기 위해 중복을 허용한다.
- 모두 최신 데이터를 유지할 수 있도록 application 레벨에서 중복된 데이터를 관리해야함
- scale-out
- 서버 여러 대로 하나의 클러스터를 구성하여 사용
- 각각의 서버에 데이터를 나눠서 저장
- ACID의 일부를 포기하고 high-throughput, low-latency 추구
단, 금융 시스템처럼 consistency가 중요한 환경에서는 사용하기가 조심스럽다.
Redis
Redis는 key-value를 저장하는 데이터베이스로 in-memory database이기 때문에 캐쉬로도 사용한다.
SET name easycode
GET name # easycode 출력
위 코드를 실행하면 key는 name이며 value는 easycode로 저장된다.
SET: key-value를 저장하는 명령어GET: key에 해당하는 value를 가져오는 명령어DEL: key에 해당하는 value를 삭제하는 명령어- value로 저장될 수 있는 데이터 타입 : string, list, set, hashes, sorted sets, …
- hash-based sharded cluster
- High Availablity(replication, automatic failover)
주로 Redis는 memory-cache라서 DB에 비해 매우 빠르기 때문에 DB앞에 위치한다.
유튜브 영상을 하나의 예로 들어보자.
일반적으로 영상 데이터는 DB에서 조회된다. 그런데 특정 영상의 인기가 많아지면, 해당 영상에 대한 요청이 급증하면서 DB 서버로 향하는 트래픽이 증가하고, 이는 DB 서버에 부하를 유발할 수 있다.
이때 Redis를 사용해 인기 영상을 캐싱해두면 DB로 직접 접근하는 횟수를 줄일 수 있다.
즉, 데이터를 조회할 때 먼저 Redis에 해당 데이터가 있는지 확인하고,
- 데이터가 있으면 Redis에서 바로 가져오고
- 없다면 DB에서 조회한 후 Redis에 저장한다.
이때 Redis에는 key-value 형태로 데이터를 저장하며, TTL(Time-To-Live)을 설정해 일정 시간이 지나면 자동으로 삭제되도록 할 수 있다.