Explicação detalhada do conhecimento introdutório baseado em zero do banco de dados de armazenamento local front-end IndexedDB

Índice

Prefácio:

1.Introdução ao IndexedDB

2.Cenários de uso do IndexedDB

3. Recursos do IndexedDB

(1) Banco de dados não relacional (NoSql)

(2) Armazenamento persistente

(3) Operação assíncrona

 (4) Assuntos de suporte

(5) Estratégia de mesma origem

(6) Grande capacidade de armazenamento

4. Suplemento de conceito IndexedDB

①Loja de objetos de armazém

②Índice

③Cursor

④ Assuntos

5. Operação prática do IndexedDB

①Crie ou conecte-se ao banco de dados

②Inserir dados

③Leia os dados por meio da chave primária 

④ Consultar dados através do cursor

⑤ Consultar dados por meio de índice

⑥ Consultar dados por meio de índices e cursores

⑦ Consulta de paginação por meio de índice e cursor

⑧Atualizar dados

⑨Excluir dados por meio da chave primária

⑩Exclua os dados especificados por meio do índice e do cursor

⑪Feche o banco de dados

⑫Excluir banco de dados


 

Prefácio:

Existem dois bancos de dados no navegador: webSQL e IndexedDB. No entanto, se você precisar usar um banco de dados no navegador, geralmente usará o banco de dados indexado e o webSQL foi basicamente abandonado.

WebSQL é uma tecnologia de armazenamento local de navegador baseada em SQL, que é uma tecnologia não padronizada em HTML5. Embora o WebSQL seja mais conveniente de usar em alguns cenários, ele causou alguns problemas porque não é padronizado pelo W3C:

  1. Problemas de compatibilidade entre navegadores. Diferentes navegadores têm diferentes níveis de suporte para WebSQL, e alguns navegadores nem sequer o suportam, o que leva a problemas de compatibilidade entre WebSQL em terminais móveis e terminais de PC.
  2. Problemas de segurança. O WebSQL apresenta alguns riscos potenciais de segurança. Por exemplo, os invasores podem obter dados do usuário injetando instruções SQL maliciosas.
  3. Limite de tamanho do banco de dados. O limite de capacidade do banco de dados do WebSQL é implementado por cada navegador. Não existe um padrão universal e a maioria dos navegadores tem limites de tamanho do banco de dados.

Portanto, o W3C lançou o padrão IndexedDB como alternativa ao WebSQL e é suportado pelos principais navegadores. IndexedDB tem melhor compatibilidade entre plataformas, é seguro e confiável, suporta transações e operações assíncronas e pode atender melhor às necessidades de aplicativos móveis modernos e aplicativos de armazenamento de dados online.

(Soluções de armazenamento front-end, como cookies, armazenamento de sessões, etc.)


1.Introdução ao IndexedDB

O site oficial do MDN explica o banco de dados indexado desta forma:

IndexedDB é uma API de baixo nível para armazenar grandes quantidades de dados estruturados (também arquivos/objetos binários grandes (blobs)) no lado do cliente. A API usa índices para permitir pesquisas de dados de alto desempenho. Embora o Web Storage seja útil para armazenar pequenas quantidades de dados, é insuficiente para armazenar grandes quantidades de dados estruturados. IndexedDB fornece uma solução para este cenário.

 Métodos de armazenamento como cookies e localStorage têm restrições de tamanho de armazenamento. Se a quantidade de dados for grande e exigir armazenamento do cliente, use o banco de dados IndexedDB.

Cookies de sessão  Cookies persistentes sessãoSto
raiva
armazenamento local
ge
banco de dados indexado WebSQL
Tamanho de armazenamento 4kb 4kb 2,5 ~ 10 MB 2,5 ~ 10 MB >250MB Descontinuada
Data de validade O navegador fecha e limpa automaticamente Defina o tempo de expiração e
limpe após a expiração

Limpar após o navegador fechar
Salvar permanentemente
(a menos que
seja limpo manualmente)

Atualização ou exclusão manual
Descontinuada
Interaja com o servidor ter ter nenhum nenhum nenhum Descontinuada
política de acesso Pode ser acessado de acordo com a política de mesma origem
Pode ser acessado em conformidade com a política de mesma origem

