본문 바로가기
JavaScript/Basic functions

[JavaScript] IndexedDB 사용법 알아보기 [JS기초 함수] - 띵코딩 on Code

by 띵코딩 2023. 10. 3.

IndexedDB란?

IndexedDB는 웹페이지에 내장된 데이터베이스로 서버가 아닌 클라이언트에 데이터를 저장하고 사용한다. 인덱스를 사용하기 때문에 탐색면에서 서버에 비하면 속도가 빠르고, 비용도 절감되며, 서버로부터 사용자의 정보를 노출시키지 않기 때문에 보안상에서도 보다 안전하다. 
이 외에 Cookie, LocalStorage 내장 데이터베이스도 존재하지만 이 둘은 저장공간이 크지않고 동기식으로 작동되며 데이터타입이 문자열인 것만 저장되기 때문에 IndexedDB에 비하면 성능이 뛰어나지 않다.
확실히 다른것에 비해 성능이 뛰어나지만 IndexedDB는 비동기식이며, 사용 난이도가 어렵다는 단점이 있다.

 

IndexedDB 구조

여러개의 객체들을 오브젝트 스토어에 넣고, 그 오브젝트 스토어들을 묶어 데이터베이스라는 큰 틀에 넣는 구조이다.

 

IndexedDB 데이터베이스 생성

const request = indexedDB.open("opentutorials", 1);

request.addEventListener( ‘success’, function(event) {
	let db = event.target.result;
});

indexedDB.open("데이터베이스 이름", 버전)은 데이터베이스를 생성하는 것을 요청하거나 기존에 있던 데이터베이스를 여는 것을 요청한다.
success 이벤트는 데이터베이스가 생성되거나 이미 존재한다면 내부 콜백함수가 작동한다. 콜백함수 내부 event.target은 request를 가리키며 갖고있는 result를 통해 생성된 데이터베이스에 접근할 수 있는 레퍼런스값을 얻게된다.

위 코드 실행 시 개발자 도구에서 데이터베이스가 생성된 것을 확인할 수 있다.

 

ObjectStore 생성

ObjectStore는 서로 연관된 객체를 저장하는 공간이다. 만들면 재사용이 가능하기 때문에 단 한번 데이터베이스의 버전이 바뀔때만 ObjectStore가 생성되게 만들어야한다. 이때 upgradeneeded이벤트를 사용한다.
일반적인 서버내에 있는 데이터베이스에 비하면 indexedDB는 클라이언트에 내장되어 있기 때문에 사용자 관리가 어렵다. 그러므로 버전 관리를 통해 사용자를 관리해야한다.
request.addEventListener( ‘upgradeneeded’, function(event) {
	let db = event.target.result; //데이터베이스 레퍼런스값
	
	db.createObjectStore('topics', {keyPath:'id', autoIncrement:true});
	// topics라는 오브젝트스토어 생성, keyPath를 통해 오브젝트스토어 객체 식별이 가능 
	// autoIncrement는 오브젝트스토어에 객체가 추가될 때마다 아이디 값이 자동으로 1씩 증가하여
	// 중복되지 않은 식별자를 만들 수 있다.
});

오브젝트스토어는 식별자를 필요하기 때문에 id값을가지는 keyPath를 주었다.
또한 오브젝트 스토어 내에 객체들에게도 식별할 수 있는 값을 주기위해서 autoIncrement를 사용하였다.


위 코드 실행 시 개발자 도구에서 오브젝트스토어가 생긴것을 확인할 수 있다. 

 

ObjectStore 데이터 추가

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.target.result);
            });

db는 ObjectStore 생성 당시 데이터베이스 레퍼런스 값을 주었다. transaction은 모드를 지정하여 특정 ObjectStore에 접근할 수 있도록 해준다. 첫 번째 매개변수로 ObjectStore의 이름, 두번째는 읽기, 쓰기 어떤 모드로 할 것인지 지정한다. 선택하지않을 시에는 readonly 모드로 열리게 된다. readwrite는 쓰기,읽기 전용 모드이다.
이렇게 참조된 ObjectStore에 add("객체")함수를 써서 데이터를 추가해준다. 추가가 완료되었을 때 success 이벤트가 작동하는 것을 볼 수 있다.

여기서 event.target.result는 데이터의 키값을 가리킨다.

 

ObjectStore 데이터 읽기

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);
            });

prompt를 통해 id값을 입력받고, get("식별자 id값")함수를 통해 주어진 id값과 동일한 키를 갖는 객체를 지정할 수 있다.

 

ObjectStore 데이터 전체 목록 읽기

let store = db.transaction('topics', 'readonly').objectStore('topics');            
            let getAllReq = store.getAll();
            getAllReq.addEventListener('success', function(event){
                console.log(event.target.result);
            });

getAll()함수를 통해 ObjectStore내에 데이터 전체 목록을 읽어올 수 있다. 하지만 데이터 양이 너무 방대할 경우 getAll이 아닌 IDBCursor를 사용해야한다.

 

ObjectStore 데이터 변경

let store = db.transaction('topics', 'readwrite').objectStore('topics');
            let putReq = store.put({
                id:Number(prompt('id?')),
                title:prompt('title?'),
                body:prompt('body?')
            });
            putReq.addEventListener('success',function(event){
                console.log(event.target.result);
            });

put(키값, 변경할 객체 내용~)함수를 사용하여 키값과 값을 갖는 객체를 변경할 수 있다.

 

ObjectStore 데이터 삭제

let store = db.transaction('topics', 'readwrite').objectStore('topics');
            let deleteReq = store.delete(Number(prompt('id?')));
            deleteReq.addEventListener('success', function(event){
                console.log(event);
            });

delete(키값)함수를 통해 동일한 키값을 갖는 객체를 삭제할 수 있다.

 

출처

웹브라우저에 데이터를 저장하기 - IndexedDB