Skip to main content

localStorage에서 MongoDB까지: 초보자를 위한 데이터베이스 구조 완전 정복

Published 5 min readMarkdown

# 📌 서론 – “데이터는 어디에 저장해야 할까?”

웹 애플리케이션을 만들다 보면 데이터를 어디에 보관할지 고민하게 됩니다.

초기 개발 단계에서는 브라우저에 내장된 localStorage를 이용해 간단히 데이터를 저장합니다.

하지만 사용자가 늘어나고, 데이터가 영구적이어야 하며, 여러 디바이스에서 동기화가 필요해지면 데이터베이스가 필수입니다.

특히 MongoDB와 같은 NoSQL 데이터베이스는 스키마가 자유롭고 확장성이 뛰어나서 현대 웹·모바일 서비스에 많이 선택됩니다.

이번 포스트에서는 localStorage와 MongoDB 사이의 차이를 짚어보고, MongoDB 구조를 초보자도 이해하기 쉽도록 단계별로 설명합니다.

키워드: MongoDB 구조, localStorage, 데이터베이스 연동


# 1️⃣ localStorage – 브라우저에 “잠깐” 저장하기

# 1-1. localStorage란?

  • 브라우저가 제공하는 키‑값(key‑value) 형태의 저장소

  • 문자열만 저장 가능 → 객체는 JSON.stringify 로 변환 필요

  • 도메인 별로 격리돼 있어 같은 사이트 내에서만 접근 가능

# 1-2. 장점 & 단점

| 장점 | 단점 |

|------|------|

| 구현이 간단 → localStorage.setItem('key', value) 한 줄 | 용량 제한 (≈ 5 MB) |

| 비동기 호출이 없어 즉시 저장/읽기 | 영구적이지 않음 (브라우저 캐시 삭제 시 사라짐) |

| 서버와 통신 불필요 → 네트워크 비용 절감 | 보안 취약 (XSS 공격 시 노출 가능) |

# 1-3. 언제 쓰나요?

  • 사용자의 UI 설정(테마, 언어) 저장

  • 로그인 상태 유지(토큰) (단, 보안 고려 필요)

  • 작은 임시 데이터(폼 입력값) 보관

하지만 비즈니스 로직에 중요한 데이터를 localStorage에만 의존하면 안 됩니다. 여기서 데이터베이스 연동이 필요합니다.


# 2️⃣ MongoDB – “문서형” 데이터베이스의 기본 구조

# 2-1. MongoDB란?

  • NoSQL 계열 중 하나로, JSON 형태의 문서(Document)를 저장

  • 스키마가 자유롭고, 컬렉션(Collection) 단위로 데이터를 관리

# 2-2. 핵심 개념

| 용어 | 설명 |

|------|------|

| Database | 여러 컬렉션을 포함하는 논리적 단위 |

| Collection | 같은 종류의 문서를 모아둔 집합 (예: users, posts) |

| Document | { field: value, ... } 형태의 JSON-like 객체 |

| ObjectId | 각 문서를 고유히 식별하는 12바이트 ID (자동 생성) |

# 2-3. MongoDB 구조 예시

json

{
  '_id': ObjectId('65f9c2a5b1e4c8d6f9a0b123'),

  'username': 'johndoe',

  'email': 'john@example.com',

  'profile': {

    'age': 28,

    'city': 'Seoul'

  },

  'createdAt': ISODate('2024-10-01T12:34:56Z')

}
  • 중첩 문서(Nested Document) 로 관계형 DB의 JOIN을 대체

  • 배열(Array) 로 여러 값을 하나의 필드에 저장 가능

# 2-4. 왜 MongoDB인가?

  1. 스키마 유연성 – 초기 설계가 미완성돼도 바로 데이터 삽입 가능

  2. 수평 확장성 – 샤딩(Sharding)으로 트래픽 급증에 대응

  3. 빠른 개발 속도 – JSON 형태라 프론트엔드와 데이터 포맷이 일치


# 3️⃣ localStorage와 MongoDB 연동 흐름 – 전체 아키텍처

# 3-1. 기본 흐름도

mermaid

flowchart TD

    A[브라우저] -->|입력 데이터| B[localStorage]

    B -->|동기화 트리거| C[프론트엔드 JS]

    C -->|REST API 호출| D[Node.js/Express 서버]

    D -->|MongoDB 드라이버| E[MongoDB]

    E -->|응답| D

    D -->|결과 반환| C

    C -->|업데이트| B
  1. 사용자 입력 → 일시적으로 localStorage에 저장 (빠른 UI 반응)

  2. 동기화 시점(예: 페이지 언로드, 일정 주기, 버튼 클릭) → 프론트엔드에서 API 호출

  3. 서버는 요청을 받아 MongoDB에 데이터를 삽입/수정

  4. 응답을 받아 프론트엔드가 localStorage를 최신 상태로 업데이트

# 3-2. 언제 동기화할까?

| 상황 | 권장 동기화 방법 |

|------|----------------|

| 사용자가 저장 버튼을 클릭 | 즉시 POST /api/items 호출 |

| 페이지를 떠날 때 | window.onbeforeunload 이벤트에 API 호출 |

| 일정 주기마다 (예: 5분) | setInterval 로 백그라운드 동기화 |