Pode
ser acessado em conformidade com a política de mesma origem
Mesmo que tenham a mesma origem
, eles não podem
acessar um ao outro.
O cumprimento da
política de mesma origem pode
descontinuar
os acessadores
Descontinuada


2.Cenários de uso do IndexedDB

Todos os cenários são baseados na premissa de que o cliente precisa armazenar uma grande quantidade de dados:

  1. Interfaces como visualização de dados, grandes quantidades de dados e cada solicitação consomem muito desempenho.
  2. Para ferramentas de chat instantâneo, um grande número de mensagens precisa ser armazenado localmente.
  3. Quando a capacidade de outros métodos de armazenamento não for suficiente, o IndexedDB deve ser utilizado como último recurso.


3. Recursos do IndexedDB

(1) Banco de dados não relacional (NoSql)

Bancos de dados como MySQL são bancos de dados relacionais e sua principal característica é que os dados são armazenados na forma de uma tabela bidimensional , enquanto o banco de dados indexado é um banco de dados não relacional que armazena principalmente dados na forma de pares chave-valor .


(2) Armazenamento persistente

Os dados armazenados em cookies, localStorage, sessionStorage, etc. serão limpos depois de limparmos o cache do navegador, mas os dados armazenados usando IndexedDB não serão, a menos que o banco de dados seja excluído manualmente.


(3) Operação assíncrona

 IndexedDB não bloqueia o navegador durante a operação (de forma assíncrona), e os usuários ainda podem realizar outras operações.Isso contrasta fortemente
com o armazenamento local, que é síncrono.

 (4) Assuntos de suporte

IndexedDB oferece suporte a transações, o que significa que se uma etapa de uma série de etapas de operação falhar, toda a transação será cancelada e o banco de dados reverterá o estado anterior à ocorrência da transação, o que é semelhante às transações em bancos de dados como MySQL.

(5) Estratégia de mesma origem

IndexedDB também possui restrições de mesma origem e cada banco de dados corresponde ao nome de domínio onde foi criado. As páginas da Web só podem acessar bancos de dados sob seus próprios nomes de domínio, mas não bancos de dados entre domínios.

(6) Grande capacidade de armazenamento

Um dos recursos mais importantes do IndexedDB é também o melhor motivo para não usar métodos de armazenamento como localStorage.


4. Suplemento de conceito IndexedDB

①Loja de objetos de armazém

IndexedDB possui apenas o conceito de warehouse store , que pode ser entendido como uma tabela, ou seja, uma loja não possui o conceito de tabela, mas é apenas uma tabela.

②Índice

Existe também o conceito de índice no banco de dados relacional, podemos adicionar índice ao campo da tabela correspondente para acelerar a velocidade de pesquisa. Também existem índices no IndexedDB. O índice pode ser criado ao mesmo tempo ao criar o armazenamento. Ao consultar o armazenamento posteriormente, você pode filtrar pelo índice. Depois de adicionar um índice a um campo, se a inserção de dados subsequente for bem-sucedida, o campo de índice Não pode estar vazio.

③Cursor

Cursor é um novo conceito de banco de dados IndexedDB. Você pode pensar no cursor como um ponteiro. Quando quiser consultar todos os dados que atendem a uma determinada condição, você precisa usar o cursor. Deixe o cursor descer linha por linha. O o lugar onde o cursor vai é conveniente. Retorne esta linha de dados e então você poderá avaliar se esta linha de dados atende às condições.
⭕Observação: consultas IndexedDB não são tão convenientes quanto bancos de dados como MySQL. Ele só pode consultar dados por meio de chaves primárias, índices e cursores.

④ Assuntos

IndexedDB suporta transações, ou seja, consistência desde que haja falha na operação do banco de dados. será revertido para o estado original para garantir que os dados 


5. Operação prática do IndexedDB

Todas as operações no warehouse do IndexedDB são baseadas em transações.

①Crie ou conecte-se ao banco de dados

//打开数据库
//@param {object} dbName 数据库的名字
//@param {string} storeName 仓库名称
//@param {string} version 数据库的版本
//@return {object} 该函数会返回一个数据库实例

