zini's blog

MongoDB & Redis 살펴보기 본문

개념정리

MongoDB & Redis 살펴보기

yjzini 2024. 11. 3. 16:59

NoSQL

  • 기본 개념
    • “Not Only SQL”, 즉 비관계형 데이터베이스를 의미
    • 관계형 데이터베이스(RDBMS)와 데이터를 저장하는 방식이 다름
    • 스키마를 미리 정의하지 않아도 데이터를 저장할 수 있는 유연성이 특징
    • 키-값 쌍, 문서, 그래프, 열 기반 등 다양한 유형 존재
    • 높은 확장성과 가용성
    • 실시간 웹 애플리케이션이나 빅데이터를 처리하는데 널리 사용됨
  • RDBMS vs NoSQL DBMS
    • 데이터 구조 차이
      • RDBMS : 테이블 형식으로 데이터 저장, 각 테이블은 행과 열로 구성
      • NoSQL DBMS : 고정된 스키마 없이 데이터 저장 가능, 다양한 데이터 모델 저장 가능
    • 스키마 유연성
      • RDBMS : 미리 정의된 스키마에 따라 저장해야 하며 스키마 변경이 복잡
      • NoSQL DBMS : 스키마 없이도 동적으로 데이터 구조 변경할 수 있어 유연하게 대응함
    • 데이터 관계 관리
      • RDBMS : 외래 키로 테이블 간의 관계 관리, 조인 연산으로 데이터 연결
      • NoSQL DBMS : 조인 없이 데이터 중복 저장을 허용해 높은 성능과 확장성 제공
    • 확장성
      • RDBMS : 수직적 확장을 통해 성능 향상
      • NoSQL DBMS : 수평적 확장 지원해 여러 서버에 데이터 분산하여 대규모 트래픽 처리
  • NoSQL 데이터베이스가 적합한 경우
    • 대규모 데이터 처리가 필요한 경우
    • 빠른 읽기/쓰기 성능이 필요한 경우 (ex. 캐싱, 실시간 게임, 세션 데이터)
    • 스키마가 자주 변경되는 경우
    • 데이터 간의 복잡한 관계를 다룰 필요가 없는 경우 (ex. 각 객체가 독립적)
    • 고가용성과 분산 시스템, 빠른 확장성 등이 필요한 경우
    • 다양한 데이터 모델을 처리해야 하는 경우 (구조적, 반구조적, 비구조적)
    • (도로 정규화된 데이터 구조를 필요로 하거나, 복잡한 트랜잭션, 조인이 필요한 경우에는 RDBMS가 적합)

