ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Database] MongoDB vs MariaDB, 설계 관점 비교 - 3
    업무 자동화/Database 2025. 12. 15. 08:30

    1. 스키마 설계 방식

    1-1. MariaDB (관계형, 정규화 중심)

    • 테이블 단위 설계
    • 각 테이블이 하나의 “엔티티(개체)” 에 해당
    • 정규화(Normalization)를 통해
      • 중복 최소화
      • 데이터 무결성 유지
    • 스키마 변경 = 테이블 구조 변경 (ALTER TABLE)

    간단 예시

    CREATE TABLE users (
        id INT PRIMARY KEY AUTO_INCREMENT,
        email VARCHAR(255) NOT NULL UNIQUE,
        name VARCHAR(100) NOT NULL
    );

    1-2. MongoDB (문서 중심, 읽기 패턴 중심)

    • 도큐먼트 단위 설계
    • 한 도큐먼트 안에 관련 데이터를 중첩해서 넣을 수 있음
    • 스키마를 엄격하게 강제하지 않음 (필요시 검증 기능 사용)
    • “어떤 화면/기능에서 어떤 데이터가 함께 필요할까?”를 먼저 생각하는 경우가 많다.

    간단 예시

    {
      "_id": ObjectId("..."),
      "email": "user@example.com",
      "name": "홍길동",
      "profile": {
        "age": 29,
        "job": "developer"
      }
    }

    2. 관계 표현 방식: 조인 vs 중첩/참조

    2-1. MariaDB: 테이블 + JOIN

    • 관계를 FK(Foreign Key) 로 표현
    • 여러 테이블을 JOIN 하여 한 번에 조회

    예: 사용자와 주문 관계

    SELECT u.name, o.order_number, o.total_price
    FROM users u
    JOIN orders o ON u.id = o.user_id
    WHERE u.id = 1;

    2-2. MongoDB: Embedded Document + Reference

    MongoDB는 두 가지 스타일을 섞어 쓴다.

    1. Embedded Document (중첩 도큐먼트)
      • 자주 같이 조회되는 데이터는 한 도큐먼트 안에 묶음
    2. Reference (참조)
      • 다른 컬렉션의 _id 만 참조해서 연결

    예: 주문 도큐먼트 안에 주문 상세를 중첩

    {
      "_id": ObjectId("..."),
      "user_id": ObjectId("..."),
      "order_date": "2025-12-08T10:00:00Z",
      "total_price": 59000,
      "items": [
        { "product_name": "무선 마우스", "quantity": 1, "price": 29000 },
        { "product_name": "기계식 키보드", "quantity": 1, "price": 30000 }
      ]
    }

    핵심 사고 차이

    • RDB: “관계를 나누고, 조회 시 JOIN으로 합친다.”
    • MongoDB: “자주 같이 쓰는 데이터는 애초에 한 덩어리로 저장한다.”

    3. 트랜잭션과 정합성

    3-1. MariaDB

    • ACID 트랜잭션 지원이 기본
    • 여러 테이블에 걸친 변경을 하나의 트랜잭션으로 묶을 수 있음
    • 금융/결제/회계처럼 숫자가 틀리면 안 되는 도메인에 적합

    예시 (의미만 표현)

    START TRANSACTION;
    
    UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
    UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
    
    COMMIT;

    3-2. MongoDB

    • 단일 도큐먼트에 대해서는 원자적 연산 보장
    • 최근 버전에서는 멀티 도큐먼트 트랜잭션도 제공하지만,
    • 일반적으로는 도큐먼트 단위 설계로 문제를 풀도록 권장
      • 돈/재고 등 강한 정합성이 필요한 경우, 여전히 RDB가 자연스러운 선택인 경우가 많다.
      • MongoDB에서는 “한 도큐먼트 안에서 완결되는 단위”를 늘리거나,
        “이벤트 소싱/보상 트랜잭션” 같은 패턴을 고려한다.
    • 설계 포인트

    4. 확장성과 성능

    4-1. MariaDB

    • 전통적인 패턴
      • 더 좋은 서버로 교체 (Scale-up)
      • 적절한 인덱스/쿼리 튜닝
    • 수평 확장(Scale-out)도 가능하지만, 구조적으로 구현 난도가 높을 수 있음

    4-2. MongoDB

    • 근본적으로 수평 확장(샤딩) 을 염두에 둔 구조
    • 특정 샤드 키(shard key)를 기준으로 데이터를 여러 서버에 분산
    • 대용량 로그/이벤트, 빅데이터성 저장에 적합
      • 규모가 크고, 읽기/쓰기가 폭증하는 경우 → MongoDB 같은 NoSQL이 편한 경우가 많다.
      • 하지만 RDB도 레플리카/샤딩/파티셔닝을 통해 확장이 가능하므로,
        결국 팀 경험과 도메인 특성이 중요하다.
    • 정리

    5. 예시: 간단 쇼핑몰 도메인 설계 비교 (실무 예시)

    도메인: 회원 + 주문 + 주문 상세

    5-1. MariaDB 설계

    테이블

    • users (회원)
    • orders (주문)
    • order_items (주문 상세)
    CREATE TABLE users (
        id INT PRIMARY KEY AUTO_INCREMENT,
        email VARCHAR(255) NOT NULL UNIQUE,
        name VARCHAR(100) NOT NULL
    );
    
    CREATE TABLE orders (
        id INT PRIMARY KEY AUTO_INCREMENT,
        user_id INT NOT NULL,
        order_date DATETIME NOT NULL,
        total_price DECIMAL(10,2) NOT NULL,
        FOREIGN KEY (user_id) REFERENCES users(id)
    );
    
    CREATE TABLE order_items (
        id INT PRIMARY KEY AUTO_INCREMENT,
        order_id INT NOT NULL,
        product_name VARCHAR(255) NOT NULL,
        quantity INT NOT NULL,
        price DECIMAL(10,2) NOT NULL,
        FOREIGN KEY (order_id) REFERENCES orders(id)
    );

    특징

    • 주문 1건에 여러 개의 주문 상세가 연결
    • 상품별 매출, 날짜별 매출 등 집계에 유리
    • 정규화된 구조로 데이터 중복 최소화

    5-2. MongoDB 설계

    컬렉션

    • users
    • orders

    orders 컬렉션의 도큐먼트 예시

    {
      "_id": ObjectId("..."),
      "user_id": ObjectId("..."),
      "order_date": "2025-12-08T10:00:00Z",
      "total_price": 59000,
      "items": [
        {
          "product_name": "무선 마우스",
          "quantity": 1,
          "price": 29000
        },
        {
          "product_name": "기계식 키보드",
          "quantity": 1,
          "price": 30000
        }
      ]
    }

    특징

    • 한 주문에 대한 모든 정보가 한 도큐먼트에 묶여 있음
    • 특정 주문을 화면에 보여줄 때, JOIN 없이 한 번에 조회 가능
    • 반면
      • 아이템 레벨에서 복잡한 집계를 많이 하는 경우에는 설계 고민이 필요
      • items 배열 안의 데이터를 별도로 인덱싱/집계해야 할 수 있음

    6. 실무적인 비교 포인트 요약

    6-1. 읽기 패턴

    • “주문 1건 전체를 자주 본다”
      → MongoDB 스타일(중첩 도큐먼트)이 편할 수 있다.
    • “상품별/카테고리별/기간별 통계를 자주 낸다”
      → RDB의 정규화 + JOIN/집계 쿼리가 직관적이다.

    6-2. 변경 패턴

    • 스키마가 비교적 안정적이고, 긴 기간 유지될 구조
      → MariaDB/RDB가 안전한 선택
    • 초반에 비즈니스 모델/필드가 자주 바뀔 예정
      → MongoDB의 스키마 유연성이 도움이 된다.

    6-3. 도메인 특성

    • 금융/정산/재고/계약 등, 숫자 한 자리 틀리는 것이 민감한 도메인
      → RDB 우선 검토
    • 로그/이벤트/행동 데이터, 대용량 히스토리 데이터
      → MongoDB 포함한 NoSQL 고려

    7. 정리

    • MariaDB와 MongoDB는 데이터를 어떻게 쪼개고, 어떻게 묶을지에 대한 철학이 다르다.
    • RDB는 정규화/조인, MongoDB는 도큐먼트/중첩 구조를 중심으로 사고한다.
    • 쇼핑몰 예시에서 보듯, 같은 요구사항도 각 DB에 맞는 방식으로 전혀 다른 모델링이 나온다.
    • 다음 시리즈에서는 이 비교를 바탕으로,
      서비스별로 어떤 기준으로 DB를 선택할지를 체크리스트 형태로 정리한다.
Designed by Tistory.