function openDB(dbName, version = 1) {
    return new Promise((resolve, reject) =>{
        // 兼容浏览器
        var indexedDB =
            window.indexedDB ||
            window.mozIndexedDB ||
            window.webkitIndexedDB ||
            window.msIndexedDB;
        let db;
        // 打开数据库,若没有则会创建
        const request = indexedDB.open(dbName,version);

        //数据库打开成功回调
        request.onsuccess = fuction(evetn){
            db = event.target.result; //数据库对象
            console.log("数据库打开成功");
            resolve(db);
        };
        //数据库打开失败的回调
        request .onerror= function(event){
            console.log("数据库打开报错");
        };

        //数据库有更新时候的回调
        request.onupgradeneeded = function (event){
            // 数据库创建或升级的时候会触发
            console.log("onupgradeneeded");
            db = event.target.result; //数据库对象var objectstore;
            // 创建存储库
            objectstore = db.createobjectstore("signalChat",{
                keyPath:"sequenceId",// 这是主键
                // autoIncrement: true // 实现自增
            });
            // 创建索引,在后面查询数据的时候可以根据索引查        
            objectStore.createIndex("link","link", { unique:false});
            objectstore.createIndex("sequenceId","sequenceId", {unique: false});
            objectStore.createIndex("messageType","messageType",{
                unique: false,
            });
        };
    });
}

A operação de criação de um banco de dados é encapsulada em uma função, e a função retorna um objeto de promessa, para que possa ser chamada em uma cadeia quando chamada.A função recebe principalmente dois parâmetros: nome do banco de dados e versão do banco de dados. Existem três funções principais de retorno de chamada dentro da função, a saber:

  • onsuccess: retorno de chamada após o banco de dados ser aberto ou criado com sucesso.Aqui retornamos a instância do banco de dados.
  • onerror: retorno de chamada após falha na abertura ou criação do banco de dados.
  • onupgradeneeded: Esta função será executada quando a versão do banco de dados mudar, por exemplo, se quisermos criar um novo repositório (tabela), podemos operar nesta função e atualizar a versão do banco de dados.

②Inserir dados

function addData(db, storeName, data) {
    var request = db
    .transaction([storeName],"readwrite") // 事务对象 指定表格名称和操作模式 ("只读"或"读写")
    .objectStore(storeName) // 仓库对象
    .add(data);

    request.onsuccess = function (event){    
        console.log("数据写入成功");
    };

    request.onerror = function (event) {
        console.log("数据写入失败");
    };
}

 IndexedDB insere dados por meio de transações. O método de inserção também é muito simples. Basta usar o método add fornecido pelo IndexedDB. Aqui, a operação de inserção de dados também é encapsulada em uma função que recebe três parâmetros, como segue:

  • banco de dados: Ao criar ou conectar-se ao banco de dados, a instância do banco de dados retornada precisa ser salva naquele momento.
  • storeName: nome do armazém (ou nome da tabela).O armazém foi criado ao criar ou conectar-se ao banco de dados.
  • dados: os dados a serem inseridos, geralmente um objeto

 ⭕Nota:  Os dados inseridos são um objeto e devem conter o par chave-valor do índice declarado


③Leia os dados por meio da chave primária 

function getDataByKey(db, storeName, key) {
    return new Promise((resolve, reject) => {
        var transaction = db.transaction([storeName]); // 事务
        var objectstore = transaction.objectstore(storeName); // 仓库对象
        var request = objectstore.get(key); // 通过主键获取数据

        request.onerror = function (event) {
            console.log("事务失败");
        };
    
        request.onsuccess = function (event) {
            console.log("主键查询结果:",,request.result);
            resolve(request.result);
        };
    });
}

④ Consultar dados através do cursor

function cursorGetData(db, storeName){
    let list = [];
    var store = db
        .transaction(storeName,"readwrite") // 事务
        .objectstore(storeName); // 仓库对象
    var request = store.openCursor(); // 指针对象
    // 游标开启成功,逐行读数据
    request.onsuccess = function (e) {
        var cursor = e.target.result;
        if (cursor) {
            // 必须要检查
            list.push(cursor.value);
            cursor.continue(); // 遍历了存储对象中的所有内容
        } else {
            console.log("游标读取的数据",list);
        }
    };
}

