IndexedDB는 브라우저에 내장된 비관계형 클라이언트 측 데이터베이스다. 대용량 구조화 데이터를 저장하고, 인덱스로 빠른 검색이 가능하며, 트랜잭션을 지원한다. Web Storage보다 훨씬 많은 데이터(수백 MB~GB)를 저장할 수 있다.
Web Storage와 비교
| 항목 | localStorage | sessionStorage | IndexedDB |
|---|
| 용량 | ~5MB | ~5MB | ~수 GB |
| 데이터 타입 | 문자열만 | 문자열만 | 모든 타입 |
| 인덱스 | 없음 | 없음 | 있음 |
| 트랜잭션 | 없음 | 없음 | 있음 |
| 비동기 | 아니오 | 아니오 | 예 |
기본 사용법
javascript
// 데이터베이스 열기 (버전 관리)
const request = indexedDB.open('MyDatabase', 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Object Store 생성 (테이블 역할)
const store = db.createObjectStore('users', { keyPath: 'id' });
// 인덱스 생성
store.createIndex('email', 'email', { unique: true });
store.createIndex('age', 'age', { unique: false });
};
request.onsuccess = (event) => {
const db = event.target.result;
insertUser(db, { id: 1, name: 'Alice', email: 'alice@ex.com', age: 30 });
};
function insertUser(db, user) {
const tx = db.transaction('users', 'readwrite');
const store = tx.objectStore('users');
store.put(user);
tx.oncomplete = () => console.log('저장 완료');
tx.onerror = (e) => console.error('오류:', e);
}
Dexie.js (래퍼 라이브러리)
typescript
import Dexie, { type Table } from 'dexie';
interface User {
id?: number;
name: string;
email: string;
age: number;
}
class AppDatabase extends Dexie {
users!: Table<User, number>;
constructor() {
super('AppDatabase');
this.version(1).stores({
users: '++id, name, email, age', // ++ = 자동 증가
});
}
}
const db = new AppDatabase();
// CRUD 작업 (Promise 기반)
await db.users.add({ name: 'Alice', email: 'alice@ex.com', age: 30 });
const user = await db.users.get(1);
const adults = await db.users.where('age').above(18).toArray();
await db.users.update(1, { age: 31 });
await db.users.delete(1);
관련 개념