Проектирую структуру бд и зашел в тупик. Дано:
Есть сущность "задание". За выполнение задания предусматривается награда, сейчас это деньги (в разных валютах) и/или мерч и/или диплом.
Спроектировал так:
Таблица task
- id
- ...
- withDiploma (boolean)
- items (какие мерчи даются в качестве награды)
- currencies
Таблица Item
- id
- name
- image_src
- category (по типу кружка, блокнот, коврик)
Таблица currency
- id
- name (Рубль, Доллар)
- sybmol (P, $)
- icon_src
Таблица task_currency
- id
- task_id
- currency_id
- amount
Что нравится при такой реализации: можно относительно простым запросом получить task со всей нужной инфой (task: { id, withDimpoma, items: { ... }[], currencies: { ... }[] })
Что смущает: в будущем может появиться больше типов наград, например, "билеты" (id, name, expire_date), "услуги" (id, name, category) и тд. Соответственно, по мере появления нового типа награды таблица task будет расширяться по горизонтали.
Подумал сделать так:
Таблица task
- id
- ...
Таблица reward
- id
- task_id
- type (dimploma | currency | ticket | item)
- entity_id (если type = dimploma, то null; если type = current, то currency.id; если type = item, то item.id)
- amount
Такой вариант кажется более масштабируемым, однако требуется много дополнительных манипуляций для получения объекта task с доступными наградами и с информацией по каждой награде. Получается, нужно получать reward-ы по task_id, далее смотреть на type каждого reward-a и ходить в нужную таблицу для получения информации о реварде.
Надеюсь понятно объяснил, прошу подсказать в какую сторону двигаться. Может моя текущая реализация самая оптимальная и горизонтальный рост таблицы по мере появления новых типов - норм?
Вы там в самом начале написали условие получения наград - и/или
Это предполагает, что за задание может выдаваться несколько наград (диплом и мерч к примеру).
Значит вам нужна связь между таблицами задач и наград "многие-ко-многим" с промежуточной связной таблицей.
Учитывая, что награды бывают разных типов, то имеет смысл определить для каждого типа свою таблицу и организовать полиморфную связь.
таблица tasks
id | other_fileds...
таблица rewards_diplomas
id | other_fields...
таблица rewards_currencies
id | other_fields...
и т.д.
reward_task - связная таблица
task_id | reward_type | reward_id
task_id - идентификатор задачи
reward_type - тип награды (diploma, currency..)
reward_id - идентификатор награды из соответствующей таблицы
Из плюсов - расширяемость. Из минусов - усложнение запросов выборки и невозможность использования внешних ключей и ограничений.