как лучше хранить битовую маску?

165 views
Skip to first unread message

Robert

unread,
Jul 7, 2016, 4:56:41 AM7/7/16
to ClickHouse
Добрый день!

Огромное спасибо разработчикам и Яндексу! Это просто сказка!

У меня вопрос.

С IoT устройств, каждое сообщение содержит битовую маска в int64. Безусловно возникает необходимость искать по отдельным битам. 
Подскажите, лучше разворачивать в виде 64 отдельных байтовых колонок?  Или есть другие варианты?
 
Спасибо

man...@gmail.com

unread,
Jul 7, 2016, 2:27:31 PM7/7/16
to ClickHouse
Добрый день.

Это зависит от того, используются ли в запросах часто отдельные флаги (биты), или все сразу.
Если флаги имеют отдельный друг от друга смысл и нужно делать запросы с использованием 1..10 флагов, то лучше разложить их по отдельным столбцам (типа UInt8, содержащим 0 или 1).
Если флаги имеют какой-то однородный смысл, и нужно часто делать операции сразу над всей маской, то лучше положить в один столбец.

Для примера: в данных Метрики есть столбцы IsMobile, IsTablet, IsDownload, IsLink и т. п. То есть, мы используем отдельные столбцы, а не битовую маску.

Robert

unread,
Jul 8, 2016, 1:56:55 AM7/8/16
to ClickHouse
Спасибо за ответ!

А что скажете о такой альтернативе? Сейчас проанализировал насколько много записей с выставленными битами.
У 96% записей все биты нулевые. У остальных записей установлено максимум 4 бита (разных бита безусловно), но безусловно может быть больше выставленных битов.
Что если хранить только позиции выставленных битов в виде массива Int8?
И в выборке использовать поиск по вхождению в массив в том случе если длина массива больше нуля? Или там есть подводные камни?

Спасибо.

Юрий Дьяченко

unread,
Jul 8, 2016, 5:43:56 AM7/8/16
to ClickHouse
Кажется, такой вариант вполне может подойти. Нужно понимать, что храниться такая конструкция будет следующим образом:
Будет создано 2 файла, в одном их них будет храниться количество элементов массива для строки (uint64_t), во втором будут храниться сами значения.
Файл с количеством элементов должен сжаться очень хорошо т.к. уникальных значений будет совсем мало. Файл с данными должен сжаться несколько хуже, но скорее всего лучше, чем битова маска (UInt64). При доступе к массиву системе придется читать и разжимать оба файла. Так же несколько усложнится сама процедура выборки: в секции WHERE должно быть что-то типа arrayAll(x -> x IN (3, 4, 5), array_column).

Из безусловных плюсов: можно хранить битовые маски произвольной длинны.

Пробуйте, будет интересно узнать результаты.

man...@gmail.com

unread,
Jul 8, 2016, 1:54:24 PM7/8/16
to ClickHouse
Мне почему-то кажется, что это будет менее удобно, чем использовать UInt64 или много столбцов-флагов типа UInt8, а разница по сжатию будет незначительной.
Наверное, вариант без массивов будет работать быстрее.
Reply all
Reply to author
Forward
0 new messages