Подтвердить что ты не робот

Выбор схемы базы данных для хранения системы папок

Я пытаюсь реализовать базу данных на базе SQLite, которая может хранить полную структуру папки размером 100 ГБ со сложной субструктурой (ожидая 50-100 Кбайт файлов). Основной целью БД было бы получить быстрые запросы по различным аспектам этой папки (общий размер, размер любой папки, историю папки и все ее содержимое и т.д.).

Однако я понял, что найти все файлы внутри папки, включая все ее подпапки, невозможно без рекурсивных запросов, если я просто создаю таблицу "файлов" только с поля parent_directory. Я рассматриваю это как одну из наиболее важных функций, которые мне нужны в моем коде, поэтому я рассмотрел два варианта схемы для этого, как показано на рисунке ниже.

  • В схеме 1 я сохраняю все имена файлов в одной таблице и именах каталогов в другой таблице. Они оба имеют элемент "parentdir", но также имеют текстовое поле (очевидно, текстовое/blob-то же в sqlite), которое называется "FullPath", которое сохранит весь путь от корня до конкретного файла/каталога (например,/etc/а/Def/вау/LongPath/test.txt). Я не предполагаю максимальный лимит подпапки, поэтому теоретически это может быть поле, которое допускает до 30 тыс. Символов. Моя идея заключается в том, что если я хочу, чтобы все файлы или каталоги принадлежали любому родителю, я просто запрашиваю полный путь родителя в этом поле и получаю fileIDs

  • В схеме 2 хранятся только имена файлов, файловые идентификаторы и DirNames, DirIDs в каталогах и таблицах файлов, соответственно. Но в третьей таблице под названием "Предки" я храню для каждого файла набор записей для каждого каталога, являющегося его предком (так что в приведенном выше примере test.txt будет иметь 5 записей, указывая на DirIDs папок и т.д. abc, def, wow и longpath соответственно). Тогда, если я хочу полное содержимое любой папки, я просто ищу DirID в этой таблице и получаю все идентификаторы fileID.

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

Каким будет лучшее из этих решений? Есть ли лучшее решение, о котором я не думал?

Two possible schemas to keep rapid allow rapid retrieval of *all* the descendants of a directory in a complex directory structure

4b9b3361

Ответ 1

  • Ваша первая схема будет работать нормально. Когда вы помещаете индекс в столбец FullPath, используйте либо регистр-регистр BETWEEN для запросов, либо используйте LIKE с COLLATE NOCASE по индексу или с помощью PRAGMA case_sensitive_like.

    Обратите внимание, что эта схема также хранит всех родителей, но идентификаторы (имена) объединены в одно значение.

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

  • Вторая схема - это Таблица закрытия, упомянутая в комментарии Dan D. Будьте осторожны, чтобы не забыть записи для глубины 0.

    Это будет хранить много данных, но, будучи идентификаторами, значения не должны быть слишком большими.

    (Вам действительно не нужно RelationshipID, не так ли?)

  • Другим выбором для хранения деревьев является вложенная модель набора или аналогичная модель вложенных интервалов. Вложенная модель набора позволяет извлекать поддеревья, запрашивая интервал, но обновления являются волосатыми. Модель вложенного интервала использует фракции, которые не являются нативным типом данных и поэтому не могут быть проиндексированы.

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

Ответ 2

Мой личный фаворит - это номер посетителя, который, я думаю, будет особенно полезен для вас, поскольку он довольно легко запускает агрегированные запросы к записи и ее потомков.