IndexedDB:浏览器里的本地数据库

更新日期: 2019-09-13阅读: 1.9k标签: 数据库

IndexedDB 是什么

在现代浏览器的本地存储方案中,indexedDB 是一项重要的能力组成, 它是可以在浏览器端使用的本地数据库,可以存储大量数据,提供接口来查询,还可以建立索引,这些都是其他存储方案 Cookie 或者 LocalStorage 无法提供的能力。单从数据库类型来看,IndexedDB 是一个非关系型数据库(不支持通过 SQL 语句操作)。


IndexedDB 的主要概念

IndexedDB 是一个比较复杂的 api 组合,学习它的过程就相当于学习它的各个对象 API 接口,包括以下这些( IDB 指当前操作的数据库实例 ):

数据库:IDBDatabase 对象
仓库对象: IDBObjectStore 对象
索引:IDBIndex 对象
事务:IDBTransaction 对象
操作请求:IDBRequest 对象
指针:IDBCursor 对象
主键:IDBKeyRange 对象

在这些 API 中包含一些主要概念:

数据库:数据库是所有相关数据的基本容器。在同源策略( 协议 + 域名 + 端口 )的前提下,每个域名下可以新建任意多的数据库。IndexedDB 中有版本概念,这就规定了同一时刻下只有一个版本的数据库存在。
对象仓库:对象仓库 ObjectStore 在 IndexedDB 中对应的是 MYSQL 中的表 Table。
数据:对象仓库中记录的是若干条数据,数据只有主键和数据体两个部分,主键不能重复,可以为自增的整数编号或者数据中指定的一个属性。数据体可以是任意数据类型,不限于对象。
索引:为不同的属性建立索引可以加快数据的检索。
事务:数据的 CURD (增删查改) 都要通过事务来完成。

通过简单的对比图来理解 IndexedDB 的概念:



快速起步 IndexedDB

在介绍了 IndexedDB 的主要概念之后,可以通过一个简单实用的 CURD 例子来学习在日常开发中我们是怎么使用 IndexedDB 的,各个 API 细节日后可以慢慢深入学习。

必不可少的浏览器支持检查:

if(!('indexedDB' in window)){
  console.log('当前浏览器支持 IndexedDB');
  return;
} else {
  console.log('您的浏览器不支持 IndexedDB')
  // todo 建议升级或者更换其他浏览器
}

连接数据库

// 数据库实例
let db;
// 数据库打开操作,第一个参数是数据库名称, 第二个参数是数据库版本
let DBRequestLink = window.indexedDB.open('dataBaseName', 1)
DBRequestLink.onsuccess = function(event) {
  // 获取数据库实例
  db = DBRequestLink.result;
  // 其他操作
};
// 这个监听回调触发于数据库首次新建、open数据库时传递新版本(只能比之前传递的版本高)
DBRequestLink.onupgradeneeded = function(event) {};

创建数据库的主键和字段

DBOpenRequest.onupgradeneeded = function(event) {
  let db = event.target.result;

  // 创建一个数据库存储对象,并指定主键
  let objectStore = db.createObjectStore('person', { 
    keyPath: 'id',
    autoIncrement: true
  });

  /* 定义存储对象的数据项 
   * 第一个参数是创建的索引名称,可以为空
   * 第二个参数是索引使用的关键名称,可以为空
   * 第三个参数是可选配置参数,可以不传,常用参数之一就是 unique ,表示该字段是否唯一,不能重复
   */ 
  objectStore.createIndex('id', 'id', {
    unique: true    
  });
  objectStore.createIndex('name', 'name');
  objectStore.createIndex('age', 'age');
  objectStore.createIndex('sex', 'sex');
};

在上述操作中,我们先定义了上文中提到的 IDBObjectStore 对象,并指定主键为 id ,随后又通过 createIndex 来创建字段。值得注意的是虽然创建了四个字段,但在 IndexedDb 中数据还是分为主键 id 和数据主体两个部分,并不会像 MYSQL 中在 Table 中呈现四列。

向数据库中添加数据

// 这里的 db 就是第二步中的 db 对象, 
// transaction api 的第一个参数是数据库名称,第二个参数是操作类型
let newItem = {
  id: 1,
  name: '徐嘻嘻',
  age: 3,
  sex: 'female'
};
let transaction = db.transaction('dataBaseName', "readwrite");
// 找到对应的存储对象
let objectStore = transaction.objectStore('person');
// 添加到数据对象中, 传入javascript对象
objectStore.add(newItem);

新建操作是在新建了一个 事务( IDBTransaction 对象)的前提下完成的,传入的数据不需要做任何转换,可以无缝传入 Javascript 对象。

修改数据库中的数据

