浏览器端大量数据存储方案-indexedDB

125 阅读2分钟

今日遇到一个需要在本地存储视频的需求,视频较大,超过200M,所以选择使用indexedDB。 我使用了indexedDB Promise,该库对 IndexedDB API 做了 promise 封装。

indexedDB结构介绍

erDiagram
database ||--|{ "object store" : createObjectStore
"object store" ||--o{ index : createIndex

操作步骤:

  1. open一个database。
  2. 创建object store,定义primary key,定义index。
  3. database的交互
    • 先transaction,增删改查全部在transaction中进行。

open database,创建object store和index store

indexedDB 除了 opera mini 不支持,其他已普遍支持了。建议做功能检测。最简单的方式就是检查 window 对象。

import { openDB } from 'idb';

// indexedDB功能检测
if (!('indexedDB' in window)) { 
    console.log("This browser doesn't support IndexedDB!"); 
    return; 
} 
const dbPromise = await idb.open('test-db1', 1, {
    // upgrade方法会在当前database version第一次打开时执行。
    upgrade(upgradeDb) => {
        // 判断当前database是否有‘people’这个object store,没有就创建
        if (!upgradeDb.objectStoreNames.contains('people')) {
            // 创建‘people’object store,primary key是‘email’
            const peopleOS = upgradeDb.createObjectStore('people', {keyPath: 'email'}); 
            // 创建2个index object,key为gender的‘genderIndex’ index object,key不唯一。
            peopleOS.createIndex('genderIndex', 'gender', {unique: false});
            // key为ssn的‘ssnIndex’ index object,key唯一。
            peopleOS.createIndex('ssnIndex', 'ssn', {unique: true}); 
        }
    }
});

处理数据

// readwrite表示允许读写,如果只是获取数据操作,值应该是read
const tx = dbPromise.transaction('people', 'readwrite');
const store = tx.objectStore('people');

添加数据add

// 单条新增
await store.add({
    email: 'Tom@xx.com'
    name: 'Tom',
    gender: 'male',
    ssn: '0001',
    age: 22,
})
// 批量新增
await Promise.all([
  tx.store.add({
    email: 'Tom@xx.com'
    name: 'Tom',
    gender: 'male',
    ssn: '0001',
    age: 22,
  }),
  tx.store.add({
    email: 'Jack@xx.com'
    name: 'Jack',
    gender: 'male',
    ssn: '0002',
    age: 23,
  }),
  tx.done,
]);

from object store读取数据getgetKeygetAllgetAllKeys

// 读取单条
await store.get('Tom@xx.com');
// 读取key值
await store.getKey('Tom@xx.com');
// 读取所有数据
await store.getAll();
// 读取所有key
await store.getAllKeys();

from index store读取数据getFromIndexgetKeyFromIndexgetAllFromIndexgetAllKeysFromIndex

// 读取单条
await dbPromise.getFromIndex('people', 'ssnIndex', '0001');
// 读取key值
await dbPromise.getKeyFromIndex('people', 'ssnIndex', '0001');
// 读取所有数据
await dbPromise.getAllFromIndex('people', 'ssnIndex');
// 读取所有key
await dbPromise.getAllKeysFromIndex('people', 'ssnIndex');

修改数据put,如果没有这条数据,会直接添加,类似add操作。

// 
await store.put({
    name: 'Tom',
    gender: 'male',
    ssn: '0001',
    age: 22,
    email: 'Tom@xx.com'
})

删除数据delete

// 
await store.delete('Tom@xx.com')
await tx.done;

参考文档