-
웹 브라우저에 데이터를 저장하고 싶다면? IndexedDB 톺아보기 🖥️웹 개발 2025. 9. 29. 00:02
IndexedDB는 브라우저에 클라이언트 측 데이터베이스를 저장하기 위한 로우레벨(Low-level) API다.
로컬 스토리지나 세션 스토리지와 비슷하게 데이터를 저장하는 용도지만, 이들과는 조금 다르다.
이 두 가지는 키-값 쌍의 데이터를 문자열 형태로만 저장할 수 있고, 용량 제한도 있는 반면, IndexedDB는 구조화된 데이터를 대용량으로 저장할 수 있다는 장점이 있다.
즉, 사용자 기기에서 데이터를 많이 다루는 오프라인 웹 애플리케이션이나 PWA(Progressive Web Apps)에 아주 유용하게 쓰일 수 있다고 한다.
👻 IndexedDB의 주요 특징
- 트랜잭션(Transaction) 기반 - 데이터의 무결성을 보장하기 위해 모든 작업은 트랜잭션 내에서 실행됨
- 비동기(Asynchronous) 방식 - 모든 작업은 비동기로 처리되어 메인 스레드를 차단하지 않아 UI가 멈추는 일이 없음
- 객체 스토어(Object Store) - 데이터를 테이블처럼 관리하는 저장소
👍 IndexedDB를 사용하는 이유
- 오프라인 접근성 - 네트워크 연결이 없어도 데이터를 읽고 쓸 수 있음
- 대용량 데이터 - 수백 MB에서 GB 단위의 대용량 데이터를 저장할 수 있음
- 구조화된 데이터 - 단순 문자열뿐만 아니라 JavaScript 객체도 저장할 수 있음
1. 기본적인 IndexedDB 세팅
🙌 데이터베이스 열기
IndexedDB를 사용하려면 먼저 데이터베이스를 열어야 한다.
이때 indexedDB.open() 메서드를 사용하는데, 이 메서드는 데이터베이스 이름과 버전을 인자로 받는다.
const request = indexedDB.open('MyTestDatabase', 1); request.onupgradeneeded = function(event) { // 데이터베이스 버전이 변경될 때 실행되는 이벤트 const db = event.target.result; db.createObjectStore('myObjectStore', { keyPath: 'id' }); }; request.onsuccess = function(event) { const db = event.target.result; console.log('데이터베이스가 성공적으로 열렸습니다.'); }; request.onerror = function(event) { console.error('데이터베이스 열기 오류:', event.target.errorCode); };🙌 데이터 추가하기
데이터를 추가하려면 먼저 트랜잭션을 시작하고, 객체 스토어를 얻어와야 한다.
트랜잭션은 읽기(readonly) 또는 쓰기(readwrite) 모드를 가진다.
// db 변수는 위에서 성공적으로 열린 데이터베이스 객체 const db = event.target.result; const transaction = db.transaction(['myObjectStore'], 'readwrite'); const objectStore = transaction.objectStore('myObjectStore'); const data = { id: 1, title: 'IndexedDB 블로그 글', content: 'IndexedDB는 정말 유용해!', author: 'citron', date: new Date() }; const addRequest = objectStore.add(data); addRequest.onsuccess = function() { console.log('데이터가 성공적으로 추가되었습니다.'); }; addRequest.onerror = function() { console.error('데이터 추가 오류:', addRequest.error); };🙌 데이터 읽기
데이터를 읽는 것도 비슷한데, 읽기 모드 트랜잭션을 시작하고 get() 메서드를 사용하면 된다.
const db = event.target.result; const transaction = db.transaction(['myObjectStore']); const objectStore = transaction.objectStore('myObjectStore'); const getRequest = objectStore.get(1); // key가 1인 데이터 가져오기 getRequest.onsuccess = function(event) { const result = event.target.result; if (result) { console.log('가져온 데이터:', result); } else { console.log('데이터를 찾을 수 없습니다.'); } };이렇게 작성한 예제는 크롬 개발자도구를 통해서 제대로 작동하는지 확인할 수 있다.

🥝 개인적인 생각
처음 IndexedDB를 접하면 비동기 방식과 트랜잭션 개념이 조금 복잡하게 느껴질 수 있는데, 특히 콜백 함수나 프로미스 체인으로 코드를 작성하면 가독성이 떨어지기도 한다.
하지만 Promise 기반의 라이브러리인 idb 같은 것을 사용하면 훨씬 더 간편하게 코드를 작성할 수 있었다 😊
결론적으로, 간단한 데이터 저장은 LocalStorage로도 충분하지만, 웹 앱에서 대용량 데이터를 다루거나 복잡한 쿼리가 필요할 때는 IndexedDB가 아주 좋은 대안이 될 수 있다.
참고 자료 🕸️
https://developer.mozilla.org/ko/docs/Web/API/IndexedDB_API/Using_IndexedDB
IndexedDB 사용하기
여러분은 이 튜토리얼에서 IndexedDB의 비동기 방식(asynchronous) API에 대해 훑어볼 수 있습니다. 만약 IndexedDB가 생소하다면, IndexedDB key characteristics and basic terminology 를 먼저 읽어보는 것이 좋습니다.
developer.mozilla.org
https://developer.mozilla.org/ko/docs/Web/API/IndexedDB_API
IndexedDB API
IndexedDB는 SQL을 사용하는 관계형 데이터베이스(RDBMS)와 같이 트랜잭션을 사용하는 데이터베이스 시스템입니다. 그러나 IndexedDB는 RDBMS의 고정컬럼 테이블 대신 JavaScript 기반의 객체지향 데이터베
developer.mozilla.org
🍉 실제 작성한 코드 !
https://github.com/citron03/practice-next-15/commit/8b899223d7fcec6170d3ef26c4bd80afa9940553
feat: update eslint config & index db test add · citron03/practice-next-15@8b89922
+ <div style={{ display: 'flex', gap: 8, marginBottom: 16 }}>
github.com
'웹 개발' 카테고리의 다른 글
가상호스트(Virtual Host)란 무엇인가? (0) 2025.12.05 MIME 타입(Multipurpose Internet Mail Extensions) 정리 🎩 (0) 2025.10.31 GitHub Copilot과 MCP에 대한 가이드 모음 (0) 2025.09.13 package.json 패키지 버전 자동 업데이트 하기 🍕 (npm-check-updates) (0) 2025.09.06 signal에 대해서 알아보고, state와 비교 (React에서는 signal이 부적합한 이유) ⚾️ (3) 2025.08.07