持续创作,加速成长!这是我参与「掘金日新计划 · 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可以用于原始类型、需要startsWithWhere 子句的字符串、需要从中查找单个元素的列表。
哈希索引
字符串和列表可以哈希化用来减少建立索引的存储空间。
哈希索引的缺点是它们不能用于前缀扫描(startsWith Where 子句)。
IndexType.hash可用于不需要startsWith和anyEqualTowhere 子句的字符串和列表属性。
哈希元素索引
字符串列表可被完全哈希化(使用 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;
}
数据:
| id | name | age | hometown |
|---|---|---|---|
| 1 | Daniel | 20 | Berlin |
| 2 | Anne | 20 | Paris |
| 3 | Carl | 24 | San Diego |
| 4 | Simon | 24 | Munich |
| 5 | David | 20 | New York |
| 6 | Carl | 24 | London |
| 7 | Audrey | 30 | Prague |
| 8 | Anne | 24 | Paris |
生成索引
| age | name | id |
|---|---|---|
| 20 | Anne | 2 |
| 20 | Daniel | 1 |
| 20 | David | 5 |
| 24 | Anne | 8 |
| 24 | Carl | 3 |
| 24 | Carl | 6 |
| 24 | Simon | 4 |
| 30 | Audrey | 7 |
生成的复合索引包含先按 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 规格将字符串分割为单词,所以它几乎可以正确地用于所有语言。
数据:
| id | description | descriptionWords |
|---|---|---|
| 1 | comfortable blue t-shirt | [comfortable, blue, t-shirt] |
| 2 | comfortable, red pullover!!! | [comfortable, red, pullover] |
| 3 | plain red t-shirt | [plain, red, t-shirt] |
| 4 | red necktie (super red) | [red, necktie, super, red] |
有重复单词的实体在索引中只会出现一次。
生成的索引
| descriptionWords | id |
|---|---|
| comfortable | [1, 2] |
| blue | 1 |
| necktie | 4 |
| plain | 3 |
| pullover | 2 |
| red | [2, 3, 4] |
| super | 4 |
| t-shirt | [1, 3] |
该索引现在可对说明的单个单词使用前缀(或 相等)where 子句。