indexed DB 사용해보기

수연·2023년 6월 7일
3

JavaScript

목록 보기
1/3

Indexed DB

Indexed DB 는 사용자의 브라우저에 데이터를 영구적으로 저장하는 방법 중 하나이다. localStorage 보다 많은 용량의 데이터를 저장할 수 있고, JS 에서 사용하는 객체 형식 그대로 저장할 수 있다.

Indexed DB 사용해보기

1. DB 열기

가장 먼저 데이터베이스 open 요청을 해야한다.

open 메소드의 첫번재 매개변수엔 데이터베이스의 이름, 두번째 매개변수엔 데이터베이스의 버전이 들어간다. 이때 버전은 정수로만 표현돼야 한다.

if (!window.indexedDB) { // 지원여부 확인하기
	alert(`your browser doesn't support indexed DB`);
}
const dbName = 'SuyeonDB';
const version = 1;
const request = window.indexedDB.open(dbName, version); // 데이터 베이스 열기 요청

db 삭제는 deleteDatabase 메서드를 통해 삭제한다.

const request = window.indexedDB.deleteDatabase(dbName);

2. Object Storage 생성하기

1. 새로운 데이터 베이스를 만들거나, 2. 기존의 데이터베이스 버전 보다 높은 데이터베이스를 부를 때 onupgradeneeded 이벤트가 트리거 된다.

해당 이벤트 처리를 해주는 코드 안에서 새로운 객체 저장소를 생성해준다.

  • name: 저장소의 이름을 뜻한다. 저장소의 이름은 고유해야 한다. (같은 이름으로 저장소를 만들면 에러 발생)
  • keyPath: 개별 객체들을 고유하게 저장할 수 있는 id 를 정의하는 파라미터다. 예를 들어 friend 대한 객체를 만들었다면 주민등록번호, 연락처 등이 사람을 고유하게 식별할 수 있게 해준다. 아래의 예시에선 id 를 사용했는데, objectStore 에 저장되는 모든 객체들엔 id 프로퍼티가 들어있어야 한다.
  • autoIncrement: 저장소에 값을 추가할 때 자동으로 키를 추가할지의 여부를 결정한다. true 로 설정해주면 초기 키값은 1이고, 이후 초기 키 값에서 1씩 더해진다.
request.onupgradeneeded = function(event) {
	const db = event.target.result;
	const objectStore = db.createObjectStore('friend', { // 저장소 이름 = friend
		keyPath: 'id',
		autoIncrement: true
	});
}

onupgradeneeded 이벤트가 끝나면 DB 열기 요청의 onsuccess 가 트리거 된다.

request.onError = function(event) {
	// 에러에 대한 처리
}
request.onupgradeneeded = function(event) {
	// 스토리지 생성
}
request.onsuccess = function(event) {
	console.log('suyeon DB 확인!');
}

DB 생성 모습

출력문 확인

DB 생성 모습과 onsuccess 콘솔을 확인할 수 있다.

3. 트랜잭션 생성

❓ 트랜잭션이 뭔가요

트랙잭션은 데이터베이스의 상태(데이터)를 변화시키기 위한 작업을 의미한다. 즉 데이터베이스의 데이터의 수정, 삭제, 삽입 등을 위해선 트랜잭션을 생성해주어야 한다는 의미이다.

transaction 메소드를 사용해 transaction을 열 수 있다.

  • storeName: 생성한 객체 스토어의 이름이다.
  • type: 트랜잭션의 모드를 설정한다.
    • readonly: 읽기 전용 (기본값)
    • readwrite: 읽기 & 쓰기
    • versionchange: 객체 저장소를 새로 생성하거나, 인덱스를 생성&삭제하는 경우 사용한다.
request.onsuccess = function(event) {
	const db = event.target.result;
	const transaction = db.transaction(storeName, mode);

	transaction.oncomplete = (e) => {} // 성공처리
	transaction.onerror = (e) => {} // 에러처리
}