MongoDB

  • 기본 개념
    • NoSQL DBMS의 한 종류. 2009년 2월 11일 발표됨
    • 문서 지향(document-oriented) 데이터베이스
  • MongoDB의 구조
    • Document: MongoDB의 데이터 저장 기본 단위. 키-값 쌍으로 구성. (RDBMS의 행)
    • Collection: Document들의 집합. 스키마가 유연함. (RDBMS의 테이블)
    • Datebase: Collection들의 집합. MongoDB 최상위 구조.
    • _id: Document가 Collection 단위로 갖는 고유한 값. (RDBMS의 PK)
  • 특징
    • RDBMS의 relationship에 대응되는 것 - embed(내장), reference(참조)
    • ACID 지원 X, BASE 기반 - 데이터 일관성보다 다른 이점이 필요할 때 유용
      • ACID 지원 X
        • 대부분의 NoSQL DBMS들은 RDBMS와 달리 ACID(Atomicity, Consistency, Isolation, Durability) 트랜잭션을 완전히 지원하지 않음
        • 단일 Document 트랜잭션은 가능.
          • 단일 Document 트랜잭션: 단일 Document 내에서의 트랜잭션을 원자적으로 처리하는 것.
          • 즉 한 Document 여러 필드의 업데이트가 함께, 동시에 이루어질 수 있음.
        • 다중 Document 트랜잭션이 제한적
          • 여러 Document에 걸쳐서 데이터를 동시에 업데이트하려면 MongoDB의 제한된 트랜잭션 기능을 사용해야 함(MongoDB 4.0 버전 이상부터 지원).
          • 추가 설정이 필요하고 성능에 영향을 미침.
        • 따라서 다중 트랜잭션을 하기보다는 조인 연산이 필요하지 않도록 관련 데이터를 Embed하여 하나의 Document로 구성하는 방식이 권장됨
      • BASE 기반
        • BASE(Basically Available, Soft state, Eventual consistency) : ACID보다 느슨한 일관성 모델로, 높은 가용성과 분산 시스템에 적합한 성능이 목표
          1. 기본적으로 사용 가능(Basically Available) : 시스템은 항상 응답을 제공하며, 일시적인 고장이나 네트워크 지연에도 높은 가용성을 유지
          2. 소프트 상태(Soft state) : 시스템의 상태는 시간에 따라 변할 수 있으며, 일관성이 항상 보장되지 않음
          3. 최종 일관성(Eventual consistency) : 시스템은 일정 시간이 지난 후에야 최종적으로 일관된 상태를 달성함
    • Document의 데이터 저장 형식 : BSON
      • Document는 JSON 형태로 표현되는데, 실제 저장 시에는 BSON 형식으로 인코딩되어 저장
      • BSON(Binary JSON): JSON과 유사한 형태인데, 이진 데이터 형식을 사용해 다양한 데이터 타입을 지원하고 효율성을 높인 데이터 저장 형식
  • 문법
    • 데이터베이스 및 컬렉션 관련
      • DB 생성 및 선택
        • use database_name // 데이터베이스 선택, 없다면 생성
      • 컬렉션 생성
        • db.createCollection("collection_name")
      • 컬렉션 삭제
        • db.collection_name.drop()
    • 문서 삽입, 문서 삭제
      • 단일 문서 삽입 & 삭제
        • db.collection_name.insertOne({ key1: "value1", key2: "value2" })
        • db.collection_name.deleteOne({ key: "value" })
      • 여러 문서 삽입 & 삭제
        • db.collection_name.insertMany([ { key1: "value1", key2: "value2" }, { key1: "value3", key2: "value4" } ])
        • db.collection_name.deleteMany({ key: "value" })
    • 문서 조회, 문서 업데이트
      • find({필터 조건}, {조회할 필드})
      • updateOne({필터 조건}, {업데이트할 필드})
      • updateMany({필터 조건}, {업데이트할 필드})
        • $set: 특정 필드를 업데이트하는 연산자
        // 모든 문서 조회
        db.collection_name.find()
         
        // 조건부 문서 조회
        db.collection_name.find({key: "valur"})
        
        // 특정 필드만 조회
        db.collection_name.find({}, { key1: 1, key2: 1 })
        
        // 단일 문서 업데이트
        db.collection_name.updateOne(
                { filter_key: "filter_value" },
        	{ $set: { key_to_update: "new_value" } }
        )
        
        // 여러 문서 업데이트
        db.collection_name.updateMany(
        	{ filter_key: "filter_value" },
        	{ $set: { key_to_update: "new_value" } }
        )
    • 인덱스 생성
      • 단일 필드 인덱스 생성
        • db.collection_name.createIndex({ key: 1 }) // 오름차순 인덱스
      • 복합 인덱스 생성
        • db.collection_name.createIndex({ key1: 1, key2: -1 }) // key1 오름차순, key2 내림차순
    • 집계 파이프라인
      • 기본적인 집계 쿼리
        db.collection_name.aggregate([
        	{ $match: { key: "value" } }, // 조건
        	{ $group: { _id: "$group_key", total: { $sum: "$amount" } } } // 그룹화 및 합계
        ])
      • MongoDB에는 네이티브 조인이 없음
      • 집계 파이프라인에서 LeftOuterJoin을 수행하는 $lookup 연산자를 제공
        // orders 컬렉션
        [
        	{ "_id": 1, "customer_id": 1, "amount": 100 },
        	{ "_id": 2, "customer_id": 2, "amount": 200 },
        	{ "_id": 3, "customer_id": 3, "amount": 150 }
        ]
        
        // customers 컬렉션
        [
        	{ "_id": 1, "name": "Alice" },
        	{ "_id": 2, "name": "Bob" }
        	// 고객 ID 3의 정보는 없음
        ]
        
        // $lookup, $unwind 예시
        db.orders.aggregate([
        	{
        		$lookup: {
        			from: "customers", // 조인할 컬렉션 이름
        			 localField: "customer_id", // orders 컬렉션의 필드
        			 foreignField: "_id", // customers 컬렉션의 필드
        			 as: "customer_info" // 결과에 추가할 필드 이름
        		 }
        	},
        	{
        		$unwind: {
        			path: "$customer_info", // 조인된 결과를 펼침
        			 preserveNullAndEmptyArrays: true // 고객 정보가 없는 경우에도 포함
        		 }
        	}
        ])
  • 스키마 설계
    • MongoDB는 application 관점에서 수행되는 query의 성능을 고려해 유연한 설계를 필요로 함
    • 본격적인 설계에 앞서 고려해야 할 사항들이 존재
      • Access Pattern
        • : “애플리케이션이 어떤 쿼리 수행? 어떤 쿼리를 빈번하게 수행? 애플리케이션은 주로 DB에서 데이터를 읽는가/쓰는가?”
        • 이러한 질문들로, 아래와 같은 과정을 통해 collection을 정의
          • 함께 조회되는 경우가 빈번한 데이터들은 같은 collection에 담아, query 횟수 줄임
          • 주로 읽기만 하는 데이터와 자주 업데이트하는 데이터는 별개의 collection에 담음
      • Relation
        • : ERD 엔티티 간에 relation 존재. MongoDB에서는 collection간에 reference할지 embed할지 결정해야 함.
        • Reference: collection 간 참조할 수 있도록 id를 저장하는 것 (데이터 정규화)
        • Embed: 관련된 document 를 통째로 저장하는 것 (데이터 비정규화)
        • 관계형 데이터베이스와 달리 MongoDB에서는 적절한 수준의 비정규화가 필요한 경우가 많음. (복잡한 조인이 불가능하기 때문)
      • Cardinality
        • : 한 테이블이 다른 테이블과 가질 수 있는 관계
        • One-to-One, One-to-Many, Many-to-Many가 존재
        • how many를 고려하는 것이 설계에 필요.
          • 적은 many는 embed, 많은 many는 개별 collection을 두어 reference 하는 것이 바람직.

 