| 네트워크가 복구될 때 | 오프라인 모드 → 온라인 전환 감지 후 전송 |


# 4️⃣ 실전 예제 – React + Express + MongoDB 연동하기

# 4-1. 프로젝트 구조 (간단히)


my-app/

├─ client/          # React 프로젝트

│   └─ src/

│       └─ utils/

│           └─ storage.js   # localStorage 헬퍼

├─ server/          # Express + MongoDB

│   └─ routes/

│       └─ items.js

│   └─ models/

│       └─ Item.js

└─ README.md

# 4-2. 프론트엔드 – localStorage 헬퍼 (storage.js)

javascript

// storage.js

export const saveToLocal = (key, data) => {

  localStorage.setItem(key, JSON.stringify(data));

};

export const loadFromLocal = (key) => {

  const raw = localStorage.getItem(key);

  return raw ? JSON.parse(raw) : null;

};

export const clearLocal = (key) => {

  localStorage.removeItem(key);

};

# 4-3. 데이터 저장 & 동기화 로직 (React 컴포넌트)

javascript

import { useState, useEffect } from 'react';

import axios from 'axios';

import { saveToLocal, loadFromLocal } from './utils/storage';

function TodoApp() {

  const [todos, setTodos] = useState(() => loadFromLocal('todos') || []);

  // 입력 → localStorage에 즉시 저장

  const addTodo = (text) => {

    const newTodo = { id: Date.now(), text };

    const updated = [...todos, newTodo];

    setTodos(updated);

    saveToLocal('todos', updated);

  };

  // 5분마다 서버와 동기화

  useEffect(() => {

    const timer = setInterval(() => {

      axios.post('/api/todos/sync', { todos })

        .then(res => console.log('Sync success:', res.data))

        .catch(err => console.error('Sync error:', err));

    }, 5 * 60 * 1000);

    return () => clearInterval(timer);

  }, [todos]);

  return (/* UI 생략 */);

}

# 4-4. 서버 – Express 라우터 (items.js)

javascript

const express = require('express');

const router = express.Router();

const Item = require('../models/Item');

// 클라이언트에서 전송한 전체 배열을 MongoDB에 upsert

router.post('/todos/sync', async (req, res) => {

  const { todos } = req.body;

  try {

    // 기존 데이터 모두 삭제 후 새로 삽입 (간단 예시)

    await Item.deleteMany({});

    await Item.insertMany(todos.map(t => ({ text: t.text, createdAt: new Date() })));

    res.json({ status: 'ok', synced: todos.length });

  } catch (e) {

    console.error(e);

    res.status(500).json({ error: 'Sync failed' });

  }

});

module.exports = router;

# 4-5. MongoDB 모델 (Item.js)

javascript

const mongoose = require('mongoose');

const ItemSchema = new mongoose.Schema({

  text: { type: String, required: true },

  createdAt: { type: Date, default: Date.now }

});

module.exports = mongoose.model('Item', ItemSchema);

핵심 포인트

  • JSON 형태가 그대로 MongoDB에 저장돼 localStorage와 구조가 유사 → 변환 로직이 최소화됩니다.

  • ObjectId 대신 클라이언트에서 만든 id(예: 타임스탬프)를 임시 키로 사용해도 무방합니다.


# 5️⃣ 베스트 프랙티스 & 주의사항

| 항목 | 권장 방법 |

|------|-----------|

| 데이터 검증 | 서버에서 Joi·zod 등으로 스키마 검증 후 DB에 삽입 |

| 보안 | 토큰 기반 인증(JWT) → API 호출 시 Authorization 헤더에 포함 |

| 오프라인 지원 | Service Worker + IndexedDB 로 localStorage를 보완 (용량·복구) |

| 에러 처리 | 동기화 실패 시 재시도 로직(exponential backoff) 구현 |

| 성능 최적화 | 대량 삽입 시 insertMany 사용, 인덱스는 필요한 필드에만 생성 |

특히 민감 정보(예: 비밀번호, 토큰)는 절대로 localStorage에 저장하지 말고, HttpOnly 쿠키 혹은 Secure Storage 를 활용하세요.


# 📌 결론 – 지금 바로 “localStorage → MongoDB” 여정을 시작해보세요!

  • 문제: localStorage는 편리하지만 영구성·보안·확장성이 부족합니다.

  • 해결: 프론트엔드에서 데이터를 잠시 저장하고, 적절한 시점에 MongoDB와 연동하면 사용자 경험과 데이터 무결성을 동시에 확보할 수 있습니다.

  • 행동: 오늘 만든 작은 프로젝트에 위 예시 코드를 적용해 보세요.

    1. storage.js 로 localStorage 헬퍼 만들기

    2. Express + Mongoose 로 간단한 API 구축

    3. 주기적 동기화 로직을 추가하고, 콘솔에 성공·실패 로그 확인

당신의 첫 번째 “데이터베이스 연동”이 성공하면, 다음 단계는 인증·권한 관리, 그리고 클라우드 배포입니다.

궁금한 점이 있으면 댓글로 남겨 주세요! 🙌


키워드 재노출 : MongoDB 구조, localStorage, 데이터베이스 연동


No comments yet. Be the first to comment.

More from this blog