Detailed explanation of the zero-based introductory knowledge of the front-end local storage database IndexedDB

Table of contents

Foreword:

1.Introduction to IndexedDB

2.IndexedDB usage scenarios

3.IndexedDB features

(1) Non-relational database (NoSql)

(2) Persistent storage

(3)Asynchronous operation

 (4)Support affairs

(5) Same origin strategy

(6) Large storage capacity

4.IndexedDB concept supplement

①Warehouse objectStore

②Indexindex

③Cursor

④ Affairs

5.IndexedDB practical operation

①Create or connect to the database

②Insert data

③Read data through primary key 

④ Query data through cursor

⑤ Query data through index

⑥ Query data through indexes and cursors

⑦Paging query through index and cursor

⑧Update data

⑨Delete data through primary key

⑩Delete specified data through index and cursor

⑪Close the database

⑫Delete database


 

Foreword:

There are two databases on the browser: webSQL and IndexedDB. However, if you need to use a database on the browser, you will generally use the Indexed DB database, and webSQL has basically been abandoned.

WebSQL is a SQL-based browser local storage technology, which is a non-standardized technology in HTML5. Although WebSQL is more convenient to use in some scenarios, it has caused some problems because it is not standardized by W3C:

  1. Compatibility issues between browsers. Different browsers have different levels of support for WebSQL, and some browsers even do not support it at all, which leads to compatibility issues between WebSQL on mobile terminals and PC terminals.
  2. Security issues. WebSQL has some potential security risks. For example, attackers can obtain user data by injecting malicious SQL statements.
  3. Database size limit. The database capacity limit of WebSQL is implemented by each browser. There is no universal standard, and most browsers have limits on database size.

Therefore, W3C launched the IndexedDB standard as an alternative to WebSQL and is supported by major browsers. IndexedDB has better cross-platform compatibility, is safe and reliable, supports transactions and asynchronous operations, and can better meet the needs of modern mobile applications and online data storage applications.

(Front-end storage solutions such as cookies, sessionstorage, etc.)


1.Introduction to IndexedDB

The MDN official website explains Indexed DB this way:

IndexedDB is a low-level API for storing large amounts of structured data (also files/binary large objects (blobs)) on the client side. The API uses indexes to enable high-performance searches of data. Although Web Storage is useful for storing smaller amounts of data, it is insufficient for storing larger amounts of structured data. IndexedDB provides a solution for this scenario.

 Storage methods such as cookies and localStorage have storage size restrictions. If the amount of data is large and requires client storage, use the IndexedDB database.

Session cookies  Persistent Cookies sessionSto
rage
localStora
ge
indexedDB WebsQL
Storage size 4kb 4kb 2.5~10MB 2.5~10MB >250MB Deprecated
Expiration time Browser closes and automatically clears Set expiration time and
clear after expiration

Clear after browser closes
Save permanently
(unless
cleared manually)
Manual update
or delete
Deprecated
Interact with the server have have none none none Deprecated
access policy Can be accessed according to the same-origin policy
Can be accessed in compliance with the same-origin policy

Can
be accessed in compliance with the same-origin policy
Even if they have the same origin
, they cannot
access each other.
Complying with the same-origin
policy can
deprecated
accessors
Deprecated


2.IndexedDB usage scenarios

All scenarios are based on the premise that the client needs to store a large amount of data:

  1. Interfaces such as data visualization, large amounts of data, and each request consume a lot of performance.
  2. For instant chat tools, a large number of messages need to be stored locally.
  3. When the capacity of other storage methods is not sufficient, IndexedDB must be used as a last resort.


3.IndexedDB features

(1) Non-relational database (NoSql)

Databases such as MySQL are relational databases, and their main feature is that data is stored in the form of a two-dimensional table , while Indexed DB is a non-relational database that mainly stores data in the form of key-value pairs .


(2) Persistent storage

Data stored in cookies, localStorage, sessionStorage, etc. will be cleared when we clear the browser cache, but data stored using IndexedDB will not unless the database is manually deleted.


(3)Asynchronous operation

 IndexedDB does not lock the browser during operation (asynchronously), and users can still perform other operations. This is in sharp
contrast to localstorage, which is synchronous.

 (4)Support affairs

IndexedDB supports transactions, which means that if one step in a series of operation steps fails, the entire transaction will be cancelled, and the database will roll back the state before the transaction occurred, which is similar to transactions in databases such as MySQL.

(5) Same origin strategy

IndexedDB also has same-origin restrictions, and each database corresponds to the domain name where it was created. Web pages can only access databases under their own domain names, but not cross-domain databases.

(6) Large storage capacity

One of the most significant features of IndexedDB is also the best reason not to use storage methods such as localStorage.


4.IndexedDB concept supplement

①Warehouse objectStore

IndexedDB only has the concept of a warehouse store , which can be understood as a table. That is, a store does not have the concept of a table, but is just a table.

②Indexindex

There is also the concept of index in relational database. We can add index to the corresponding table field to speed up the search speed. There are also indexes in IndexedDB. The index can be created at the same time when creating the store. When subsequently querying the store, you can filter by the index. After adding an index to a field, if the subsequent data insertion is successful, the index field It cannot be empty.

