IndexedDB

bible_k_·2023년 3월 15일
0

인스타그램 클론코딩 과정 중 indexedDB를 처음 다루고있다. 생활코딩 indexedDB강의를 바탕으로indexedDB의 기본개념과 사용방법을 정리해보고자 한다.

웹브라우저에 정보를 저장하는 것의 장점

  1. 정보를 서버가 아닌 클라이언트에 저장하여 네트워크를 이용하지 않기 때문에 데이터를 가져오는 속도가 빠르다.
  2. 오프라인에서도 데이터를 사용할 수 있다.
  3. 속도가 빠르기 때문에 비용이 절약된다.
  4. 사용자의 정보가 서버로 전송되지 않고 브라우저에 직접 저장되기 때문에 보안이 유지된다.

indexedDB의 특징

브라우저에 정보를 저장하는 기술은 대표적으로 Cookie, LocalStorage, indexedDB가 있다.
이 중 indexedDB의 상대적인 특징은 다음과 같다.

  1. 저장공간이 크다. (브라우저마다 다르다. 크롬의 경우 컴퓨터 저장장치의 80%까지 저장할 수 있다.)
  2. 네트워크에 포함되지 않는다.
  3. 데이터 타입의 제한이 없다.
  4. 비동기식으로 동작하여 성능이 빠르다.

indexedDB의 구조

  • Object: 데이터가 담긴 객체
  • Object Store: 여러개의 객체 데이터를 연관된 것끼리 그룹핑. 여러개 존재할 수 있다.
  • Database: Object Store를 묶는 최상위의 수납상자

Database를 만들고 Object Store를 만들고 Object를 저장하고 읽고 수정하고 삭제할 수 있는 구조이다.


indexedDB 사용방법

데이터 베이스 만들기

<script>
    const dbReq = indexedDB.open('opentutorials',1);
    let db;
    dbReq.addEventListener('success', function(event){
        db = event.target.result;
    });
    dbReq.addEventListener('error', function(event){
        const error = event.target.error; 
        console.log('error', error.name);
    });            
</script>

indexedDB에 open함수를 호출하여 데이터베이스의 이름과 버전을 입력한다.
const dbReq = indexedDB.open('databaseName', version)

즉시 데이터베이스가 만들어지는 것이 아니라 IDBOpenDBRequest를 전달받는다.
dbrequest는 쉽게 말해 대기번호 같은 개념이다.

dbReq.addEventListener('success', function(event){});
addEventListener를 이용하여 success한다면 (데이터베이스가 생성되거나 이미 존재한다면) callback함수를 실행시킨다.
event.target은 dbReq변수를 가리킨다.
dbreq가 갖고있는 result를 통해 생성된 데이터베이스에 접근할 수 레퍼런스를 얻게된다.
이 레퍼런스는 애플리케이션에서 전역적으로 사용되어야 하기 때문에 바깥에서 let을 이용해 db라는 이름으로 변수를 선언하였다.

dbReq.addEventListener('error', function(event){});

에러가 발생했을 때의 예외상황을 처리하는 것도 중요하다.
에러 이벤트를 설치하여 에러를 핸들링 할 수 있다.
이는 open에서 뿐만 아니라 아래 진행되는 add, get, put등과 같은 작업들에서도 에러 이벤트를 설치해서 사용하게된다.

upgradeneeded

<script>
dbReq.addEventListener('upgradeneeded', function(event){
        db = event.target.result;  
        let oldVersion = event.oldVersion;
        if(oldVersion < 1){
            db.createObjectStore('topics', {keyPath:'id', autoIncrement:true});
        } 
    });
    </script>

브라우저의 마지막 버전과 소스코드의 최신버전이 일치하지 않을 때 upgradeneeded 이벤트가 실행된다.
처음 데이터베이스를 만들었을 때도 실행된다.

object store 생성

upgradeneeded는 버전이 업데이트 될 때만 실행되기 때문에 object store를 만들기에도 최적이다.
createObjectStore함수를 이용하여 object store 생성한다.

db.createObjectStore('topics', {keyPath:'id', autoIncrement:true});

  • 여기서 topic은 object store의 이름에 해당한다.
  • keyPath: 식별자로 사용할 프로퍼티이다.
  • autoIncrement: true => object store에 객체가 추가될 때마다 id값이 자동으로 1씩 증가하여 중복되지 않는 식별자를 만들어주는 옵션이다.

