浏览器百科:网页存储篇-IndexedDB介绍(十)
1.引言
在现代网页开发中,数据存储需求日益增多和复杂,传统的客户端存储技术如localStorage和sessionStorage已难以满足大型数据的存储和管理需求。为了解决这一问题,HTML5 引入了 IndexedDB,在本篇《浏览器百科:网页存储篇-IndexedDB介绍(十)》中,我们将详细介绍 IndexedDB 的基本概念、使用方法及其在实际开发中的应用场景,帮助您全面掌握这一强大的数据存储技术,为您的网页应用提供更可靠和高效的数据管理解决方案。
2.什么是IndexedDB
IndexedDB 是一种基于键值对存储的大型数据库,允许开发者在用户的浏览器中存储和检索大量数据。与其他存储方式(如 LocalStorage 和 SessionStorage)不同,IndexedDB 设计用于存储结构化数据,并支持事务、索引、查询等高级功能,类似于传统的关系型数据库。
3.IndexedDB的特点
- 大量数据存储:IndexedDB 可以存储大量数据,远超过 LocalStorage 的 5MB 限制,并允许在没有网络连接时进行读写操作,因此IndexedDB 是离线应用程序的理想选择。
- 异步 API:IndexedDB 使用异步 API,有助于避免阻塞主线程,提高应用程序的性能和响应速度。
- 事务支持:IndexedDB 支持事务处理,保证了数据操作的原子性和一致性,避免数据不一致的情况。
- 复杂查询能力:IndexedDB 支持使用索引和游标进行复杂查询,能够高效地检索和操作数据。
- 结构化存储:IndexedDB 允许存储结构化数据,包括对象和文件,使数据管理更加灵活和方便。
4. IndexedDB中的基本概念
4.1 数据库和对象存储
IndexedDB 中的数据存储在数据库中,每个数据库可以包含多个对象存储。对象存储类似于关系数据库中的表,用于存储特定类型的数据记录。每个对象存储中的数据记录都具有唯一的键(key),通过键可以快速查找对应的数据。
在IndexedDB中,可以通过以下步骤来创建或打开一个数据库:
const openDB = () => {return new Promise<void>((resolve, reject) => {// 打开名为 'MyDatabase' 且版本号为 1 的数据库const request = indexedDB.open('MyDatabase', 1)// 当数据库版本升级或首次创建数据库时触发request.onupgradeneeded = (event: IDBVersionChangeEvent) => {db = (event.target as IDBOpenDBRequest).result}// 当数据库成功打开时触发request.onsuccess = (event: Event) => {db = (event.target as IDBOpenDBRequest).resultresolve()}// 当数据库打开失败时触发request.onerror = (event: Event) => {console.error('Database error:', (event.target as IDBOpenDBRequest).error)reject((event.target as IDBOpenDBRequest).error)}}
}
4.2 键值对存储模型
键(key)是 IndexedDB 中用于标识数据记录的唯一标识符。键可以是一个数值、字符串、日期或者二进制数据。对应值(Value)是一个字符串,指向对象中的某个属性,用于自动生成键。
- 在IndexedDB中,可以通过以下步骤来向对象存储空间添加数据:
const addItem = async () => {if (id.value !== null && name.value) {// 创建一个读写事务const transaction = db.transaction('MyObjectStore', 'readwrite')// 获取对象存储const objectStore = transaction.objectStore('MyObjectStore')// 定义要添加的对象const item = { id: id.value, name: name.value }// 将对象添加到对象存储中const request = objectStore.add(item)request.onsuccess = () => {alert('Item added successfully')// 添加成功后获取所有对象并更新显示getAllItems()}request.onerror = (event: Event) => {console.error('Add item error:', (event.target as IDBRequest).error)}}
}
- 要删除对象存储空间,可以使用delete()方法:
const deleteItem = (id: number) => {const transaction = db.transaction('MyObjectStore', 'readwrite')const objectStore = transaction.objectStore('MyObjectStore')const request = objectStore.delete(id)request.onsuccess = () => {alert('Item deleted successfully')getAllItems()}request.onerror = (event: Event) => {console.error('Delete item error:', (event.target as IDBRequest).error)}
}
- 要更新对象,可以使用put方法:
const updateItem = (id: number, newName: string) => {const transaction = db.transaction('MyObjectStore', 'readwrite')const objectStore = transaction.objectStore('MyObjectStore')const request = objectStore.get(id)request.onsuccess = (event: Event) => {const item = (event.target as IDBRequest).resultif (item) {item.name = newNameconst updateRequest = objectStore.put(item)updateRequest.onsuccess = () => {alert('Item updated successfully')getAllItems()}updateRequest.onerror = (event: Event) => {console.error('Update item error:', (event.target as IDBRequest).error)}} else {alert('Item not found')}}request.onerror = (event: Event) => {console.error('Get item for update error:', (event.target as IDBRequest).error)}
}
4.3 事务和作用域
事务是 IndexedDB 中的数据操作单位,用于确保数据操作的原子性和一致性。事务具有作用域,指定了哪些对象存储可以在事务中访问。事务可以是只读的或读写的。在事务完成之前,所有的数据操作都在一个隔离的环境中进行,确保数据的一致性。
4.4 索引和游标
索引是 IndexedDB 提供的快速查找机制,用于加速数据查询。索引基于对象存储中的一个或多个属性构建,可以显著提高查询效率。游标则是一种遍历数据记录的机制,允许开发者逐条访问数据记录,适用于需要处理大量数据的场景。
在 IndexedDB 中查询对象可以使用多种方法,具体取决于查询的需求和复杂性。
- get方法用于根据键查询单个对象:
const getItem = (id: number) => {const transaction = db.transaction('MyObjectStore', 'readonly')const objectStore = transaction.objectStore('MyObjectStore')const request = objectStore.get(id)request.onsuccess = (event: Event) => {const item = (event.target as IDBRequest).resultif (item) {console.log('Item found:', item)// 这里可以添加处理找到的对象的逻辑,例如更新状态或显示在UI中} else {console.log('Item not found')}}request.onerror = (event: Event) => {console.error('Get item error:', (event.target as IDBRequest).error)}
}
- getAll方法用于获取对象存储中的所有对象:
const getAllItems = () => {const transaction = db.transaction('MyObjectStore', 'readonly')const objectStore = transaction.objectStore('MyObjectStore')const request = objectStore.getAll()request.onsuccess = (event: Event) => {items.value = (event.target as IDBRequest).result}request.onerror = (event: Event) => {console.error('Get all items error:', (event.target as IDBRequest).error)}
}
5. 总结
通过对 IndexedDB 的详细介绍,我们了解了其作为现代网页存储解决方案的强大特性和应用方法。IndexedDB 提供了大规模数据存储、异步API、事务支持、复杂查询能力和结构化存储等多种优势,能够满足现代Web应用程序复杂的数据管理需求。在本篇文章中,我们涵盖了 IndexedDB 的基本概念、特点以及实际应用中的一些代码示例,包括如何创建和打开数据库、添加、删除、更新和查询数据等操作。希望这些内容能帮助您更好地理解和应用 IndexedDB。
为了更好地管理和调试 IndexedDB,Chrome 浏览器提供了一个强大的开发者工具,其中包含了IndexedDB窗格。在下一篇《浏览器百科:网页存储篇-如何在Chrome中打开IndexedDB窗格(十一)》中,我们将详细介绍如何在 Chrome 中打开并使用 IndexedDB 窗格,以便开发者能更直观地查看和操作存储的数据,进一步提升开发效率和应用性能。敬请期待!
相关文章:

浏览器百科:网页存储篇-IndexedDB介绍(十)
1.引言 在现代网页开发中,数据存储需求日益增多和复杂,传统的客户端存储技术如localStorage和sessionStorage已难以满足大型数据的存储和管理需求。为了解决这一问题,HTML5 引入了 IndexedDB,在本篇《浏览器百科:网页…...

Java语言程序设计基础篇_编程练习题*18.22 (将十进制數转换为十六进制数)
题目:*18.22 (将十进制數转换为十六进制数) 编写一个递归方法,将一个十进制数转换为一个十六进制数的字符串。方法头如下: public static String dec2Hex(int value)编写一个测试程序,提示用户输入一个十进制数,然后显示等价的十…...

蓝桥杯3. 压缩字符串
题目描述 实现一个算法来压缩一个字符串。压缩的要求如下: 需要判断压缩能不能节省空间,仅在压缩后字符串比原字符串长度更短时进行压缩。 压缩的格式是将连续相同字符替换为字符 数字形式,例如 "AAABCCDDDD" 变为 "A3BC2D…...

Java设计模式之责任链模式详细讲解和案例示范
在本文中,我们将详细讲解Java设计模式中的责任链模式,探讨其基本概念、使用场景、常见问题和解决方式。同时,我们还会介绍责任链模式与策略模式的区别,并结合电商交易系统的示例进行说明。此外,我们还会探讨责任链模式…...

ubuntu_如何解决apt install时报错:Waiting for cache lock: Could not get lock
当你在 Ubuntu 上运行 apt 时,遇到类似 Waiting for cache lock: Could not get lock 错误,通常是因为另一个进程正在使用 apt 或者类似的包管理器工具。你可以按照以下步骤来查找并解决这个问题: 1. 查询哪个进程正在使用锁 系统中的锁文件…...

软件测试(D5)
步骤: 设计测试-->发现缺陷-->测试报告 Day1 target 1.复述软件测试的定义 2.7种软件测试分类的区别 3.质量模型的重点5项 4.测试流程的6个步骤 5.测试模板的8个要素 认识软件及测试 软件: 控制硬件的工具 应用软件系统软件࿰…...

CSS 圆角渐变边框
<div class"contact-box"><div class"contact-item">联系我们</div> </div>.contact-item{width: 194px;height: 48px;border-radius: 20px 20px 20px 20px;background-color: #000000;color: #BDBDBD;font-weight: 500;font-size…...

骑砍2霸主MOD开发(26)-使用TrfExporterBlender制作TRF文件
一.Blender导入TRF文件 import bpytrf_meshes = []trf_contents = []trf_import_path = D:\pt_ladder.trftrf_export_path = D:\pt_ladder_morph_keys.trfclass TrfMesh:def __init__(self):self.mesh_name = self.mesh_materials = []self.vertex_cnt = 0self.vertex_fvf_cnt…...

Leetcode 最大子数组和
使用“Kadane’s Algorithm”来解决。 Kadane’s Algorithm 在每个步骤中都保持着一个局部最优解,即以当前元素为结尾的最大子数组和(也就是局部最优解),并通过比较这些局部最优解和当前的全局最优解来找到最终的全局最优解。 Kadane’s Algorithm的核…...

目标检测-YOLOv2
YOLOv2介绍 YOLOv2(You Only Look Once version 2)是一种用于目标检测的深度学习模型,由Joseph Redmon等人于2016年提出,并详细论述在其论文《YOLO9000: Better, Faster, Stronger》中。YOLOv2在保持高速检测的同时,显…...

大数据 - OLAP与OLTP的区别
前言 联机事务处理OLTP(on-line transaction processing)和 联机分析处理OLAP(On-Line Analytical Processing)。 OLTP,主要是面向传统的“增删改查”事务系统,数据大都是以实体对象模型来存储数据&#…...

win10+eclipse+ESP8266_RTOS_SDK开发环境构建
官网教程 https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/eclipse-setup.html 1. 导入工程 Build and Flash with Eclipse IDE — ESP8266 RTOS SDK Programming Guide documentation (espressif.com) 导入整个SDK,便于查看所有代…...

树形弹窗选择框/vue2/Element/弹框选择
前言 此类选择器根据vueelementUI实现,使用vue3的可以根据此案例稍作改动即可实现,主要功能有弹出选择、搜索过滤、搜索结果高亮等,此选择器只支持单选,如需多选可在此基础进行改造。 效果图 代码实现 使用时,props-…...

Python精选200Tips:121-125
Spend your time on self-improvement 121 Requests - 简化的 HTTP 请求处理发送 GET 请求发送 POST 请求发送 PUT 请求发送 DELETE 请求会话管理处理超时文件上传122 Beautiful Soup - 网页解析和抓取解析 HTML 和 XML 文档查找单个标签查找多个标签使用 CSS 选择器查找标签提…...

对接后端download接口报未知异常错误
你一定遇到过这种情况,在一个项目中下载功能明明好好的,下载接口调用方法与前端调用方法封装的好好的,可是换了一个接口,竟然搞罢工了,类似下面这样的,你会不会无从下手,不知道该怎么办呢&#…...

vue3 指定元素全屏 screenfull(可直接粘贴使用)
业务需求 由于输入的文字较多,需要将输入框进行全屏展示,方便输入和查看! 效果图 实现方式 下载插件"screenfull": “^6.0.2” yarn add screenfull -S项目中使用 import screenfull from "screenfull"templte中代码…...

【规范】Git Commit 约定式提交规范
文章目录 前言介绍使用约定式提交规范的好处提交信息格式信息头部(Header)正文(Body)脚注(Footer)撤销(Revert) 提交类型表格官网 前言介绍 约定式提交规范它是一种基于提交信息的轻…...

GDB的基本使用方法(之一)
1.编译程序 如果要让GDB调试程序,则编译生成程序时,要添加-g编译选项: $gcc -Wall -O2 -g 源文件 编译器含有针对源代码中的各种各样的错误输出信息的功能,称为警告选项。这些信息并不一定是错误,但却指出了容易引发bug的编码方式。-Werror选项可以在警告发生时,将其当…...

DoubletFinder去除双细胞分析学习
在单细胞RNA测序过程中,有时两个或多个细胞可能在制备过程中意外结合成一个单一的"假细胞",称为双峰细胞或双倍体。这些双峰细胞可能会扭曲数据分析和解释,因此,需要使用一些方法对它们进行识别和剔除。其中DoubletFind…...

软考高级第四版备考---第四十八天(项目基本要素-项目项目、项目集、项目组合和运营管理之间的关系)
一、概述: 项目集是一组相互关联且被协调管理的项目、子项目集和项目集活动,目的是为了获得分别管理无法获得的利益。项目集不是大项目,大项目是指规模、影响等特别大的项目; 项目组合是指为实现战略目标而组合在一起管理的项目、…...

系统架构设计师:信息系统基础知识
简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师:信息系统基础知识前言信息系统构成:信息系统功能:信息系统生命周期…...

微服务-nacos
nacos-注册中心 启动 服务注册到nacos...

快速上手 | 数据可观测性平台 Datavines 自定义SQL规则使用指南
摘要 本文主要介绍在 Datavines平台已有规则不能满足需求的情况下,如何通过自定义SQL规则来实现基于业务特性的数据质量检查。 规则介绍 自定义聚合SQL规则是 Datavines 平台中内置的一个灵活的规则,该规则允许用户通过编写SQL的方式来实现想要的数据质…...

MySQL零基础入门教程-6 查询去重、内外连接查询、子查询、分页查询DQL,基础+实战
教程来源:B站视频BV1Vy4y1z7EX 001-数据库概述_哔哩哔哩_bilibili 我听课收集整理的课程的完整笔记,供大家学习交流下载:夸克网盘分享 本文内容为完整笔记的第六篇 分组查询&DQL总结P41-P66 1、把查询结果去除重复记录 注意…...

Elastic:如何将数据转化为可操作的见解?
作者:来自 Elastic Elastic Platform Team 一切,从某种程度上说,每个人,都是数据。在我们这个数据驱动的世界里,我们的兴趣和互动被统计和分类,为组织提供如何创造更好的产品和更好的体验的见解。更不用说&…...

基于SSM和VUE的药品管理系统(含源码+sql+视频导入教程+文档)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM和VUE的药品管理系统2拥有两种角色 管理员:药品管理、出库管理、入库管理、销售员管理、报损管理等 销售员:登录注册、入库、出库、销售、报损等 1.1 背景…...

机器学习--神经网络
神经网络 计算 神经网络非常简单,举个例子就理解了(最后一层的那个写错了,应该是 a 1 ( 3 ) a^{(3)}_1 a1(3)): n o t a t i o n notation notation: a j ( i ) a^{(i)}_j aj(i) 表示第 i i i 层的…...

post请求中有[]报400异常
序言 在和前端同学联调的时候,发现只要post请求参数里面有[],就会报400的错误 可以看到日志中: The valid characters are defined in RFC 7230 and RFC 3986 解决办法: 参考了博客: spring boot 中解决post请求中有…...

ad22 如何在pcb 的keepout layout 上画线 然后裁出想要的黑色画布大小
选择下面的keepout layout,然后右键打开,然后按照这个图进行选择 然后看这个界面我收藏的第三个,就可以了...

SparkSQL SET和RESET
前言 我们在用代码写spark程序的时候,如果要设置一些配置参数,可以通过: SparkConf val conf = new SparkConf().setMaster("local[2]").setAppName("CountingSheep") val sc = new SparkContext(conf)spark-submit ./bin/spark-submit --name "M…...