③Cursor

Cursor is a new concept of IndexedDB database. You can think of the cursor as a pointer. When you want to query all the data that meets a certain condition, you need to use the cursor. Let the cursor go down line by line. The place where the cursor goes is convenient. Return this row of data, and then you can judge whether this row of data meets the conditions.
⭕Note: IndexedDB queries are not as convenient as databases such as MySQL. It can only query data through primary keys, indexes, and cursors.

④ Affairs

IndexedDB supports transactions, that is, consistency as long as there is a failure when operating on the database. will be rolled back to the original state to ensure that the data 


5.IndexedDB practical operation

All operations on IndexedDB's warehouse are transaction-based.

①Create or connect to the database

//打开数据库
//@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,
            });
        };
    });
}

The operation of creating a database is encapsulated into a function, and the function returns a promise object, so that it can be called in a chain when called. The function mainly receives two parameters: database name and database version. There are three main callback functions inside the function, namely:

  • onsuccess: callback after the database is successfully opened or created. Here we return the database instance.
  • onerror: callback after database opening or creation fails.
  • onupgradeneeded: This function will be executed when the database version changes. For example, if we want to create a new repository (table), we can operate in this function and update the database version.

②Insert data

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 inserts data through transactions. The insertion method is also very simple. Just use the add method provided by IndexedDB. Here, the operation of inserting data is also encapsulated into a function that receives three parameters, as follows:

  • db: When creating or connecting to the database, the db instance returned needs to be saved at that time.
  • storeName: Warehouse name (or table name). The warehouse has been created when creating or connecting to the database.
  • data: the data to be inserted, usually an object

 ⭕Note:  The inserted data is an object and must contain the declared index key-value pair


③Read data through primary key 

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);
        };
    });
}

④ Query data through 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);
        }
    };
}

⑤ Query data through index

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);
    };
}

The index name is the index name created when the warehouse is created, which is the key in the key-value pair. All data that satisfies the index value of the incoming function will eventually be queried.

The index name is the index name created when the warehouse is created, which is the key in the key-value pair. Eventually, only one piece of data with the index value passed into the function will be queried.


⑥ Query data through indexes and cursors

The data queried through the index or cursor alone is part or all of the data. If you want to query all the data in the index that meets certain conditions, it is impossible to use the index or cursor alone. Of course, you can query all the data and filter out the appropriate data in the loop array, but this is not the best way to implement it. The best way is of course to combine indexes and cursors.

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) {};
}

⑦Paging query through index and cursor

IndexedDB paging query is not as simple as MySQL paging query. It does not provide ready-made APIs, such as limit, etc., so you need to implement paging by yourself.

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) {};
}

An API of IndexedDB: advance. This function allows the cursor to skip how many items to start querying. If the paging is 10 pieces of data per page, and now you need to query the second page, then you need to skip the first 10 pieces of data, start querying from the 11th piece of data, until the counter equals 10, then close the cursor and end the query.


⑧Update data

It is relatively simple to update data in IndexedDB. Use the put method directly. It is worth noting that if the data does not exist in the database, the data will be added by default, otherwise it will be updated. If you like to use the put method for updates and new additions, this is also feasible.

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("数据更新失败");
    };
}

 The put method receives a data object


⑨Delete data through primary key

The primary key is the keyPath declared when creating the database, and it is unique.

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("数据删除失败");
    };
}

⑩Delete specified data through index and cursor

Sometimes the primary key value cannot be obtained and can only be deleted through the index value. In this way, you can delete a piece of data (the index value is unique) or all data that meets the conditions (the index value is not unique).

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){ };
}

The above code can delete all data whose index value is indexValue. It is worth noting that IDBKeyRange.only0API is used. This API means that it can only be used when two values ​​​​are equal. For specific API explanation, please refer to the MDN official website.


⑪Close the database

 When the database operation is completed, it is recommended to close it to save resources.

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

⑫Delete database

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

Summarize:

IndexedDB is an API defined in the HTML5 standard for storing large amounts of structured data on the browser side. It has the following characteristics:

  1. Asynchronous API: IndexedDB uses asynchronous API for access and operations, which can better cope with the needs of large amounts of data storage and high concurrent data access.
  2. Large-scale data storage: IndexedDB supports the storage of large amounts of structured data and supports advanced operations such as indexing and transaction processing. It is suitable for scenarios that require high-performance local storage of large-scale data.
  3. Database query: IndexedDB supports complex queries, including range queries and cursor queries, which can help developers conduct precise queries and efficient data retrieval.
  4. Database design: IndexedDB itself is a key-value storage database based on NoSQL. It has a similar design concept to other databases (such as MongoDB) and can help developers carry out flexible database design and data model design.

Compared with other browser-side storage technologies, IndexedDB has better cross-platform compatibility, security and scalability, and can meet various data storage requirements of modern web applications. However, due to its complexity in use, developers need to have an in-depth understanding of browser-side storage technology, JavaScript asynchronous programming, database design and querying to fully utilize its advantages.

Guess you like

Origin blog.csdn.net/m0_61662775/article/details/131029016