1. 理解IndexedDB与前端数据存储需求
在前端开发中,数据存储一直是个重要话题。随着Web应用越来越复杂,我们经常需要在浏览器端存储大量结构化数据。传统的localStorage虽然简单易用,但存在明显局限:只能存储字符串、容量有限(通常5MB左右)、缺乏索引和查询能力。这时候,IndexedDB就成为了更专业的选择。
IndexedDB是一种底层API,用于在客户端存储大量结构化数据。它提供了以下几个关键特性:
- 支持事务型数据库系统
- 使用对象存储而非表格存储
- 支持索引实现高效查询
- 异步API设计避免阻塞UI
- 存储容量远大于localStorage(通常为浏览器可用空间的50%)
在实际项目中,我经常遇到需要离线存储的场景。比如一个电商网站的商品列表,我们希望用户在没有网络时也能浏览最近查看过的商品;或者一个文档编辑器,需要自动保存草稿到本地。这些场景下,IndexedDB都是理想选择。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. IndexedDB基础概念解析
2.1 核心组件结构
理解IndexedDB首先要掌握它的几个核心概念:
- 数据库(Database):最顶层容器,每个域名下可以创建多个数据库
- 对象存储(Object Store):相当于关系型数据库中的表
- 索引(Index):用于快速查找对象存储中的数据
- 事务(Transaction):所有操作都必须发生在事务中
- 游标(Cursor):用于遍历对象存储或索引中的记录
2.2 与关系型数据库的对比
虽然IndexedDB被称为"浏览器中的数据库",但它与传统SQL数据库有很大不同:
| 特性 | IndexedDB | SQL数据库 |
|---|---|---|
| 数据模型 | 对象存储 | 表格 |
| 查询语言 | JavaScript API | SQL |
| 索引 | 支持 | 支持 |
| 事务 | 支持 | 支持 |
| 数据类型 | 结构化克隆算法支持的类型 | 严格类型系统 |
| 模式 | 动态模式 | 固定模式 |
3. 实战:创建第一个IndexedDB数据库
3.1 初始化数据库连接
让我们从最基本的数据库创建开始。以下代码展示了如何打开或创建一个IndexedDB数据库:
javascript复制const request = indexedDB.open('MyFirstDB', 1);
request.onerror = (event) => {
console.error('数据库打开失败:', event.target.error);
};
request.onsuccess = (event) => {
const db = event.target.result;
console.log('数据库连接成功');
// 这里可以执行数据库操作
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 在这里创建对象存储和索引
};
关键点说明:
indexedDB.open()第一个参数是数据库名,第二个是版本号onupgradeneeded是唯一可以修改数据库结构的地方- 连接是异步的,所有操作都需要在success事件后执行
3.2 创建对象存储和索引
在onupgradeneeded回调中,我们可以定义数据库结构:
javascript复制request.onupgradeneeded = (event) => {
const db = event.target.result;
// 创建对象存储(类似表)
const store = db.createObjectStore('books', {
keyPath: 'id',
autoIncrement: true
});
// 创建索引
store.createIndex('by_author', 'author', { unique: false });
store.createIndex('by_title', 'title', { unique: true });
};
这里我们创建了一个名为books的对象存储,并定义了两个索引:
by_author:按作者查询,允许重复值by_title:按书名查询,要求唯一
4. 数据操作CRUD实战
4.1 添加数据
向对象存储中添加数据需要通过事务:
javascript复制function addBook(db, book) {
const transaction = db.transaction(['books'], 'readwrite');
const store = transaction.objectStore('books');
const request = store.add(book);
request.onsuccess = () => {
console.log('书籍添加成功');
};
request.onerror = (event) => {
console.error('添加失败:', event.target.error);
};
}
// 使用示例
const book = {
title: 'JavaScript高级程序设计',
author: 'Nicholas C. Zakas',
year: 2020,
price: 99
