SQlite FTS压缩“文本”编号列的大小

时间:2013-08-11 01:55:28

标签: android sqlite full-text-search tokenize

我在Android设备上有一个FTS 3表。表中的一列包含文本格式的32位数字数组。我正在使用FTS,因为FTS在索引系统中找到非唯一值的速度相对非常快。

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

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

E.g。

  • 简单的标记符识别26个字母(a-Z),将大写转换为小写。
  • 它还识别10个数字(0-9)

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

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

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

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

但我的问题是......大部分unicode范围都充满了保留值。简单的标记化器是否会搜索整个可能的代码点范围(即保留值是否有效?),还是仅适用于某些值(哪个?)。

1 个答案:

答案 0 :(得分:1)

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

FTS索引不存储每个列值而只存储字数,因此当存在重复时它们会更有效。

如果可能的话,你应该整理你的表格,以便数字可以作为单个值存储在一列中。