Магазин ключей-значений от foldername
У нас есть собственная база данных NoSQL DB, которая в основном хранит все в компактном двоичном файле. Теперь мне нужна структура данных, похожая на хранилище значений ключей или B+Tree. Проблема в том, что "ценность" в моем случае может быть разных типов и иметь очень изменчивый размер, может быть от 1Кб до 1-2Гб. Обычно ключ представляет собой строку, а значение представляет собой поток данных, может быть потоком типа int, string или произвольного типа.
Я думал о реализации B+ Tree, но это нелегко, потому что B + Tree нужно, чтобы "значение" было того же типа, а размер "значения" должен быть достаточно мал, чтобы его можно было хранить в относительно небольшом блоке. Возможно, есть вариант, но я не нашел учебника по реализации дерева B + с примерами, показывающими, как хранить на диске. Большинство уроков, которые я вижу, это только B + Tree в памяти.
У меня тогда есть идея использовать имя папки / файла в качестве ключа. И тогда значение может быть любым внутри файла. Значения могут быть произвольного размера, это действительно то, что я хочу. Так что мой вопрос здесь, в крайнем случае,
- данные за разные дни хранятся в отдельных папках
- У меня могут быть ключи 1M-50M (действительно файлы / папки) для хранения на диске в течение нескольких дней
- Операции с данными над файлами обычно выполняются только для чтения и добавляются в течение дня. Исторические данные никогда не будут изменены.
Я видел, что у меня может быть ~4 миллиарда файлов в современной ОС, поэтому я доволен таким подходом для хранения ~2 года на одной машине. Я просто волнуюсь, если такой способ реализации хранилища значений ключей очень плох? Зачем? Какие проблемы могут возникнуть при работе с файловой системой? (Фрагментированный диск на windows например?)
Все они реализованы на C++ как в Windows, так и в Linux.
3 ответа
Я думаю, если вы можете обеспечить и соответствовать вашим требованиям, это не должно быть плохо. Я сделал подобное для встроенного проекта и его ограниченного набора данных.
Вещи должны быть рассмотрены
- ОС / Файловая система должна поддерживать необходимую длину папки (ключ) и имя файла (как вы выберете)
- Он фрагментирует диск и может задержать доступ к диску для огромных структур каталогов. Что может повлиять на общий системный процесс.
- Производительность приложения может ухудшиться, так как операция чтения / записи зависит от файловой операции - возможно, вы можете добавить кеш в вашу программу, если потребуется.
- Не подходит для многопоточных приложений, следует позаботиться о блокировке файлов.
- О безопасности нужно заботиться.
"Данные за разные дни хранятся в разных папках" - это не удобно, если вы хотите выполнить поиск по дням.
Кроме того, вы можете столкнуться с проблемами, когда количество файлов в папке превышает ограничение файловой системы. 4 миллиарда файлов на диске - не проблема, 50M в одной папке. Но вам не нужно хранить все в одной папке, конечно. Ключ может быть разделен на часть папки и часть имени файла.
Вещи становятся сложными, если вам нужно полагаться на свойство B-Tree при поиске диапазона ключей. Это означает, что вам нужен порядок, и вы не можете использовать функцию хеширования для сопоставления ключа с парой папка / имя файла. В этом случае у вас есть проблема. В худшем случае ваши ключи непрерывно имеют значение от "1" до "999999999", плюс случайный набор ключей намного большего размера. Это означает, что вы не можете использовать последние 4 цифры в качестве имени файла (слишком много папок) или последние 8 цифр (слишком много файлов).
Почему вы беспокоитесь о размере стоимости. Вы можете использовать свой существующий дБ. Значение может быть строкой следующего формата "type|value_data", где "|" это разделитель.
Здесь value_data может быть "фактическим значением" или "путем к файлу, который содержит значение"
- type = LOCAL (в этом случае value_data будет фактическим значением, если оно может уместиться в дБ)
- type = REMOTE (в этом случае value_data будет путем к файлу)