- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在 IndexedDB 中,有两种方法可以更新数据库中已有的对象。您可以调用 IDBCursor.update
或 IDBObjectStore.put
。
两者都接受更新后的对象作为参数。
IDBCursor.update
要求您先打开游标,但您基本上也必须使用 IDBObjectStore.put
来执行此操作才能检索先前的值。
IDBObjectStore.put
如果找不到要更新的对象,将创建一个新对象,但由于它必须先检查更新,我不知道这是否真的会创建一个性能差异。
那么这些方法有什么区别呢?有什么我想念的吗?我试图制作一个测试用例来调查性能差异:
var db;
function runTest(N, cb) {
console.log("N = " + N);
// Add some fake data to object store
var tx = db.transaction("store", "readwrite");
tx.objectStore("store").clear();
for (var i = 0; i < N; i++) {
tx.objectStore("store").add({"id": i, "index":0,"guid":"21310c91-ff31-4cb9-ae68-16d48cbbd84a","isActive":false,"balance":"$1,840.25","picture":"http://placehold.it/32x32","age":33,"eyeColor":"brown","name":"Witt Fletcher","gender":"male","company":"QUILM","email":"wittfletcher@quilm.com","phone":"+1 (851) 485-2174","address":"729 Conover Street, Marenisco, Virginia, 7219","about":"Incididunt do deserunt ut quis. Exercitation et ut ad aliqua ut do sint Lorem. Aliquip sit aliquip nulla excepteur pariatur ut laborum ea dolor. Consectetur incididunt et et esse commodo id eu dolor in. Nostrud sit mollit occaecat ullamco commodo aute anim duis enim et aliqua. Aute duis nostrud do minim labore sunt mollit in voluptate aliquip sit. Aliqua aliquip non ipsum exercitation cillum irure in.\r\n","registered":"2014-07-02T03:42:57 +04:00","latitude":-65.942119,"longitude":-129.471674,"tags":["reprehenderit","nostrud","velit","exercitation","nulla","nulla","est"],"friends":[{"id":0,"name":"Kristine Francis"},{"id":1,"name":"Lizzie Ruiz"},{"id":2,"name":"Bobbie Underwood"}],"greeting":"Hello, Witt Fletcher! You have 7 unread messages.","favoriteFruit":"apple"});
}
tx.oncomplete = function () {
// Update with cursor.update
var tStart = (new Date()).getTime();
tx = db.transaction("store", "readwrite");
var store = tx.objectStore("store");
for (var i = 0; i < N; i++) {
store.openCursor(i).onsuccess = function (event) {
var cursor = event.target.result;
cursor.value.age = 34;
cursor.update(cursor.value);
};
}
tx.oncomplete = function () {
var tEnd = (new Date()).getTime();
console.log("cursor.update - " + (tEnd - tStart) + " milliseconds");
// Update with put
tStart = (new Date()).getTime();
tx = db.transaction("store", "readwrite");
store = tx.objectStore("store");
for (var i = 0; i < N; i++) {
store.openCursor(i).onsuccess = function (event) {
var cursor = event.target.result;
cursor.value.age = 34;
store.put(cursor.value);
};
}
tx.oncomplete = function () {
tEnd = (new Date()).getTime();
console.log("put - " + (tEnd - tStart) + " milliseconds");
if (cb !== undefined) {
cb();
}
};
};
};
}
request = indexedDB.open("yes5ytrye", 1);
request.onerror = function (event) { console.log(event); };
request.onupgradeneeded = function (event) {
var db = event.target.result;
db.onerror = function (event) { console.log(event); };
db.createObjectStore("store", {keyPath: "id"});
};
request.onsuccess = function (event) {
db = request.result;
db.onerror = function (event) { console.log(event); };
runTest(100, function () {
runTest(1000, function () {
runTest(10000, function () {
console.log("Done");
});
});
});
};
可以试试here .
在 Firefox 中,我得到如下输出:
N = 100
cursor.update - 39 milliseconds
put - 40 milliseconds
N = 1000
cursor.update - 229 milliseconds
put - 256 milliseconds
N = 10000
cursor.update - 2194 milliseconds
put - 2096 milliseconds
Done
性能上基本没有区别。当 N
较大时,Chrome 中的结果略有不同:
N = 100
cursor.update - 51 milliseconds
put - 44 milliseconds
N = 1000
cursor.update - 414 milliseconds
put - 447 milliseconds
N = 10000
cursor.update - 13506 milliseconds
put - 22783 milliseconds
Done
但正如我上面所说,我什至不确定这两种方法之间是否应该有区别,因为看起来它们必须做完全相同的事情。
最佳答案
update cursor
和put
的主要区别在于,您需要使用cursor
检索要更新的元素;另一方面,当使用 put
语句时,您只需要知道要更新的元素的 id
并执行 put
在 store
级别定义的函数。然而,这种加速只适用于您将完整对象存储在内存中的情况。
我稍微更新了您的代码并加快了速度:
var db;
function runTest(N, cb) {
console.log("N = " + N);
// Add some fake data to object store
var tx = db.transaction("store", "readwrite");
tx.objectStore("store").clear();
for (var i = 0; i < N; i++) {
tx.objectStore("store").add({"id": i, "index":0,"guid":"21310c91-ff31-4cb9-ae68-16d48cbbd84a","isActive":false,"balance":"$1,840.25","picture":"http://placehold.it/32x32","age":33,"eyeColor":"brown","name":"Witt Fletcher","gender":"male","company":"QUILM","email":"wittfletcher@quilm.com","phone":"+1 (851) 485-2174","address":"729 Conover Street, Marenisco, Virginia, 7219","about":"Incididunt do deserunt ut quis. Exercitation et ut ad aliqua ut do sint Lorem. Aliquip sit aliquip nulla excepteur pariatur ut laborum ea dolor. Consectetur incididunt et et esse commodo id eu dolor in. Nostrud sit mollit occaecat ullamco commodo aute anim duis enim et aliqua. Aute duis nostrud do minim labore sunt mollit in voluptate aliquip sit. Aliqua aliquip non ipsum exercitation cillum irure in.\r\n","registered":"2014-07-02T03:42:57 +04:00","latitude":-65.942119,"longitude":-129.471674,"tags":["reprehenderit","nostrud","velit","exercitation","nulla","nulla","est"],"friends":[{"id":0,"name":"Kristine Francis"},{"id":1,"name":"Lizzie Ruiz"},{"id":2,"name":"Bobbie Underwood"}],"greeting":"Hello, Witt Fletcher! You have 7 unread messages.","favoriteFruit":"apple"});
}
tx.oncomplete = function () {
// Update with cursor.update
var tStart = (new Date()).getTime();
tx = db.transaction("store", "readwrite");
var store = tx.objectStore("store");
for (var i = 0; i < N; i++) {
store.openCursor(i).onsuccess = function (event) {
var cursor = event.target.result;
cursor.value.age = 34;
cursor.update(cursor.value);
};
}
tx.oncomplete = function () {
var tEnd = (new Date()).getTime();
console.log("cursor.update - " + (tEnd - tStart) + " milliseconds");
// Update with put
tStart = (new Date()).getTime();
tx = db.transaction("store", "readwrite");
store = tx.objectStore("store");
for (var i = 0; i < N; i++) {
//you don't need the element just update
store.put({"id": i, "index":0,"guid":"21310c91-ff31-4cb9-ae68-16d48cbbd84a","isActive":false,"balance":"$1,840.25","picture":"http://placehold.it/32x32","age":33,"eyeColor":"brown","name":"Witt Fletcher","gender":"male","company":"QUILM","email":"wittfletcher@quilm.com","phone":"+1 (851) 485-2174","address":"729 Conover Street, Marenisco, Virginia, 7219","about":"Incididunt do deserunt ut quis. Exercitation et ut ad aliqua ut do sint Lorem. Aliquip sit aliquip nulla excepteur pariatur ut laborum ea dolor. Consectetur incididunt et et esse commodo id eu dolor in. Nostrud sit mollit occaecat ullamco commodo aute anim duis enim et aliqua. Aute duis nostrud do minim labore sunt mollit in voluptate aliquip sit. Aliqua aliquip non ipsum exercitation cillum irure in.\r\n","registered":"2014-07-02T03:42:57 +04:00","latitude":-65.942119,"longitude":-129.471674,"tags":["reprehenderit","nostrud","velit","exercitation","nulla","nulla","est"],"friends":[{"id":0,"name":"Kristine Francis"},{"id":1,"name":"Lizzie Ruiz"},{"id":2,"name":"Bobbie Underwood"}],"greeting":"Hello, Witt Fletcher! You have 7 unread messages.","favoriteFruit":"apple"});
}
tx.oncomplete = function () {
tEnd = (new Date()).getTime();
console.log("put - " + (tEnd - tStart) + " milliseconds");
if (cb !== undefined) {
cb();
}
};
};
};
}
request = indexedDB.open("yes5ytrye", 1);
request.onerror = function (event) { console.log(event); };
request.onupgradeneeded = function (event) {
var db = event.target.result;
db.onerror = function (event) { console.log(event); };
db.createObjectStore("store", {keyPath: "id"});
};
request.onsuccess = function (event) {
db = request.result;
db.onerror = function (event) { console.log(event); };
runTest(100, function () {
runTest(1000, function () {
runTest(10000, function () {
console.log("Done");
});
});
});
};
这是我的结果:
N = 100
cursor.update - 46 milliseconds
put - 28 milliseconds
N = 1000
cursor.update - 157 milliseconds
put - 114 milliseconds
N = 10000
cursor.update - 5530 milliseconds
put - 2391 milliseconds
Done
关于javascript - 在 IndexedDB 中,IDBObjectStore.put 和 IDBCursor.update 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27470839/
IDBObjectStore有一个方法 getAll() . 但是,TypeScript 报告没有这样的方法。 lib.d.ts 中的相关部分是: interface IDBObjectStore {
我正在尝试将 javascript 对象(函数构造函数)添加到 IndexedDB 但出现错误 Failed to execute 'add' on 'IDBObjectStore': functio
我正在尝试掌握使用 indexedDB 在客户端存储数据的窍门。 考虑以下代码: function queryURL(message, sender) { chrome.contextMenu
我有一个类,其中某些属性不应存储到 indexedDB 存储中。当我克隆对象并随后删除属性时它可以工作,但是我不太喜欢这个解决方案。我想知道是否有一种解决方案,我们只是将属性设置为私有(private
我一直在阅读 MDN,但我得到了 stuff like : keyPath The key path for the index to use. Note that it is possible to
我支持的基于 chrome 的 APP 给了我们这个错误。我试图找出更多关于错误的信息,但没有成功。有人可以向我解释一下这可能是什么原因吗。 错误如下图 看跌期权发生在这段代码中 var ydbReq
当尝试在 chrome 中存储已编译的 wasm 模块时,这是我收到的错误:无法在“IDBObjectStore”上执行“put”:无法克隆对象。 但根据 MDN 的说法,这应该是可能的。 https
我正在尝试使用indexedDB更新我的简单应用程序中的条目,但是我收到无法在“IDBObjectStore”上执行“put”:事务已完成。 我似乎无法弄清楚为什么它无法完成事务,我尝试了调试器,它停
所以我正在开发一个使用 API 的 PWA。我刚刚设法设置代码以从 API 获取国家并将它们存储在我的 indexedDB 中。但是我不断收到“idb.js:23 Uncaught (in promi
在此代码中,当我查看控制台时,我在 store1.add 遇到问题,它显示 TransactionInactiveError: 无法在“IDBObjectStore”上执行“add”:事务未激活。 任
这似乎是 Safari 唯一的错误。据我所知,它不会出现在 Chrome 中。我有一个非常标准的 IndexedDB 设置。我调用 initDb,保存结果,这为我提供了一种调用数据库的好方法。 var
我正在尝试将一些值添加到对象存储中,得到这个错误作为返回(在第 22 行)。对象存储使用 keyPath 'id' 和 autoincrement: true。 function cacheObjec
我正在使用 Google map API 和 HTML 5 地理定位 API 将我的位置显示为 map 上的标记。显示此标记后,我有一个简单的标记双击功能,可以使用 indexedDB 将新标记保存到
在 IndexedDB 中,有两种方法可以更新数据库中已有的对象。您可以调用 IDBCursor.update 或 IDBObjectStore.put。 两者都接受更新后的对象作为参数。 IDBCu
我有一个 indexeddb,当我第一次在 chrome 中打开我的网站并尝试调用 init.savedb();我收到一条错误消息 未捕获的 DOMException:无法在“IDBObjectSto
我是一名优秀的程序员,十分优秀!