0

我在 android 设备上有一个 FTS 3 表。表中的一列包含文本格式的 32 位数字数组。我使用 FTS 是因为 FTS 在查找非唯一值方面相对来说非常快,因为它的索引系统。

唯一的缺点是一个 32 位数字可能需要 10-11 个 ascII 字符才能放入表中(例如 1234567890)。这使得一个 4 字节的数字基本上是 10-11 个字节的 ascII,基本上将大小增加到原始大小的 250%,更不用说相同的值也被推到索引中,我估计增加了 500%。

我想我可以通过将数字转换为字母数字字符的独特组合来压缩数字。

例如

  • 简单的分词器可识别 26 个字母 (aZ),将大写字母转换为小写字母。
  • 它还可以识别 10 个数字 (0-9)

这使我可以开始使用每个字节的 36 个组合。

这意味着我可以用 6 个字符压缩多达 36^6 = 21.7 亿的范围(足以压缩 32 位整数的正范围)。或包含 7 个字符的整个范围(正负)。减少 30%。

但是简单的标记器也可以识别码点 >= 128 的 unicode 字符。这意味着,我可以跳过字母数字字符,而使用 unicode 字符进行压缩。

假设toekenizer 可以识别高于128 的每个代码点,则可以将99.6% 的32 位整数范围编码为4 个字节,并将整个范围编码为5 个,例如(2 个unicode16 位字符+ 1 个8 位字母数字)。

但是我的问题是……很多 unicode 范围都充满了保留值。简单的标记器会搜索整个可能的代码点范围(即保留值会起作用吗?),还是只对某些值起作用(哪个?)。

4

1 回答 1

1

SQLite 并不真正关心哪些字符有效或无效(只要避免代理范围),但使用 Unicode 字符不会大大提高存储效率,因为在 UTF-8 中,非 ASCII 字符可以存储在两个以上字节。

FTS 索引不存储每个列的值,而只是存储单词编号,因此在存在重复时它们更有效。

如果可能的话,您应该组织表格,以便将数字作为单个值存储在列中。

于 2013-08-11T07:22:20.123 回答