⑤ Consultar dados por meio de índice

function getDataByIndex(db,storeName, indexName, indexValue){
    var store = db,transaction(storeName, "readwrite").objectstore(storeName);
    var request = store.index(indexName).get(indexValue);
    request.onerror = function () {
        console.log("事务失败");
    };
    request.onsuccess = function (e) {
        var result = e.target.result;
        console.log("索引查询结果:",result);
    };
}

O nome do índice é o nome do índice criado quando o armazém é criado, que é a chave no par chave-valor.Todos os dados que satisfaçam o valor do índice da função de entrada serão eventualmente consultados.

O nome do índice é o nome do índice criado quando o warehouse é criado, que é a chave no par chave-valor. Eventualmente, apenas um dado com o valor do índice passado para a função será consultado.


⑥ Consultar dados por meio de índices e cursores

Os dados consultados apenas através do índice ou cursor são parte ou todos os dados. Se você deseja consultar todos os dados do índice que atendam a determinadas condições, é impossível usar apenas o índice ou o cursor. Claro, você pode consultar todos os dados e filtrar os dados apropriados na matriz de loop, mas esta não é a melhor maneira de implementá-los. A melhor maneira é, claro, combinar índices e cursores.

function cursorGetDataByIndex(db,storeName ,indexName ,indexValue ){
    let list = [];
    var store = db.transaction(storeName."readwrite").objectstore(storeName); // 仓库对象
    var request = store
        .index(indexName) // 索引对象
        .openCursor(IDBKeyRange.only(indexValue)); // 指针对象
    request.onsuccess = function (e) {var cursor = e.target.result;
        if (cursor) {
            // 必须要检查
            list.push(cursor.value);
            cursor.continue(); // 遍历了存储对象中的所有内容
        } else {
            console.log("游标索引查询结果:",list);
        }
    };
    request.onerror = function (e) {};
}

⑦ Consulta de paginação por meio de índice e cursor

A consulta de paginação IndexedDB não é tão simples quanto a consulta de paginação MySQL. Ele não fornece APIs prontas, como limite, etc., então você precisa implementar a paginação sozinho.

function cursorGetDataByIndexAndPage(
    db ,  //数据库实例
    storeName,
    indexName,
    indexValue,
    page,
    pageSize
){
    let list = []; //设置空数组用来保存实例
    let counter = ; // 计数器——停止游标
    let advanced = true; // 是否跳过多少条查询
    var store = db.transaction(storeName, "readwrite"),obiectStore(storeName): // 库对象
    var request = store
        .index(indexName) // 索引对象
        .openCursor(IDBKeyRange.only(indexValue)); // 指针对象
    request.onsuccess = function (e) {
        var cursor = e.target.result;
        if (page > 1 && advanced) {
            advanced = false; //是否跳转
            cursor.advance((page - 1) * pagesize); // 跳过多少条
            return;
        }
        if (cursor) {
                // 必须要检查
                list.push(cursor.value);
                counter++;
                if (counter < pageSize) [
                cursor.continue(); // 遍历了存储对象中的所有内容
            } else {
                cursor = null;
                console.log("分页查询结果",,list);
            }
       } else {
            console.log("分页查询结果",list);
       }
    };    
    request.onerror = function (e) {};
}

Uma API do IndexedDB: avanço. Esta função permite que o cursor pule quantos itens iniciar a consulta. Se a paginação tiver 10 dados por página e agora você precisar consultar a segunda página, será necessário pular os primeiros 10 dados, começar a consultar a partir do 11º dado, até que o contador seja igual a 10 e, em seguida, feche o cursor e finalize a consulta.


⑧Atualizar dados

É relativamente simples atualizar dados no IndexedDB. Use o método put diretamente. Vale ressaltar que se os dados não existirem no banco de dados, os dados serão adicionados por padrão, caso contrário serão atualizados. Se você gosta de usar o método put para atualizações e novas adições, isso também é viável.

function updateDB(db, storeName, data) {
    var request = db
        .transaction([storeName],"readwrite") // 事务对象
        .objectstore(storeName) // 仓库对象
        .put(data);

    request.onsuccess = function () {
        console.log("数据更新成功");
    };

    request.onerror = function () {
        console.log("数据更新失败");
    };
}

 O método put recebe um objeto de dados