// 这里的 db 就是第二步中的 db 对象, 
// 新建事务
let transaction = db.transaction('dataBaseName', "readwrite");
// 新数据主体
let newRecord = {
  id: 1,
  name: '徐嘎嘎',
  age: 5,
  sex: 'male'
};
// 打开已经存储的数据对象
let objectStore = transaction.objectStore('person');
// 获取存储的对应键的存储对象, 传入主键 id,值为 1  
let objectStoreRequest = objectStore.get(1);
// 获取成功后替换当前数据
objectStoreRequest.onsuccess = function(event) {
  // 数据
  var record = objectStoreRequest.result;
  // 遍历替换
  for (let key in newRecord) {
    if (typeof record[key] != 'undefined' || key !== 'id') {
      record[key] = newRecord[key];
    }
  }
  // 更新数据库存储数据             
  objectStore.put(record);
};

基本思路是创建一个事务,先找到想要修改的数据主体,然后在更新该数据主体内容。 事务创建逻辑相同,并在创建之后调用事务的 get 和 put 操作。

删除数据库中的数据

// 这里的 db 就是第二步中的 db 对象, 
// 新建事务
let transaction = db.transaction('dataBaseName', "readwrite");
// 打开已经存储的数据对象
let objectStore = transaction.objectStore('person');
// 获取存储的对应键的存储对象, 传入主键 id,值为 1  
let objectStoreRequest = objectStore.delete(1);

调用 delete 接口,传入指定的 id 即可。


可以提效的类库

​ 从上面的例子中可以看出,每一次操作需要至少三行代码才能完成,而且需要一直维护 DB 的对象引用,避免它被回收,这样子开发代码膨胀得太厉害,所以我们在业务中引入其他类库来减少代码量

LocalForage
可以指定数据存储方案,默认依次为 IndexedDB、WebSQL、LocalStorage,意味着当前 IndexedDB 失效可以有兜底措施。
API 简化为 CRUD ( getItem、removeItem、setItem、clear )
库大小为 475b
Pouchdb
API 简化为 put、get、remove,基于 promise 来检查回收错误
有较好的错误日志机制, 如失败,冲突等等,方便调试
库大小为 255b

这两个类库比较符合我们的开发要求,我们当前使用的是 LocalForage。


结束语

在业务开发中,我们都会碰到或多或少的本地存储需求,本文介绍了其中一种存储方案 IndexedDB 的简单实践。就我们的应用场景来看,IndexedDB 的适用面还是很广的。考虑到 IE10 也可以支持,把它实践在实际项目中应该是没有问题的。


链接: https://www.fly63.com/article/detial/5900

数据库的选择:数据库种类那么多,该如何选择?

技术真的是日新月异,Web 网站已经脱离之前的静态网站的体系,转而使用动态语言搭建的动态网站。这也衍生出一个问题:该如何存储数据了?数据库就应运而生,它的作用是提供存储数据的容器。方便 web 网站进行存储、查询、更新等。

数据库的常用sql操作

数据库操作,不管是服务端、前端、移动端,都或多或少的会涉及到数据的存储、查询、修改。所以作为一名开发者,数据库操作也是开发必备的一项技能。本文是对数据库中经常用到的一些写法与及函数的归纳总结

B树和哈希索引的比较

了解B树和哈希数据结构有助于预测查询在这些使用不同索引数据结构的存储引擎上的执行情况,特别是对于MEMORY存储引擎,它是允许您选择B树或哈希作为索引的存储引擎。

使用 TypeScript 访问 MySQL 数据库

TypeScript 已经成为一个强大的 Web 应用程序开发环境,在与标准 JavaScript 保持一致的同时,提供了显著的改进。在本文中,我们将深入探讨使用 TypeScript 相关的细节

MyISAM和InnoDB的比较

MyISAM:不支持事务,而且也不支持外键,但是每次查询都是原子的,支持表级锁,即每次操作是对整个表加锁;InnoDb:支持ACID的事务,支持事务的四种隔离级别;

MongoDB的特性、使用原理

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 具有高性能、易部署、易使用,存储数据非常方便等特点

传统数据库不适合现代企业架构了?

它还是我们如今看到的更广泛的技术趋势背后的统一思想,这些技术包括机器学习、物联网、无处不在的 SaaS 以及云计算。这些趋势都在用不同的方法使软件变得更丰富和功能强大,并在企业间扩大其影响范围

数据库自增ID用完了会怎样?

对DBA来说这应该是送分题吧。而我是突如其来的想法想测试下的。正常来说程序员是不会关心自增ID用完的情况的。以 Mysql 为例,它支持的最大的整型是unsigned bigint

浏览器数据库 indexedDB

indexedDB用于在浏览器端存储大量的结构化数据。对比于其他的浏览器存储技术(cookie,localStorage),indexedDB具有以下优点:另外,indexedDB还具备以下特点:

node如何连接数据库?

node连接数据库的方法:使用命令npm install mysql --save安装mysql的软件包,在项目文档中使用client.connect()即可连接数据库。下载MySQL :MySQL Downloads,并进行安装。安装完,会引导你对数据库进行配置,设置root密码以及创建普通用户以及密码

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!