JavaScript - IndexedDB: 클라이언트 측 데이터 저장의 문이打开了
안녕하세요, 열정적인 개발자 여러분! 오늘 우리는 IndexedDB라는 흥미로운 세계로 여행을 떠납니다. 여러분의 친절한 이웃 컴퓨터 과학 교사로서 저는 이 강력한 기술을 안내해 드리겠습니다. 이 기술은 여러분의 웹 애플리케이션에 대한 생각을 완전히 혁명시킬 수 있을지도 모릅니다. 그麼, 좋아하는 음료를 한 잔 손에 들고, 가장 편안한 의자에 앉아 함께 들어보겠습니다!
IndexedDB는 무엇인가요?
IndexedDB는 여러분의 웹 브라우저에 거주하는 마이크로 데이터베이스입니다. 간단한 텍스트에서 복잡한 객체, 이미지, 심지어 파일까지 다양한 정보를 저장할 수 있는 디지털 파일 캐비닛을 상상해 보세요. 그것이 IndexedDB입니다!
하지만 여기 더 재미있는 점이 있습니다: 서버에서 먼 곳에 있는 전통적인 데이터베이스와 달리, IndexedDB는 사용자 기기에 거주합니다. 이는 인터넷 연결이 없을 때에도 여러분의 웹 애플리케이션이 데이터를 처리할 수 있음을 의미합니다. 정말 멋지죠?
IndexedDB의 주요 기능
- 비동기적 성격: 데이터를 처리할 때 앱을 동결시키지 않습니다.
- 객체 지향: JavaScript 객체를 직접 저장할 수 있어 복잡한 변환 필요 없음.
- 대용량 데이터 저장: 다른 클라이언트 측 저장 옵션보다 훨씬 더 많은 데이터를 저장할 수 있습니다.
IndexedDB를 사용해야 하는 이유
이제 여러분은 "localStorage와 같은 다른 옵션을 가지고 있을 때 왜 IndexedDB를 귀찮게 해야 하나요?"라고 고민할 수도 있습니다. 훌륭한 질문입니다! 소소한 이야기로 설명해 드리겠습니다.
여러분이 메모 앱을 개발 중이라고 상상해 보세요. localStorage를 사용하면 단순한 문자열만 저장할 수 있습니다. 이는 각 책이 하나의 문장만 포함할 수 있는 도서관을 정리하려는 것과 같습니다. 매우 유용하지 않죠?
반면에 IndexedDB는 각 책이 전체 소설, 이미지, 심지어 동영상을 포함할 수 있는 마법의 도서관과 같습니다. 이 도서관을 매우 빠르게 검색할 수 있으며, 일반 책장보다 훨씬 더 많은 정보를 저장할 수 있습니다.
IndexedDB를 사용해야 하는 몇 가지 설득력 있는 이유는 다음과 같습니다:
- 오프라인 기능: 인터넷 연결이 없을 때에도 앱을 계속 작동시킬 수 있습니다.
- 성능: 대용량 구조화된 데이터를 효율적으로 처리합니다.
- 복잡한 데이터 구조: JavaScript 객체를 쉽게 저장하고检索할 수 있습니다.
- 트랜잭션 데이터베이스 모델: 문제가 발생더라도 데이터 일관성을 보장합니다.
CRUD 연산
이제 코드로 손을 더러워보겠습니다! 데이터베이스 세계에서 우리는 종종 CRUD 연산에 대해 이야기합니다. 아니, 이것은 청소와는 관련이 없습니다 (하지만 데이터에 대해 청소하는 데 도움이 될 수 있습니다). CRUD는 Create, Read, Update, Delete를 의미합니다. 이는 IndexedDB에서 수행할 기본 연산입니다.
다음은 예제를 통해 이를 설명해 드리겠습니다:
1. Create (데이터 추가)
let db;
const request = indexedDB.open("MyNotes", 1);
request.onupgradeneeded = (event) => {
db = event.target.result;
const objectStore = db.createObjectStore("notes", { keyPath: "id", autoIncrement: true });
};
request.onsuccess = (event) => {
db = event.target.result;
const transaction = db.transaction(["notes"], "readwrite");
const objectStore = transaction.objectStore("notes");
const note = { title: "My First Note", content: "Hello, IndexedDB!" };
const request = objectStore.add(note);
request.onsuccess = () => {
console.log("Note added successfully");
};
};
이 예제에서는 "MyNotes" 데이터베이스를 열고 메모를 추가합니다. 일기에 새로운 기록을 쓰는 것과 같습니다.
2. Read (데이터检索)
const transaction = db.transaction(["notes"]);
const objectStore = transaction.objectStore("notes");
const request = objectStore.get(1);
request.onsuccess = (event) => {
if (request.result) {
console.log("Note:", request.result);
} else {
console.log("No note found with id 1");
}
};
여기서는 id가 1인 메모를检索합니다. 일기의 특정 페이지를 펼쳐 읽는 것과 같습니다.
3. Update (데이터 수정)
const transaction = db.transaction(["notes"], "readwrite");
const objectStore = transaction.objectStore("notes");
const request = objectStore.get(1);
request.onsuccess = (event) => {
const data = event.target.result;
data.content = "Updated content!";
const updateRequest = objectStore.put(data);
updateRequest.onsuccess = () => {
console.log("Note updated successfully");
};
};
이 코드는 기존 메모를 수정합니다. 일기에 있는 것을 지우고 새로운 내용을 쓰는 것과 같습니다.
4. Delete (데이터 삭제)
const request = db.transaction(["notes"], "readwrite")
.objectStore("notes")
.delete(1);
request.onsuccess = () => {
console.log("Note deleted successfully");
};
여기서는 메모를 삭제합니다. 일기에서 페이지를 찢는 것과 같습니다 (하지만 실제 생활에서는 그러지 마세요, 아이들!).
구현 예제: 간단한 메모 앱
이제 모든 것을 통합하여 간단한 예제를 보여드리겠습니다. 우리는 모든 CRUD 연산을 보여주는 간단한 메모 앱을 만들겠습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IndexedDB Notes App</title>
</head>
<body>
<h1>My Notes</h1>
<input type="text" id="noteTitle" placeholder="Note Title">
<textarea id="noteContent" placeholder="Note Content"></textarea>
<button id="addNote">Add Note</button>
<div id="notesList"></div>
<script>
let db;
const dbName = "NotesDB";
const request = indexedDB.open(dbName, 1);
request.onerror = (event) => {
console.error("Database error: " + event.target.error);
};
request.onsuccess = (event) => {
db = event.target.result;
displayNotes();
};
request.onupgradeneeded = (event) => {
db = event.target.result;
const objectStore = db.createObjectStore("notes", { keyPath: "id", autoIncrement: true });
};
function addNote() {
const title = document.getElementById("noteTitle").value;
const content = document.getElementById("noteContent").value;
const transaction = db.transaction(["notes"], "readwrite");
const objectStore = transaction.objectStore("notes");
const note = { title: title, content: content };
const request = objectStore.add(note);
request.onsuccess = () => {
document.getElementById("noteTitle").value = "";
document.getElementById("noteContent").value = "";
displayNotes();
};
}
function displayNotes() {
const notesList = document.getElementById("notesList");
notesList.innerHTML = "";
const objectStore = db.transaction("notes").objectStore("notes");
objectStore.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
const noteElement = document.createElement("div");
noteElement.innerHTML = `
<h3>${cursor.value.title}</h3>
<p>${cursor.value.content}</p>
<button onclick="deleteNote(${cursor.value.id})">Delete</button>
`;
notesList.appendChild(noteElement);
cursor.continue();
}
};
}
function deleteNote(id) {
const request = db.transaction(["notes"], "readwrite")
.objectStore("notes")
.delete(id);
request.onsuccess = () => {
displayNotes();
};
}
document.getElementById("addNote").onclick = addNote;
</script>
</body>
</html>
이 예제는 간단한 웹 페이지에서 메모를 추가, 보여주고 삭제할 수 있는 기능을 제공합니다. 이는 IndexedDB의 강력함을 보여주는 기본적인 메모 앱입니다.
결론
그렇습니다, 친구들! IndexedDB의 땅을 거쳐 여행을 했습니다. 기본 개념을 이해하는 것에서 시작하여 실제 예제를 구현하는 것까지. 기억하시죠, 강력한 도구는 연습이 필요합니다. 처음에는 약간 혼란스러울 수 있지만, 계속 실험하고 코딩을 하다 보면 곧 IndexedDB 마스터가 될 것입니다!
마지막으로, 오늘 우리가 다루었던 주요 IndexedDB 메서드를 요약하겠습니다:
메서드 | 설명 |
---|---|
indexedDB.open() |
데이터베이스 연결 열기 |
createObjectStore() |
새로운 객체 저장소 생성 |
transaction() |
새로운 트랜잭션 시작 |
add() |
객체 저장소에 새로운 레코드 추가 |
put() |
객체 저장소에 기존 레코드 업데이트 |
get() |
객체 저장소에서 레코드检索 |
delete() |
객체 저장소에서 레코드 삭제 |
openCursor() |
레코드를 순회할 커서 열기 |
이 것들을 손에 두고, 곧 IndexedDB 고수가 될 것입니다! 행복하게 코딩하시고, 데이터베이스가 항상 색인되기를 바랍니다!
Credits: Image by storyset