Я ищу встраиваемый механизм хранения данных в C ++. RocksDB — это хранилище ключей-значений.
Мои данные очень однородны. У меня есть скромное количество типов (порядка 20), и я храню много экземпляров (порядка 1 миллиона) этих типов.
Я полагаю, что однородность моих данных делает RocksDB плохим выбором. Если я сериализую каждый объект по отдельности, наверняка я дублирую метаданные схемы? И, конечно же, это приведет к снижению производительности?
Итак, мой вопрос: Является ли RocksDB хорошим выбором для хранения однородных объектов? Если да, то как избежать влияния на производительность дублирования метаданных схемы?
Как я понимаю, RocksDB на самом деле является хранилищем KeyValue, а не базой данных вообще.
Это означает, что вы получаете только возможность хранить двоичный ключ и данные значений. В отличие от обычной базы данных (например, MySQL, SQLite) у вас нет таблиц, в которых вы можете определить столбцы / типы и т. Д.
Поэтому именно ваша программа определяет, как будут храниться данные.
Одной из возможностей является сохранение ваших данных в виде значений JSON, и в этом случае, как вы говорите, вы платите за хранение «схемы» (то есть имен полей JSON) в значениях.
Другой выбор может быть, у вас есть специальный ключ (например) под названием SCHEMA которая содержит схему AVRO всех ваших типов объектов. Ваше приложение может прочитать это при запуске, инициализировать устройства чтения / записи, а затем оно знает, как обрабатывать каждый ключ + значение, хранящееся в RocksDB.
Еще одним вариантом может быть жесткое программирование логики в вашем приложении. Для этого вы можете использовать любое количество библиотек, включая AVRO (как упоминалось выше) или MsgPack и его варианты. В этом случае вам нужно быть осторожным, если вы собираетесь использовать данные RocksDB из предыдущей версии приложения, если вы внесли какие-либо изменения в схему. Так что, возможно, сохранить номер версии или что-то в БД.
В отличие, например, от sqlite, в RocksDB нет метаданных схемы, потому что нет схемы: она отображает двоичный ключ в двоичное значение. RocksDB не имеет встроенной сериализации. Если вы храните объекты, вам придется самим их сериализовать и использовать, например, ключ, префикс ключа или семейство столбцов (свет таблицы ~ DB) для различения типов.
Обычно вы используете RocksDB для создания какой-то пользовательской базы данных. Кто-то создал, например, кеш для объектов protobuf поверх него (ProfaneDB). Часто я бы сказал, что он слишком низкоуровневый, но если вам не нужны структурированные данные и запросы, он будет работать нормально, очень быстро и с ним обычно приятно работать (их код читабелен, а иногда и лучшая документация, потому что вы будете иметь дело с внутренностями базы данных).
Раньше я использовал префикс ключа varint в небольшом игрушечном приложении, который занимает всего около байта до 127 типов, но семейства столбцов, вероятно, предпочтительнее для приложения prod. Они также имеют постоянные издержки и могут индивидуально настраиваться, добавляться, отбрасываться и управляться. Я бы не отказался от дополнительных функций, которые вы получаете от них, на несколько байтов. Это также примерно соответствует уровню, на котором вы будете иметь дело с проблемами, если вы пойдете с RocksDB.