教程持续更新中……
**参考*
[1] 《IndexedDB》 - https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
概述
IndexedDB 是一种 web 浏览器中持久存储数据的方法,是一种“NoSQL”数据库。IndexedDB 提供了高性能的接口,适用于大量数据的本地读写和持久存储,对于开发可离线 Web 应用意义非凡。
Web 本地存储有很多方法可选,早期可选的方法可能只有 cookie。但 cookie 的初衷并非单纯用来做本地存储的,而是用来记录一些用户身份信息,便于网站标识访问者身份。因此 cookie 的可用大小有限,并且会被 HTTP 请求携带,造成了不必要的网络性能开销,尤其是在较差的网络环境中,这些开销将导致极差的体验。
在新的 HTML 标准中提供了 Web Storage API,包括 sessionStorage 和 localStorage 两种机制。新的 API 配合 Ajax 在很多场景中完全可以替代 cookie,并且存储容量限制大大提高。两个接口不同的生命周期机制也提供了一定的方便。
虽然不同于 cookie 的字符串存储的方式,Web Storage API 提供了键值对的存储方式。但对于复杂数据来说,依然只能通过格式化后的字符串去存储数据,这就决定了 Web Storage API 在进行复杂数据的修改和查询时很不方便。更关键的是,Web Storage API 是同步接口,会同步阻断浏览器 JavaScript 进程。当数据量比较大,或操作比较复杂时,这两个缺陷将会带来致命的性能问题。
随着移动互联网发展和技术进步,用户和开发者对 Web 应用的期望越来越高,Web 应用需要承担越来越多的任务。体现在可离线应用和数据持久化方面,对于本地化数据存储的要求也越来越高。浏览器本地数据库被设计和实现出来,关系型数据库 WebSql 出现了,大量的数据存储和对 SQL 语句的支持,大大提高了浏览器本地数据存储能力。
2010 年 W3C 组织废弃了 WebSql,key-value 数据库 IndexedDB 成为其替代品。
例子
为了方便介绍和观察 IndexedDB 的结构和特点,我们先创建一个 IndexedDB 的简单实例。
复制以下代码到 Chrome 中并执行。该代码将创建一个 IndexedDB
数据库,并建立一个
ObjectStore
(对象仓库),同时存储了一条数据到数据库中。
可以不必在意代码的实现细节,后续会详细介绍。
1 |
|
代码执行成功后,打开 Chrome 的开发者工具,在 Application 面板中找到 IndexedDB 选项,打开就能查看一个最简单的 IndexedDB 的样例了。
有了这个例子,我们可以分析一些 IndexedDB 的显著特点。
特性
面向对象数据库
IndexedDB 是不需要 SQL 语句来操控的,是面向对象数据库。
从例子中可以看出,IndexedDB 数据库并不具备类似关系数据库的表结构和固定的字段。在同一个源下,可以存在多个不同名的数据库,每个数据库下包含若干个对象仓库(Object Store),对象仓库是 Key-Value 结构的。你可以将数据(甚至是 JavaScript 对象)存储到对象仓库中,需要时通过键或索引快速的读出数据。
这种面向对象的设计,允许直接对 JavaScript 对象进行存取,使得数据库的灵活性大大提高,读取存储数据的格式转化成本也大大下降。也规避了关系型数据库中需求变更时,需要对表结构进行修改甚至重新设计的风险。
key-value 数据库
与传统的关系型数据库不同,IndexedDB 是 kye-value 数据库。value 可以是非常复杂的对象,key 可以是对象自身的属性。可以对对象的某个属性创建索引来实现快速查询和列举排序。并且,key 的数据类型几乎没有限制,甚至可以是二进制对象。
事务模式数据库
对于 IndexedDB 数据的操作都必须在一个事务中完成,因此 IndexedDB 基本(对于持久性,IndexedDB 在实现中是有一个默认的 BUG 的,参见)保证了原子性、一致性、隔离性和持久性,减少了数据混乱的机会。
异步
IndexedDB API 基本上是异步的。当对 IndexedDB 数据库进行读写等操作时,会向数据库发送一个操作请求,当操作完成时数据库会通过事件通知我们。这类似 Ajax 请求,这样的好处在于程序不会阻塞在数据库操作过程,对于大量复杂数据的操作,这一点是很重要的。
IndexedDB 标准中提供了同步接口,但这些同步接口只能用于 Web Workers。
同源策略
IndexedDB 同样遵循同源策略,即对于不同的应用层协议、域名、端口产生不同的“源”。在不同的“源”之间,数据是不会相互干扰和作用的,在同一个“源”内所有的数据库都有唯一的名称。
容易理解,同源策略是为了数据安全考虑。
局限性
IndexedDB 是有一些局限性的,下面的内容只是指导性的,一些特性和原因后面的教程中会进行解释。
!以下情况不适合使用IndexedDB
- 全球多种语言混合存储。国际化支持不好。需要自己处理。
- 和服务器端数据库同步。你得自己写同步代码。
- 全文搜索。IndexedDB 接口没有类似 SQL 语句中 LIKE 的功能。
!注意,在以下情况下,数据库可能被清除:
- 用户请求清除数据。
- 浏览器处于隐私模式。最后退出浏览器的时候,数据会被清除。
- 硬盘等存储设备的容量到限。
- 数据损坏。
- 进行与特性不兼容的操作。