indexedDB

Joey·2024년 12월 1일

indexedDB?

IndexedDB는 브라우저에 내장된 비관계형 데이터베이스입니다. 클라이언트 측에서 대용량 데이터를 저장하고 효율적으로 관리할 수 있도록 설계되었습니다.

IndexedDB를 사용하면 구조화된 데이터를 영구적으로 저장하고, 검색, 수정, 삭제와 같은 작업을 수행할 수 있습니다.

IndexedDB의 구성 요소

데이터베이스 (Database)

IndexedDB는 하나의 데이터베이스 안에 여러 개의 Object Store를 포함합니다.

객체 저장소 (Object Store)

데이터를 저장하는 단위입니다. 키-값 형태로 데이터를 저장하며, 관계형 데이터베이스의 테이블과 비슷한 역할을 합니다.

키 (Key)

데이터에 접근하기 위한 고유 식별자입니다. 키는 직접 지정하거나, 자동 생성할 수 있습니다.

인덱스 (Index)

특정 필드에 대해 검색 성능을 높이기 위한 구조입니다. 관계형 데이터베이스의 인덱스와 비슷합니다.

트랜잭션 (Transaction)

데이터 작업을 안전하게 처리하는 단위입니다. 트랜잭션은 읽기 또는 읽기/쓰기 모드로 실행됩니다.

IndexedDB 기본 작업 흐름

데이터베이스 열기 > 업그레이드 이벤트 처리 > 트랜잭션 시작 > 데이터 작업 수행 > 트랜잭션 완료

데이터베이스 생성 및 객체 저장소 설정

const request = indexedDB.open("MyDatabase", 1);
//indexedDB.open 메서드를 사용하여 데이터베이스를 엽니다.
//데이터베이스가 없으면 새로 생성합니다.

request.onupgradeneeded = function (event) {
const db = event.target.result;
//데이터베이스가 처음 생성되거나 버전이 변경될 때 onupgradeneeded 이벤트가 발생합니다. 이 이벤트에서 객체 저장소와 인덱스를 설정합니다.

// 객체 저장소 생성
if (!db.objectStoreNames.contains("users")) {
db.createObjectStore("users", { keyPath: "id" });
//db.objectStoreNames에 users라는 객체 저장소가 있다면의 부정 연산자
//그 조건을 충족한다면 => "users"라는 이름의 객체 저장소를 생성하고, keyPath로 id 필드를 설정합니다. 여기서 keyPath는 객체 저장소에서 각 객체의 고유 키로 사용할 속성을 지정하는 역할을 합니다.
  }
};

request.onsuccess = function (event) {
const db = event.target.result;
console.log("Database opened successfully:", db.name);
};//요청이 성공적으로 완료되었을 경우 onsuccess가 호출됩니다

request.onerror = function (event) {
console.error("Database error:", event.target.errorCode);
};//반대로 요청이 실패했을 때엔 onerror가 호출됩니다.

데이터 추가

const addData = (db) => {
const transaction = db.transaction("users", "readwrite"); // 트랜잭션 시작
//트랜잭션은 데이터 작업을 안전하게 처리하는 단위입니다.
const store = transaction.objectStore("users");
//db.transaction("users", "readwrite")는 데이터베이스의 "users" 객체 저장소를 대상으로 읽기/쓰기(readwrite) 권한을 가지는 트랜잭션을 생성합니다.
const user = { id: 1, name: "Alice", age: 25 };
//그럼 이 user라는 데이터를 ACID원칙을 만족하면서 안전하게 처리가 되겠습니다.
const request = store.add(user);
//여기서 그 데이터를 store에 추가하는 것 같죠?
  request.onsuccess = () => {
    console.log("Data added successfully");
  };
//성공시 onsuccess와 함께 콘솔창에 Data added successfully 라는 메세지가 뜨겠습니다.
  request.onerror = (event) => {
    console.error("Error adding data:", event.target.error);
  };
};
//하지만 실패시엔 onerror와 함께 Error adding data: ~~~뜹니다.

// 데이터베이스 연결 후 데이터 추가
request.onsuccess = function (event) {
  const db = event.target.result;
  addData(db);
};
//네, 추가되었습니다 껄껄

데이터 검색

const getData = (db, id) => {
  const transaction = db.transaction("users", "readonly"); //여기도 똑같이 트랜잭션하고요.
  const store = transaction.objectStore("users");
//참조해줍니다
  const request = store.get(id);
//id라는 값을 조회해주는거 같죠?
  request.onsuccess = () => {
    // 요청이 성공했을 때 실행되는 함수
    if (request.result) {
// request.result가 존재하면, 즉 데이터를 성공적으로 가져왔다면
      console.log("Data retrieved:", 
// 데이터가 성공적으로 검색된 경우, 콘솔에 "Data retrieved:"와 함께 검색된 데이터를 출력request.result);
    } else {
// request.result가 없다면, 즉 데이터가 존재하지 않으면
      console.log("No data found for ID:", id);
// request.result가 없다면, 즉 데이터가 존재하지 않으면
    }
  };
//아까와는 다르게 onsuccess에 조건문이 걸려있는 모습 해석을 하자면 데이터가 존재하면 그 데이터를 출력하고,
//데이터가 없다면 해당 ID에 대한 데이터가 없다는 메시지를 출력합니다.
request.onerror = (event) => {
// 요청이 실패했을 때 실행되는 함수
console.error("Error retrieving data:", event.target.error);
// 콘솔에 "Error retrieving data:"와 함께 오류 정보를 출력
// event.target.error는 요청에서 발생한 오류 객체 를 나타냅니다
  };
};

// 데이터베이스 연결 후 데이터 검색
request.onsuccess = function (event) {
  const db = event.target.result;
  getData(db, 1);
}; // 검색해줍니다.

위 세가지 예제에서 나온 주요 이벤트

onupgradeneeded
데이터베이스 생성 또는 버전 변경 시 호출됩니다.
객체 저장소 및 인덱스를 초기화하거나 변경할 때 사용됩니다.

onsuccess
요청이 성공적으로 완료되었을 때 호출됩니다.

onerror
요청이 실패했을 때 호출됩니다.

onblocked
데이터베이스가 다른 연결에 의해 잠겨 있어 업그레이드가 불가능할 때 호출됩니다.

IndexedDB의 장/단점

장점

1.대용량 데이터 저장
JSON, 파일, Blob 등 다양한 데이터 타입을 저장할 수 있습니다.
2.오프라인 지원
인터넷 연결 없이도 데이터 작업이 가능합니다.
3.트랜잭션 기반
데이터 작업의 안정성을 보장합니다.
4.브라우저 지원
대부분의 최신 브라우저에서 지원됩니다.

단점

1.복잡한 API
사용이 어렵고, 콜백 패턴이 많아 코드가 복잡해질 수 있습니다.
2.브라우저 의존성
브라우저 간의 세부 동작이 다를 수 있습니다.
3.동기화 문제
IndexedDB는 클라이언트 측 데이터베이스이므로, 서버와의 동기화는 별도로 구현해야 합니다.

SPA(Single Page Application)에서 자주 사용되니까 익혀두자.

profile
멋쟁이사자처럼 프론트엔드 부트캠프 12기

0개의 댓글