이때 여러개의 저장소에 접근하고 싶은 경우 배열 요소로 store 를 집어넣으면 된다.

const transaction = db.transaction(['store1', 'store2']);

4. 데이터 삽입하기

스토어에 저장하기 위해 스토어를 다시 불러온다.

request.onsuccess = function(event) {
	// 생략
	const transaction = db.transaction(storeName, mode);
	const objectStore = transaction.objectStore('friend');
}

친구 정보를 위한 객체를 따로 만들어 저장소에 저장해준다.

const friends = [
  {name: '김정호', team:'front'},
  {name: '김유진', team:'front'},
  {name: '송인재', team:'front'},
  {name: '우지호', team:'front'},
  {name: '조수연', team:'front'},
];
request.onsuccess = function(event) {
	// 생략
	const transaction = db.transaction(storeName, mode);
	const objectStore = transaction.objectStore('friend');

	friends.forEach((e, i) => {
		const request = objectStore.add(e);
		request.onsuccess = (e) => { // ... } // 성공에 대한 처리
	})
}

예쁘게 들어간 우리 팀원들의 이름…

5. 데이터 가져오기

데이터는 get 함수와 키값을 통해 가져올 수 있다.

const key = 5;
const request = objectStore.get(key); // IDBRequest 객체 반환
console.log(request.result); // name: 조수연 team: front

6. 데이터 수정하기

갑자기 내가 백엔드로 가고 싶어진다면 어떻게 해야할까. get 으로 값을 가져온 다음 put 함수로 수정해주면 된다.

const key = 5;
const request = objectStore.get(key);
request.onsuccess = (e) => {
	objectStore.put({name: 조수연, 'team': back'});
}

데이터 변경

7. 데이터 삭제하기

마찬가지로 key 값을 통해 삭제하면 된다.

const key = 5;
const request = objectStore.delete(key); // 조수연 삭제

삭제한 모습

8. cursor?

get 으로 key 값을 가져오려면 key 값을 우리가 알고 있어야 한다.

key 값을 모르는 상태에서 전체 데이터를 조회하고 싶을 땐 cursor 를 사용하면 된다.

objectStore.openCursor().onsuccess = (e) => {
  const cursor = e.target.result;

  if (cursor) {
		console.log(`key: ${cursor.key} name: ${cursor.value.name}`);
    cursor.continue(); // continue 를 사용해 연속 조회
  }
}

9. 인덱스 사용하기

만약 이름이 조수연 인 사람의 데이터를 찾고 싶을 때, id 를 통해 검색하려면 한번씩 순회를 하며 이름을 검색해야할 것이다. 이런 방식은 비효율적이므로 프로퍼티에 index 를 부여하여 검색할 수 있다.

index 를 사용하려면 onupgradeneeded 에서 index 설정을 해줘야한다.

// onupgradeneeded
const indexReq = store.createIndex('name', 'name'); // index 추가
// onsuccess
index.get('조수연').onsuccess = (e) => { // name 프로퍼티 중 조수연이란 이름을 가진 
    console.log(e.target.result);
}

onupgradeneeded 는 데이터베이스가 처음 만들어지거나 버전이 업그레이드 될 때 실행되므로 db를 처음부터 새로 생성했다.

request.onupgradeneeded = (e) => {
    const db = e.target.result;
    const store = db.createObjectStore('friend',  {
      keyPath: 'id',
      autoIncrement: true
    });

    const indexReq = store.createIndex('name', 'name'); // index 추가
  }
request.onsuccess = (e) => {
    const db = e.target.result;
    const transaction = db.transaction('friend', 'readwrite');
    const store = transaction.objectStore('friend');
    const index = store.index('name');

    index.get('조수연').onsuccess = (e) => {
      console.log(e.target.result);
    }
  }

인덱스 출력

이름을 통해서도 데이터가 잘 출력되는 걸 확인할 수 있다!


참고 사이트

MDN indexed DB

0개의 댓글