[官文翻译]Futter超快数据库Isar - 概念 - 索引(下)

159 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情


Isar:用于 Futter 可跨平台的超快数据库

官方文档:Home | Isar Database

pub:isar | Dart Package (flutter-io.cn)

本文翻译自:Indexes | Isar Database

译时版本:isar: 3.0.2


索引类型

索引有不同的类型。大多数情况,你会想使用 IndexType.value 索引,但是哈希索引更高效。

值索引

该类型是索引的默认类型,而且也是所有非字符串或列表属性可使用的唯一类型。 属性值用来构建索引。列表的话,会使用列表的元素。它也是最有弹性的,但也占用了三种索引类型的空间。

IndexType.value 可以用于原始类型、需要 startsWith Where 子句的字符串、需要从中查找单个元素的列表。

哈希索引

字符串和列表可以哈希化用来减少建立索引的存储空间。 哈希索引的缺点是它们不能用于前缀扫描(startsWith Where 子句)。

IndexType.hash 可用于不需要 startsWith 和 anyEqualTo where 子句的字符串和列表属性。 

哈希元素索引

字符串列表可被完全哈希化(使用 IndexType.hash)或者列表的元素也可被高效哈希化(使用 IndexType.hashElements),通过使用哈希元素创建复合实体索引。

IndexType.hashElements 用于需要 anyEqualTo Where 子句的 List<String> 。

复合索引

复合索引是多个属性上的索引。Isar 允许创建最多由 3 个属性组成的复合索引。 复合索引也是常说的多列索引。

最好还是开始一个示例。 我们创建了一个 person 集合,并且在 age 和 name 属性上定义了一个复合索引:

@Collection()
class Person {
  int? id;

  late String name;

  @Index(composite: [CompositeIndex('name')])
  late int age;

  late String hometown;
}

数据:

idnameagehometown
1Daniel20Berlin
2Anne20Paris
3Carl24San Diego
4Simon24Munich
5David20New York
6Carl24London
7Audrey30Prague
8Anne24Paris

生成索引

agenameid
20Anne2
20Daniel1
20David5
24Anne8
24Carl3
24Carl6
24Simon4
30Audrey7

生成的复合索引包含先按 age 再按 name 排好序的所有 person 。

很明显如果想要创建按多个属性排序的高效查询,复合索引是很给力的。 复合索引也允许在多个属性上的复杂 Where 子句:

final result = await isar.where()
  .ageNameEqualTo(24, 'Carl')
  .hometownProperty()
  .findAll() // -> ['San Diego', 'London']

复合索引的最后一个属性也支持如 startsWith() 或 lessThan() 的条件:

final result = await isar.where()
  .ageEqualToNameStartsWith(20, 'Da')
  .findAll() // -> [Daniel, David]

多实体索引

如果使用了 IndexType.value 对列表进行索引,Isar 会自动创建一个多实体索引,数组中的每个项目都会被索引指向该对象。所有类型的列表都是如此。

多实体索引可运用的应用是,例如索引标签列表或创建一个全文搜索索引。

@Collection()
class Product {
  int? id;

  late String description;

  @Index(type: IndexType.value, caseSensitive: false)
  List<String> get descriptionWords => Isar.splitWords(description);
}

Isar.splitWords() 使用 Unicode Annex #29 规格将字符串分割为单词,所以它几乎可以正确地用于所有语言。

数据:

iddescriptiondescriptionWords
1comfortable blue t-shirt[comfortable, blue, t-shirt]
2comfortable, red pullover!!![comfortable, red, pullover]
3plain red t-shirt[plain, red, t-shirt]
4red necktie (super red)[red, necktie, super, red]

有重复单词的实体在索引中只会出现一次。

生成的索引

descriptionWordsid
comfortable[1, 2]
blue1
necktie4
plain3
pullover2
red[2, 3, 4]
super4
t-shirt[1, 3]

该索引现在可对说明的单个单词使用前缀(或 相等)where 子句。

代替直接排序单词,也可以考虑使用 语音算法 如 Soundex