2013-08-11 3 views
0

У меня есть таблица FTS 3 на устройстве Android. Один из столбцов в таблице содержит массивы 32-разрядных чисел в текстовом формате. Я использую FTS, потому что FTS сравнительно чрезвычайно быстро обнаруживает уникальные значения, учитывая его индексную систему.SQlite FTS сжать размер «текстового» номера столбца

Единственным недостатком является то, что 32-разрядное число может принимать 10-11 символов ascII для размещения в таблице (например, 1234567890). Это составляет 4 байта в количестве 10-11 байт ascII, существенно увеличивая размер до 250% оригинала, не говоря уже о том же значении, которое также затухает в индексе, для чего я оценил увеличение на 500%.

Я понял, что могу сжать число, превратив его в уникальную комбинацию буквенно-цифровых символов.

E.g.

  • простой токенизатор распознает 26 букв (a-Z), преобразует прописные в строчные буквы.
  • также распознает 10 номеров (0-9)

, что дает мне начать 36 комбинаций на байты для работы.

Это означает, что я мог бы сжать до диапазона 36^6 = 2,17 млрд. С 6 символами (достаточно, чтобы сжать положительный диапазон 32-битного целого числа). Или весь диапазон (положительный и отрицательный) с 7 символами. Снижение на 30%.

Но простой токенизатор также распознает символы Unicode с кодовыми точками> = 128. Это означает, что я мог пропускать буквенно-цифровые символы, в пользу символов Unicode для сжатия.

Предполагая, что указатель распознал каждую кодовую точку выше 128, можно было кодировать 99,6% от 32-битного целочисленного диапазона в 4 байта, а полный диапазон в 5, например. (2 символа unicode16 бит + 1 8 бит буквенно-цифровой).

Но есть мой вопрос ... Большая часть диапазонов юникода заполняется зарезервированными значениями. Будет ли простой поиск токенизатора во всем возможном диапазоне кодовых точек (т. Е. Будут ли зарезервированные значения работать?), Или он будет работать только для некоторых значений (что?).

ответ

1

SQLite действительно не заботится о том, какие символы действительны или нет (если вы избегаете суррогатного диапазона), но использование символов Юникода не улучшит эффективность хранения, поскольку в UTF-8 могут сохраняться символы без ASCII в более чем двух байтах.

Индексы FTS не сохраняют каждое значение столбца, а просто номера слов, поэтому они более эффективны при наличии дубликатов.

Если возможно, вы должны организовать свою таблицу, чтобы числа могли храниться как одиночные значения в столбце.

+0

Вы правы, это не будет большой выгодой для хранения. Я не смог объяснить факт, что 5 бит в UTF-16 являются сигнальными битами, просто чтобы сказать «эй, я - символ UTF-16». Это означает, что для кодирования чисел осталось только 11 бит. Таким образом, вместо 16^2 мы имеем 11^2, что означает, что потребуется не менее 3 символов UTF-16 (6 байт), предполагая, что каждый перечислимый код был действительным. Это всего лишь 1 байт улучшение по сравнению с тем, что я могу сделать с обычной буквенно-цифровой кодировкой, чтобы получить весь диапазон int32. –

+0

SQLite всегда использовал UTF-8, который использует переменную кодировку. Символы между U + 0080 и U + 07FF кодируют 11 бит в двух байтах, между U + 0800 и U + FFFF кодируют 16 бит в трех байтах, между U + 10000 и U + 10FFFF кодируют 21 бит в четырех байтах. –

Смежные вопросы