객체 추가하기

 <input type="button" value="add" onclick="
            let store = db.transaction('topics', 'readwrite').objectStore('topics');
            let addReq = store.add({
                title:prompt('title?'),
                body:prompt('body?')
            });
            addReq.addEventListener('success', function(event){
                console.log(event);
            });
        ">

let store = db.transaction('topics', 'readwrite').objectStore('topics');
transaction함수를 사용하여 object store를 가져온다.
첫번째 파라미터에는 객체를 추가할 object store 이름,
두번째 파라미터에는 transaction mode 를 입력한다.

transaction mode의 종류

  • readonly: 이미 존재하는 객체 저장소의 레코드를 읽기만 할 때
  • readwrite: 이미 존재하는 객체 저장소에 변경점을 기록할 때

구체적으로 코드를 뜯어보자

아래 코드를 통해 'topics'object store에 대한 레퍼런스를 얻는다.

let store = db.transaction('topics', 'readwrite').objectStore('topics');

object store에 연결되는 레퍼런스에 add함수를 호출한다.
함수의 파라미터로 들어가는 객체가 object store에 저장된다.

let addReq = store.add({
    title:prompt('title?'),
    body:prompt('body?')
});

success 이벤트를 설치하면 즉각적으로 객체가 추가되는 것이 아니라,
아래와 같이 모드(readwrite) 쓰기작업이 끝났을 때 함수가 실행된다.
쓰기작업이 끝나고 실행될 후속 작업 코드를 입력하면 된다.
마찬가지로 에러 이벤트도 설치할 수 있다.

addReq.addEventListener('success', function(event){
    console.log(event);
});

객체 읽기

 <input type="button" value="get" onclick="
            let id = Number(prompt('?id'));
            let store = db.transaction('topics', 'readonly').objectStore('topics');            
            let getReq = store.get(id);
            getReq.addEventListener('success', function(event){
                console.log(event.target.result);
            });
        ">

let id = Number(prompt('?id'));
읽어오는 객체의 id 값을 가져온다
이 경우에 사용자가 입력한 정보는 문자열이기 때문에 숫자로 컨버팅한다.

let store = db.transaction('topics', 'readonly').objectStore('topics');
객체 추가하기와 동일하게 transection함수를 이용하여 object store를 가져온다.
여기서는 읽기 전용으로 transaction mode를 readonly로 설정한다.

let getReq = store.get(id);
get api를 이용하여 식별자를 입력하고 객체를 가져오는 변수를 설정한다.

getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.

객체 목록 가져오기

let store = db.transaction('topics', 'readonly').objectStore('topics');
transection함수를 이용하여 object store를 가져온다.
읽기 전용으로 transaction mode를 readonly로 설정한다.

let getAllReq = store.getAll();
getAll api를 호출하면 모든 데이터를 가져온다.

getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.

객체 업데이트(객체 수정하기)

let store = db.transaction('topics', 'readwrite').objectStore('topics');
transection함수를 이용하여 object store를 가져온다.
수정해야하므로 transaction mode를 readwrite로 설정한다.

let putReq = store.put({
    id:Number(prompt('id?')),
    title:prompt('title?'),
    body:prompt('body?')
});

put api를 사용하여 수정할 내용을 입력한다. 식별자(id값)을 명시해줘야한다.

getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.

객체 삭제하기

let store = db.transaction('topics', 'readwrite').objectStore('topics');
transection함수를 이용하여 object store를 가져온다.
transaction mode를 readwrite로 설정한다.

let deleteReq = store.delete(Number(prompt('id?')));
deleteReq.addEventListener('success', function(event){});

delete api를 사용하여 삭제할 객체의 식별자(id값)을 입력한다.

getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.


Comment

엘리스에서 사용한 코드와 생활코딩에서 정리한 코드가 같은 용도임에도 많이 다르다.
그래도 주요 키워드는 모두 동일하기 때문에 indexedDB 기본적인 동작 원리를 이해할 수 있는 시간이었다. indexedDB를 사용할 일이 많이 없다고하지만 내가 애용하는 YoutubeMusic에서 오프라인 저장 기능이 indexedDB를 사용한다고 하니 신기하기도 하고. 빨리 다른 database도 공부하여 이해도를 기르고싶다.

profile
후론트엔드 개발자

0개의 댓글