[官文翻译]Futter超快数据库Isar - 技巧 - 字符串 ID

350 阅读1分钟

我正在参加「掘金·启航计划」


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

官方文档:Home | Isar Database

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

本文翻译自:
String ids | Isar Database

译时版本:3.0.2


字符串 ID

这是被问到频度最高的问题之一,所以这里写了一个使用字符串 ID 的指南。

Isar 原生并不支持字符串 ID ,理由是:整型 ID 要高效得多、也快得多。 特别是对于链接,字符串 ID 的开销非常大。

也能理解有的时候需要存储一些使用 UUID 或者其它非整型 ID 的外部数据。 建议在对象中存储字符串 ID 作为属性,然后使用快速的哈希实现来生成生成一个64位整数用作 ID 。

@collection
class User {
  String? id;

  Id get isarId => fastHash(id!);

  String? name;

  int? age;
}

用这种方法,会有两个收获:用于链接的高效的整数 ID 和使用字符串 ID 的能力。

快速哈希函数

理想的哈希函数应该有很高的质量(不会冲突)并且很快。 建议使用下面的实现:

/// 为 Dart 字符串优化后 FNV-1a 64bit 哈希算法
int fastHash(String string) {
  var hash = 0xcbf29ce484222325;

  var i = 0;
  while (i < string.length) {
    final codeUnit = string.codeUnitAt(i++);
    hash ^= codeUnit >> 8;
    hash *= 0x100000001b3;
    hash ^= codeUnit & 0xFF;
    hash *= 0x100000001b3;
  }

  return hash;
}

如果选择了不同的哈希函数,确保返回64位的整数,并且避免使用加密的哈希函数,因为这些函数要慢很多。

避免使用 string.hashCode 因为在不同的平台和不同版本的 Dart 上,它不能确保是稳定的。