为什么 indexedDB 使用“版本”?

问题描述 投票:0回答:3

刚刚学习indexedDB,这是我对搭建数据库的理解。您调用

.open(dbName)
来获取数据库实例。如果用户计算机上不存在这个名称的数据库(例如,如果这是他们第一次访问该站点),那么这将触发一个 onUpdateNeeded 事件,因此您应该在该事件中进行初始化工作,例如创建 ObjectStores。

现在,您还可以传入版本 -

.open(dbName, version)
- 如果数据库存在但使用较低版本,则无论如何都会强制执行 onUpdateNeeded 事件。现在,我可以看到它的实用性了……但是为什么要有一个整数参数呢?如果“版本”论点的重点是强制更新,为什么不只使用
forceUpdate
标志呢?为什么要有一个整数版本参数,因此您需要在调试代码时将其递增到更高版本,大概经过多日调试后达到版本 156?

除了强制更新之外,是否在我不知道的某些功能中使用了该版本,如果没有,其背后的基本原理是什么?此外,您是打算在开发过程中不断更改版本,但在应用程序发布后保持不变,还是您应该在应用程序的整个生命周期中不断更改它?

javascript indexeddb
3个回答
25
投票

单调递增的整数允许这种模式:

var open = indexedDB.open('db', 3);
open.onupgradeneeded = function(e) {
  var db = open.result;
  if (e.oldVersion < 1) {
    // create v1 schema
  }
  if (e.oldVersion < 2) {
    // upgrade v1 to v2 schema
  }
  if (e.oldVersion < 3) {
    // upgrade v2 to v3 schema
  }
  // ...
};
open.onsuccess = function() {
  var db = open.result;
  // ...
};

这是一个很常见的模式。显然,可以想象这是手动完成的——开发人员可以在一个特殊的元数据表中跟踪一个版本——而不是将其写入标准。但它很常见,它是内置的,类似于索引和密钥生成器。

有一个有效的论点,这使得 API 对于初学者来说太复杂了,但是如果没有时间机器,它就有点没有意义了。

...

如果您在本地调试并且更改仅限于您的机器,那么删除/重新创建数据库可能比为每个小更改编写模式升级逻辑更容易。


1
投票

我为商业企业开发商业应用程序,当我遇到你的问题时,我笑了。有趣的是 6 多年前就有人问过这个问题。

我碰巧遇到这样一种情况,客户端需要服务器数据库上的新功能,这导致我们也将其添加到客户端的数据库中。这意味着我们不能没有相关的版本号。我们必须为新的应用程序版本指定更高的数据库版本号,让浏览器知道只需将数据库迁移到新版本,并且这次仍然保留旧用户数据迁移和更新以前编写的模式而不是删除和重新初始化一个全新的数据库。


0
投票

因为 indexedDB 数据库不完全由开发者单独控制,所以可能会发生这种情况:

用户打开同一站点的多个选项卡(或窗口)的情况。

由于所有选项卡都使用相同的底层数据库,因此用户打开同一站点的新选项卡时可能会收到应用程序的新版本(刚刚推送到生产环境)并且该版本会更改数据库模式。

发生这种情况时,新选项卡将具有较新版本的数据库......并且在新选项卡中运行的代码(因为这是应用程序的最新版本) 可以与新的数据库模式一起使用。然而,在上一个选项卡中,旧版本的代码适用于不同的数据库模式——如果我们继续运行该代码,它可能会损坏数据库。

幸运的是,indexedDB 的创建者预见到了这个问题,并为我们提供了一些工具来处理此类冲突——其中之一就是版本号。

这就是它存在的原因。

此外,O'Reilly 摘录建议 IndexedDB API 中版本编号方案的另一个原因是

to be able to store multiple versions of data within the same object store within the same database.
但是,正如文章指出的那样,
this is overkill; just reassign your IndexedDB database version.

https://dev.to/ivandotv/handling-indexeddb-upgrade-version-conflict-368a

© www.soinside.com 2019 - 2024. All rights reserved.