当前位置: 首页 > Web前端 > HTML5

存储引擎及如何选择合适的存储API

时间:2023-04-04 23:12:02 HTML5

原文请见此处,略有删节,本文根据知识共享署名4.0国际许可协议共享,BYTroland。本系列持续更新中,Github地址请查看这里。这是JavaScript工作原理的第十六章。概述在设计Web应用程序时,为本地设备选择合适的存储机制非常重要。一个好的存储引擎可以帮助开发者高效地存储数据,降低传输带宽,提高程序响应速度。正确的存储和缓存策略是构建离线移动网络体验的核心组成部分。越来越多的用户认为他们可以离线使用移动网络应用程序是理所当然的。在本章中,我们将讨论各种可用的存储API和服务,并就如何在构建Web应用程序时选择正确的存储引擎提供一些建议。数据模型数据存储模型决定了如何在内部组织和存储数据。这影响到整个Web应用的设计,计算出获得一个高性能的Web应用和解决它遇到的问题的成本。没有更好的技术和一刀切的解决方案,因为所有的问题都是工程相关的问题。那么,让我们看看替代数据模型:结构化:将数据存储在具有预定义字段的表中,非常适合灵活性和动态性,因为它是基于SQL的数据库管理系统数据查询的典型特征。IndexedDB是浏览器端结构化数据库的典型例子。键/值类型:键/值数据存储和关系型NoSQL数据库,允许开发者通过唯一的键索引存储和检索非结构化数据(即非预定数据类型的字段中的数据)。键/值数据存储在某种意义上类似于哈希表存储,它允许在特定时间访问不确定数据类型的索引数据。键/值数据存储的好例子是浏览器端的CacheAPI和服务器端的ApacheCassandra。字节流:这种简单的模型将数据存储为固定长度的、混淆的字符串字节变量,并让应用层控制其内部数据组织。此模型特别适用于文件存储和其他分层组织的blob数据。字节流存储的典型例子包括文件系统和云存储设备。持久化网页程序的数据存储方式可以根据数据的存储时长来分析:会话持久化:数据仅在单个活动网页会话或浏览器标签页关闭时有效,关闭后失效。会话持久数据存储的一个示例是会话存储API。设备持久性:这种类型的数据存储在给定设备上的会话和浏览器选项卡/窗口中。设备持久存储机制的一个示例是CacheAPI。全局持久性:此类数据跨会话和跨设备存储。因此,它是最兼容的数据持久化解决方案。它不会存储在设备上,这意味着数据需要从服务器端存储中获取。因为这里只讨论设备端的数据存储,所以这里只说服务器端的数据存储。客户端数据持久化如今,有相当多的浏览器API可供选择来存储数据。此处将详细讨论这些方法,然后进行比较,以便开发人员轻松选择合适的数据存储解决方案。但是,在选择如何存储数据之前,开发人员需要首先考虑一些事项。当然,首先是想清楚如何使用web程序以及后续的维护和性能优化。即使您有一个周密的计划,也可能只有几个备选方案。以下是开发人员需要考虑的事项:浏览器支持-优先考虑不会轻易更改且兼容的标准化和组织良好的API。这些API还拥有非常丰富的文档和活跃的开发者社区。事务-有时事务对于一组相关数据存储操作的原子成功或失败至关重要。传统数据库使用事务模型实现此功能,其中相关数据更新被划分为任意单元。同步/异步——很少有存储API是同步的,这意味着存储或检索数据请求将阻塞当前活动的线程,直到数据请求完成。使用同步数据存储API会阻塞主线程并冻结程序界面。尽可能使用异步存储API。对比这里,让我们看看目前Web开发者可用的API,并使用上面提到的维度进行比较。FileSystemAPI有了FileSystemAPI,web程序可以在用户本地文件系统的沙箱中创建新文件,读取Fetch、操作和写入文件。该接口包括以下部分:读取和操作文件:File/Blob、FileList、FileReader创建和写入文件:Blob()、FileWriter访问目录和文件系统:DirectoryReader、FileEntry/DirectoryEntry、LocalFileSystem文件系统API不是标准的API,因为兼容性不好,切记不要在生产环境中使用,各个浏览器厂商的实现会有很大差异,以后API可能会发生变化,文档和目录入口API接口filesystem用来表示一个文件系统。这些对象可以从任何文件系统条目的文件系统属性中获得。一些浏览器提供额外的API来创建和操作文件系统。该接口将不允许开发人员访问用户的文件系统。相反,开发人员在浏览器沙箱中获得了一个虚拟磁盘。如果你想访问用户的文件系统,你可以安装一个Chrome扩展。获取文件系统Web应用程序可以调用window.requestFileSystem()来访问沙箱文件系统。://注意:自GoogleChrome12起,文件系统已添加前缀:window.requestFileSystem=window.requestFileSystem||window.webkitRequestFileSystem;window.requestFileSystem(type,size,successCallback,opt_errorCallback)会在第一次调用requestFileSystem()方法时创建一个新的本地存储。需要注意的是文件系统是沙箱类型的,也就是说web程序不能访问其他程序的文件。在获得对文件系统的访问权限后,开发人员可以对文件和目录执行大多数正常的文件系统操作。与其他存储策略相比,FileSystem有很大的不同,它是为满足数据库不能很好解决客户端存储的情况而设计的。通常,程序用于处理大型二进制blob或与浏览器上下文之外的程序共享数据。以下是使用文件系统的一个很好的示例:断点简历工具-选择文件或文件目录以上载时,它将将文件复制到沙箱中,并一次上传一个段。视频游戏、音乐或其他媒体密集型程序提供离线访问或本地缓存以获得更好性能的音频/图片编辑器-数据块通常很大,需要可读和可写的离线视频播放器-这需要下载大文件供以后查看或快速tracking-Bufferingofflinewebmailclients-下载附件并存储在本地以下是当前浏览器对该API的支持:本地存储localStorageAPI允许开发人员访问文档源的Storage对象。存储的数据在多个浏览器会话中仍然有效。localStorage与sessionStorage类似,只是localStorage中存储的数据没有过期时间,而sessionStorage中存储的数据会在页面会话结束时丢失——即页面关闭时丢失。无论是localStorage还是sessionStorage,其数据都只存储在特定的页面源中。所谓页面源包括协议、主机名和端口。以下是当前浏览器对该API的支持:会话存储sessionStorage属性允许开发人员访问当前来源的会话存储对象。如前所述,sessionStorage类似于localStorage。唯一不同的是,localStorage中存储的数据没有过期时间,sessionStorage中的数据会在页面会话结束时丢失。只要浏览器打开以及页面重新加载和恢复,页面会话就会持续。在新选项卡中打开新页面或窗口将导致重新初始化新会话,这与会话cookie的工作方式不同。请注意,数据存储在sessionStorage还是localStorage只在指定的页面源中有效。以下是目前浏览器支持的API:Cookies所谓cookie(网页cookie,浏览器cookie)是指用户的服务器向客户端发送的一小段数据。浏览器存储它并在下一次请求服务器时搭载它。通常它用于判断两个请求是否来自同一个客户端-例如保持用户登录。它记录无状态HTTP协议的状态信息。Cookies有以下三个主要用途:会话管理——登录、购物车、游戏积分或其他需要存储在服务器端的数据。个性化-用户参数、皮肤等设置监控-记录和分析用户行为Cookies曾经是统一的客户端存储解决方案。当它是客户端存储的唯一选择时,这是唯一的选择,现代存储API现在是存储客户端数据的推荐选择。每次发送请求时,都会携带Cookies,因此会影响性能(尤其是在移动端请求数据时)。有两种类型的cookie:会话cookie-在用户关闭浏览器时过期。Web浏览器可以使用恢复会话技术来修复大多数会话cookie,就好像浏览器从未关闭过一样。Persistentcookie-与客户端关闭过期相反,persistentcookie会在指定的过期时间或指定的时间(Max-age)后过期。请注意不要将凭据或敏感信息存储在cookie中,因为它们存在固有的不安全机制。不过步晓表示,cookies是最兼容的解决方案。CacheCache接口是一种用于缓存请求/响应对象的存储机制。请注意,Cache接口在窗口范围和工作程序中都可用。尽管在ServiceWorker规范中定义了Cache,但这并不一定意味着它必须与ServiceWorkers一起使用。一个源可以有多个命名缓存对象。开发者只需要在脚本中实现如何处理更新缓存(例如,在serviceworker线程中)。除非明确请求,否则不会更新缓存中的对象,只能删除缓存的对象,否则不会过期。使用CacheStorage.open()打开命名缓存对象,然后调用任何缓存方法来维护缓存。开发者需要定期清除缓存条目。每个来源在浏览器端都有一定的缓存数据配额。使用StorageEstimate估计缓存配额使用情况。浏览器会尽力管理硬盘空间,但它可能会删除给定来源的缓存数据。浏览器可能会也可能不会删除指定来源的所有数据。请记住使用名称对脚本进行版本控制,并且仅在可安全操作的脚本版本上运行。有关详细信息,请参阅删除旧缓存。CacheStorage接口表示缓存对象存储。接口:为所有可以被ServiceWorker、其他类型的工作线程或窗口范围访问的命名缓存提供一个主目录(虽然它是定义在服务工作线程中的缓存,但并不意味着它只能与workerthreads结合使用)维护角色名称和Cache对象之间的映射使用CacheStorage.open()创建Cache实例。使用CacheStorage.match()检查指定的Request是否是CacheStorage对象中Cache对象的键。使用全局缓存属性访问CacheStorage。IndexedDBIndexedDB是一种客户端持久化数据存储解决方案。因为它允许开发者创建具有丰富查询能力的网络程序而不受网络条件的影响,这些网络程序可以在线或离线运行。IndexedDB适用于大量数据存储(例如,商业图书馆DVD目录)和不需要持续网络连接的Web应用程序(例如,邮件客户端、待办事项列表和笔记)。因为大家对其他的存储API比较熟悉,所以本文就多讲IndexedDB。此外,随着Web应用程序变得越来越复杂,IndexedDB也越来越受欢迎。IndexedDB原理IndexedDB允许开发人员使用键来存储和检索对象。对数据库的所有操作都发生在事务中。与其他网络存储解决方案一样,IndexedDB遵循同源策略。因此无法跨域访问数据,只能访问同域名下存储的数据。此异步API可用于大多数上下文,包括Web服务线程。IndexedDB曾经有一个同步版本,用于web线程,但由于社区不喜欢它而被从规范中删除。IndexedDB也曾经有一个名为WebSQL数据库的竞争规范,但它已被W3C弃用。IndexedDB和WebSQL虽然都是存储解决方案,但是功能并不相同。WebSQL数据库是一个关系数据库访问系统,而IndexedDB只是一个索引表系统。不要将IndexedDB用作其他类型数据库的蓝图。相反,需要仔细阅读文档。以下是开发者需要了解的核心概念:IndexedDB数据库存储键值对——值可以是复杂的结构对象,键可以是这些对象的属性。开发人员可以使用对象的任何属性来创建用于快速搜索的索引,例如枚举排序。键也可以是二进制对象。IndexedDB建立在事务数据模型之上——IndexedDB中的所有操作都发生在事务上下文中。因此,开发人员无法在事务之外执行命令或打开游标。同样,事务只能自动提交,不能手动提交。IndexedDB的大部分是异步的——API不通过返回值返回数据。相反,需要传入一个回调函数来处理返回值。也就是说,开发人员不是将值同步存储到数据库中,也不是直接从数据库中检索值。反之,发起一个request请求就意味着一次数据库操作。当数据处理完成后,会通知开发者,开发者监听的事件类型会通知数据操作是否成功。这与XMLHttpRequest(或许多其他与JavaScript相关的事物)的工作方式非常相似。IndexedDB使用了很多请求——请求是接收前面提到的成功或失败事件的对象。它们包含onsuccess和onerror属性,以及readyState、result、errorCode和其他用于通知请求状态的属性。IndexedDB是面向对象的——IndexedDB不是关系数据库,其表表示行和列的集合。这种巨大的差异会影响开发人员设计和构建Web应用程序。IndexedDB不使用结构化查询语言(SQL)-它在对索引使用查询后创建一个游标,该游标可用于遍历结果集。如果您不熟悉NoSQL系统,可以阅读有关NoSQL的维基百科文章。IndexedDB也采用了同源策略——一个origin是包含域名、应用层协议、URL端口地址的文档,脚本在origin上执行。每个源都有其关联的数据库集。每个数据库在源中都是唯一标识的。IndexedDB限制IndexedDB旨在满足大多数客户端存储情况。但是,它并不是为处理以下情况而设计的:国际化排序——并非所有语言都以相同的方式排列字符串,因此不支持国际化排序。虽然数据库不能按照指定的国际顺序存储数据,但是开发者可以自己读取数据库中的数据,并对数据进行排列。同步-API并非设计用于与服务器同步数据。开发人员必须编写自己的代码来将客户端indexedDB数据库与服务器端数据库同步。全文搜索-此API中没有与LIKE运算符等效的SQL。另外需要注意的是,浏览器在以下几种情况下会清空数据库:用户发起清空操作的请求——很多浏览器允许用户清空指定网站的数据,包括cookies、书签、存储的密码和IndexedDB数据。隐私模式下的浏览器-某些浏览器具有“隐私浏览”(Firefox)和“隐私浏览”(Chrome)模式。数据库在会话结束时被清除。超出磁盘容量或磁盘配额。数据损坏。..尽管现实和浏览器的能力日新月异,但浏览器制造商正在努力尽可能地节省数据。选择合适的存储API正如我之前所说,最好尽可能使用兼容的API,并提供异步调用模型以最大化UI响应速度。这些标准自然而然地导致了如下的技术选择:使用CacheAPI来操作离线存储。API在支持ServiceWorker功能的浏览器中可用,这是创建离线应用程序所必需的。CacheAPI非常适合排列与已知URL关联的资源。使用IndexedDB存储程序状态和用户生成的内容。这允许用户在比只支持CacheAPI的浏览器更多的浏览器中离线使用程序。参考https://developers.google.com...https://developer.mozilla.org...https://developer.mozilla.org...本系列持续更新中,Github地址可以在这里找到。