Трудности выбора
Пишу этот пост в напоминание о муках выбора схемы для БД.
Строго говоря, это уже третий подход к этому снаряду.
Первая версия задумывалась как одна таблица с уникальным индексом и куча мелких таблиц, под каждую конкретную категорию данных. Выглядело это примерно так:
s_files:
| uuid | path |
| ... | ... |
d_tags:
| uuid | tags |
| ... | ... |
d_img:
| uuid | res_x | res_y | ... |
| ... | ... | ... | ... |
...и так далее. Схема достаточно громоздкая, но легко расширяемая. Окинув сиё трезвым взором и перечитав реймонда для наставления себя на путь истинный, решил не делать программу "на вырост", а ограничится текущими потребностями - хранением и поиском тегов. Маятник качнулся в другую сторону - выкинул все талички и все данные загнал в одну табличку - вместе с uuid'ом. Выглядело всё это примерно так:
| uuid | path | name | tags |
| ... | ... | ... | ... |
Но пожалуй я перестарался. При попытки проработать запросы к базе, я понял, что не смогу сделать поиск по тегам без LIKE, а список уникальных тегов можно получить, только прочитав весь массив данных и распарсив каждую строчку. Автодополнение и статистика тэгов накрывается медным тазом.
Сейчас ваяю третью версию схемы БД, предварительный вариант состоит из 3х табличек:
| f_id | crc_path | crc_name | filename |
| ... | ... | ... | ... |
| t_id | used | tag |
| ... | ... | ... |
| f_id | t_id |
| ... | ... |
Реальный uuid в схеме - трёхкомпонентный, всего в базе может хранится 2^24 файлов или, 16.5 миллионов. Число запросов вырастет, по сравнению с предыдущим вариантом, сами запросы станут сложнее, так что нужно дважды подумать, нужна ли нам такая плата за автодополнение по тегам.
Ограничение на количество тэгов я вводить не хочу, рано или поздно в это упрусь либо я, либо юзеры. А вот на длинну одного тега - неплохо было бы. Если у вас тег в килобайт размером, вы явно что-то делаете не так.
Также, нужно сохранить быструю выборку по всем файлам в директории.
UPD: Блиа!!! "А на третий день Зоркий Глаз заметил, что четвертой стены в камере нет." Думал-думал как обеспечить идентификатором теги. С путями всё понятно - там чексуммы. И пришла в голову простая, но гениальная мысль - "Используй чексуммы, Лю^W блжад!". Коллизий на такой длинне "текста" не будет, и она легко сводится к bigint. Т.о. все выборки будут идти против таблицы с двумя bigint'ами фиксированного размера!
UPD2: По результатам тестов, придуманная схема просирает впятеро по производительности против "одной таблицы". Выборка - ~300k файлов, ~32к уникальных тэгов. Число связей на файл - rand(1,10).