웹 전반, 브라우저/Web API

IndexDB (1) : 간단한 개념을 알아보고 사용해보자

DarrenKwonDev 2021. 11. 28. 02:13
IndexedDB는 파일이나 블롭 등 많은 양의 구조화된 데이터를 클라이언트에 저장하기 위한 로우 레벨 API입니다. IndexedDB API는 인덱스를 사용해 데이터를 고성능으로 탐색할 수 있습니다. Web Storage(localStorage나 sessionStorage)는 적은 양의 데이터를 저장하는데 유용하지만 많은 양의 구조화된 데이터에는 적합하지 않은데, 이런 상황에서 IndexedDB를 사용할 수 있습니다.
- https://developer.mozilla.org/ko/docs/Web/API/IndexedDB_API

 

결국 Web Storage보다 많은 양의 데이터를 저장하는데 더 적합한 저장소라는 것이다. 단순히 get, set만 지원하는 것이 아니라 좀 더 DB스럽게 사용할 수 있고 용량도 더 많다. 

 

Web Storage는 간편하지만 기능이 많다고 할 수는 없다.  좀 더 강력한 기능을 위해 google web.dev의 storage for web의 설명에 따르면 다음과 같은 저장소를 사용하도록 추천하고 있다. 

 

IndexDB의 특성들

(https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Terminology)

 

IndexedDB는 많은 양의 데이터를 저장하는 애플리케이션이지만 작동을 위해 지속적인 인터넷 연결이 필요하지 않은 애플리케이션에 적합하다. 예로 들자면, 할 일이 2만개가 되는 앱은 굳이 서버와 통신할 이유가 없고 데이터를 클라이언트 단에서만 저장하면 된다.

 

클라이언트 단이라고 하면 정확히 어디에 저장되는건가?

Chrome 기본 경로라는 가정 하에, 다음과 같은 경로에 저장된다.

%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\IndexedDB

/Users/[USERNAME]/Library/Application Support/Google/Chrome/Default/IndexedDB/

 

기본적인 특성들은 무엇인가?

  • 키-밸류 값으로 저장되고 가져온다.
  • 빠른 검색과 정렬을 위해 개체의 속성을 사용하는 인덱스를 만들 수 있다. (WOW 이걸 웹에서?)
  • IndexedDB는 트랜잭션 데이터베이스 모델을 기반으로 한다.
  • The IndexedDB API is mostly asynchronous
  • Full Text Searching 없음. (너무 당연한 거 아닌가;;)
  • SQL의 Like 문 류의 기능 없음.
 
 
브라우저가 IndexDB를 지우는 경우
  • 브라우저 설정에서 지우겠다고 선택하는 경우 (종종 브라우저 히스토리 지울 때 이것 저것 체크하는데 그 옵션인가 보다)
  • 비공개 브라우저에서는 브라우저가 종료되면 IndexDB도 날아감
  • 데이터가 손상되었을 때 (정확히 어떻게 손상되었을 때인지는 모르겠음)
  • 컴퓨터 하드 드라이브 용량이 다 찼을 때
즉, 정말로 중요한 데이터는 indexDB를 비롯하여 클라이언트에 저장하는 것이 좋지 않을 것으로 보인다.

 

IndexDB를 사용하는 방법

 

Cursor, Index, TX 등 되게 많은 개념이 있어서 후딱 끝낼 수 없는 수준이다; 여기서는 일단 간단히 알아보자.

(https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB)

 

version, indexDB open

 

어렵게 정리했는데 몇마디로 요약하자면

"현재 indexDB의 version 보다 낮은 version을 open하려고 하면 에러가 발생한다"

"upgrade할 때 schema를 생성하고 success할 때 활용한다"

const INDEXDB_NAME='mydb'

// IDBFactory
const indexedDB =
  window.indexedDB ||
  window.mozIndexedDB ||
  window.webkitIndexedDB ||
  window.msIndexedDB ||
  window.shimIndexedDB;

const request = indexedDB.open(INDEXDB_NAME, 1)

request.onupgradeneeded = e => {
  console.log("upgrade called")
}

request.onsuccess = e => {
  console.log("success")
}

request.onerror = e => {
  alert("error")
}

위 플로우 차트에서 주의할 점은 upgrade만 트리거 되고 끝나는게 아니라 연이어 success event가 트리거 된다는 점이다.

indexDB를 삭제한후 리로드해보면 upgrade 이벤트가 발생한 후 success 이벤트가 발생하는 것을 확인할 수 있다.

 

생성된 결과는 다음에서 확인할 수 있다.

 

 

IDBObjectStore 만들고 Transaction을 통해 데이터 추가하기

// IDBObjectStore
const store = IDB.createObjectStore(storeName, { keyPath: key });

주의할점은 indexDB의 대부분의 API는 비동기적이라는 것이다. store가 만들어진 직후에 사용할 수 있지 않다.

그래서 upgrade 이벤트가 발생할 때 schema를 생성하고 테이블을 만드는 등의 작업을 진행한다.

 

여튼 이제 store를 만들었으니 tx를 생성하여 store에 넣어보자.

// readwrite IDBTransaction 생성
const tx = db.transaction("storeName", "readwrite");
tx.onerror = (e) => alert(`Error! ${e.target.error}`);

// 생성된 IDBObjectStore 불러오기
const store = tx.objectStore("storeName");

// IDBObjectStore에 추가!
store.add(yourObject);

 

Cursor를 통해 store에 저장된 데이터 읽기

// readonly한 IDBTransaction 생성
const tx = db.transaction("storeName", "readonly");

const store = tx.objectStore("storeName");
const request = store.openCursor();
request.onsuccess = (e) => {
  const cursor = e.target.result;
   if (cursor) {    
    // 다음 커서 진행
    cursor.continue();
  }
};

 

 

ref)

https://developer.mozilla.org/ko/docs/Web/API/IndexedDB_API

 

 

http://labs.brandi.co.kr/2021/04/19/leejm3.html

https://pks2974.medium.com/indexeddb-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0-ca9be4add614