«Простые мелодии» или как все свести к коллекциям
Привет хабр. Делюсь своей наработкой, даже с большего концепцией в плане организации хранения данных и работы с ними для определенного класса задач.
Об идее и полученном прототипе ниже.
Предистория. По части фриланса, с тройку проектов за последние пол года между собой были очень похожи. Прослеживался четкий общий знаменатель. Они требовали генерацию каких то заранее не определенных списков, иерархии категорий и отображения этого всего в какой то суммарной таблице с последующей распечаткой на бумагу и прочее. Как правило точности вектора развития проекта сложно понять даже самому заказчику на момент переговоров. Все это способствовало зарождению следующей идеи.
Основная идея. В качестве ключа отдельной записи указываем ключи, которые по смыслу определяют к каким множествам относится запись. Если проводить аналогию с известными нам вещами — это подобно, например, тегам, которыми помечаем статьи на хабре. Далее мы статью можем найти по комбинации тегов. Либо по точному совпадению ключей. Либо если указанные теги входят в теги статьи. Либо если указанные теги пересекаются с тегами статьи.
Вспомогательная логика. Если один из ключей принимает значение uniq то запись с текущей совокупностью ключей будет уникальна (индекс values_uniq_ifcontainuniqkey_idx).
В прототипе РСУБТ postgre. На поле с ключами индекс gin.
Схема БД, индексы и вспомогательные функции.
CREATE TABLE values (
value_id uuid NOT NULL PRIMARY KEY,
keys text[],
value jsonb NOT NULL DEFAULT '{}',
is_removed boolean DEFAULT false,
created_at timestamp,
updated_at timestamp DEFAULT now()
);
create function sort_text_array(text[]) returns text[][] as $$
select array_agg(n) from (select n from unnest($1) as t(n) order by n) as a;
$$ language sql immutable;
CREATE INDEX values_keys_gin_idx on values USING GIN (keys);
CREATE UNIQUE INDEX values_uniq_ifcontainuniqkey_idx on values (sort_text_array(keys))
WHERE keys @> '{uniq}';
На клиенте получаем коллекцию записей. Дальнейшие действия на клиенте с данной коллекцией уже сводится к выборке требуемых записей по ключам. И это уже детали второстепенные которые мы опустим. Несколько примеров к прототипу приложены и продемонстрированы.
В итоге была весьма упрощена жизнь в плане разработки API для UI. Не требовалось продумывать и разрабатывать схему БД. Суммарно на разработку подобного проекта уже требовалось разы меньше времени.
Прототип на github-е.
В ваших комментариях мне будет интересно услышать проекты\задачи, в которых возможно применение описанного подхода. Плюсы и минусы которые видите. В целом все то, что поможет сформировать более масштабный взгляд.