IndexedDB - 布尔索引

g00*_*0fy 12 indexing boolean google-chrome indexeddb

是否可以在布尔类型字段上创建索引?

让我们说我想要存储的记录的架构是:

{
  id:1,
  name:"Kris",
  _dirty:true
}
Run Code Online (Sandbox Code Playgroud)

我创建了正常的非唯一索引(onupgradeneeded):

...
store.createIndex("dirty","_dirty",{ unique: false })
...
Run Code Online (Sandbox Code Playgroud)

索引已创建,但它是空的!- 在索引IndexedDB浏览器中,没有带布尔值的记录- 只有字符串,数字日期甚至数组.

我正在使用Chrome 25金丝雀

我想找到_dirty属性设置为true的所有记录 - 我是否必须将_dirty修改为string或int?

Kya*_*Tun 9

是的,布尔值不是有效密钥.

如果必须,当然可以解决为1和0.

但这是有充分理由的.索引布尔值不提供信息.在上面的例子中,您可以动态地进行表扫描和过滤,而不是索引查询.

  • 这种推理需要假设50%的对象为真,50%为假.在现实世界中,您可能有100,000个具有错误值且只有少数具有值true.在那种情况下,索引布尔值确实有意义. (11认同)
  • 正确答案,但我不同意其推理。在处理大量记录时,对布尔值建立索引会提供丰富的信息。即时过滤完全是一种处理浪费。并且存储值为 0 的键而不是根本不存储该键是浪费空间。 (3认同)

Jos*_*osh 8

标记为选中的答案并不完全正确。

您不能在包含 Boolean JavaScript 类型值的属性上创建索引。另一个答案的那部分是正确的。如果您有类似 的对象var obj = {isActive: true};,尝试在其上创建索引obj.isActive将不起作用,浏览器将报告错误消息。

但是,您可以轻松模拟所需的结果。indexedDB 不会将对象中不存在的属性插入到索引中。因此,您可以定义一个属性来表示真,而不是定义一个属性来表示假。当属性存在时,对象会出现在索引中。当该属性不存在时,该对象将不会出现在索引中。

例子

例如,假设您有一个“obj”对象的对象存储。假设您想在isActive这些对象的属性上创建一个类似布尔值的索引。

首先在 isActive 属性上创建索引。在 onupgradeneeded 回调函数中,使用store.createIndex('isActive','isActive');

要表示对象的“真”,只需使用obj.isActive = 1;. 然后将对象添加或放入对象存储。当您想查询所有isActive设置的对象时,您只需使用db.transaction('store').index('isActive').openCursor();.

要表示 false,只需使用delete obj.isActive;然后将对象添加或放入对象存储中即可。

当您查询所有isActive设置的对象时,这些缺少该isActive属性的对象(因为它已被删除或从未设置)在使用游标进行迭代时不会出现。

瞧,一个布尔索引。

性能说明

像在此处使用的示例中所做的那样在索引上打开游标将提供良好的性能。对于小数据,性能差异并不明显,但在存储大量对象时,性能差异非常明显。不需要采用一些第三方库来完成“布尔索引”。这是一个平凡而简单的功能,您可以自己完成。您应该尽量使用本机功能。