⑨Excluir dados por meio da chave primária

A chave primária é o keyPath declarado ao criar o banco de dados e é único.

function deleteDB(db, storeName, id) {
    var request = db
        .transaction([storeName],"readwrite")
        .objectstore(storeName)
        .delete(id);
    request.onsuccess = function () {
        console.log("数据删除成功");
    };

    request.onerror = function () {
        console.log("数据删除失败");
    };
}

⑩Exclua os dados especificados por meio do índice e do cursor

Às vezes, o valor da chave primária não pode ser obtido e só pode ser excluído por meio do valor do índice. Dessa forma, você pode excluir um dado (o valor do índice é único) ou todos os dados que atendem às condições (o valor do índice não é exclusivo). ).

function cursorDelete(db,storeName,indexName,indexValue){
    var store = db,transaction(storeName,"readwrite").objectstore(storeName);
    var request = store
        .index(indexName) // 索引对象
        .openCursor(IDBKeyRange.only(indexValue)); // 指针对象
    request.onsuccess = function (e) {
        var cursor = e.target.result;
        var deleteRequest;
        if (cursor) {
            deleteRequest = cursor.delete(); // 请求删除当前项
            deleteRequest.onerror = function () {
                console.log("游标删除该记录失败");
            };
            deleteRequest.onsuccess = function () {    
                console.log("游标删除该记录成功");
            };
            cursor.continue();
        }
    };
    request.onerror = function (e){ };
}

O código acima pode excluir todos os dados cujo valor de índice é indexValue. É importante notar que IDBKeyRange.only0API é usado. Esta API significa que só pode ser usada quando dois valores são iguais. Para obter uma explicação específica da API, consulte para o site oficial do MDN.


⑪Feche o banco de dados

 Quando a operação do banco de dados for concluída, é recomendável fechá-lo para economizar recursos.

function closeDB(db) {
    db.close();
    console.log("数据库已关闭");
}

⑫Excluir banco de dados

function deleteDBAll(dbName){
    console.log(dbName);
    let deleteRequest = window,indexedDB.deleteDatabase(dbName);
    deleteRequest.onerror = function (event) {
        console.log("删除失败");
    };
    deleteRequest.onsuccess = function (event) {
        console.log("删除成功");
    };
}

Resumir:

IndexedDB é uma API definida no padrão HTML5 para armazenamento de grandes quantidades de dados estruturados no lado do navegador. Possui as seguintes características:

  1. API assíncrona: IndexedDB usa API assíncrona para acesso e operações, que pode lidar melhor com as necessidades de grandes quantidades de armazenamento de dados e alto acesso simultâneo a dados.
  2. Armazenamento de dados em grande escala: IndexedDB suporta o armazenamento de grandes quantidades de dados estruturados e suporta operações avançadas, como indexação e processamento de transações.É adequado para cenários que exigem armazenamento local de alto desempenho de dados em grande escala.
  3. Consulta de banco de dados: IndexedDB oferece suporte a consultas complexas, incluindo consultas de intervalo e consultas de cursor, o que pode ajudar os desenvolvedores a realizar consultas precisas e recuperação eficiente de dados.
  4. Design de banco de dados: o próprio IndexedDB é um banco de dados de armazenamento de valor-chave baseado em NoSQL. Ele tem um conceito de design semelhante a outros bancos de dados (como MongoDB) e pode ajudar os desenvolvedores a realizar design de banco de dados flexível e design de modelo de dados.

Comparado com outras tecnologias de armazenamento no navegador, o IndexedDB tem melhor compatibilidade, segurança e escalabilidade entre plataformas e pode atender a vários requisitos de armazenamento de dados de aplicativos da web modernos. No entanto, devido à sua complexidade de uso, os desenvolvedores precisam ter um conhecimento profundo da tecnologia de armazenamento do lado do navegador, programação assíncrona JavaScript, design de banco de dados e consultas para utilizar plenamente suas vantagens.

Acho que você gosta

Origin blog.csdn.net/m0_61662775/article/details/131029016
Recomendado
Clasificación