Redis

  • 기본 개념
    • Redis = “Remote Dictionary Server”
    • "키-값" 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형 데이터베이스 관리 시스템
  • Redis의 특징
    • 키-값 저장소(key-value store): 데이터를 “키”와 “값” 쌍으로 저장하는 비관계형 데이터베이스 유형. 데이터 구조가 단순, 빠른 성능.
    • 인메모리: 데이터 저장 및 처리를 RAM(메모리)에서 수행. 빠른 읽기 및 쓰기 성능.
  • Redis의 구조
    • Key: Redis에서 데이터에 접근하는 기본 단위. 각 키는 유일해야 하며, 문자열, 해시, 리스트, 집합 등 다양한 데이터 타입을 가짐.
    • Value: 각 키에 연결된 데이터. 문자열, JSON, 바이너리 데이터 등 다양한 형식 으로 저장이 가능함.
    • DB: Redis는 데이터베이스를 여러 개 생성할 수 있으며, 기본적으로 16개의 데이 터베이스를 지원함.
  • Redis의 활용
    • 캐시 – 데이터베이스 부하 줄이고 응답 시간 단
    • 세션 저장소 - 사용자 세션 정보를 Redis에 저장
    • 메시지 브로커 - 게시/구독(pub/sub) 시스템으로 실시간 통신 구현 가능
    • 실시간 분석 및 통계 수집
    • 분산 락
    • ...

 

EFUB 4주차 세미나 자료를 기반으로 작성된 글입니다.