Я создаю сайт, содержащий тысячи предметов.Помимо прочего, пользователи могут голосовать за присвоение тегов элементам со следующей логикой:
- Пользователи могут голосовать за любое количество тегов для каждого элемента.
- Элементы могут иметь любое количествотегов.
- Любой элемент получает тег, где
[the number of votes for that tag] ≥ 0.5 * [the number of votes for the most voted tag]
(внутри вопроса). - Пользователи могут видеть и изменять свой голос за элемент, поэтому мне нужно сохранить фактические голоса.
Я новичок в SQL и мне интересно, как лучше всего заполнить элементы тегами.
Я хочу, чтобы отношения были доступны в обоих направлениях.Т.е. я хочу иметь возможность получить все tags
для любого item
и все items
для любого tag
.
Технический стек:
- DB: MySQL-сервер под управлением v. 8 (может переключаться, например, на Postgres)
- API: приложение узла, работающее в экспресс-формате с Objection.js в качестве ORM (но я предполагаю, что вопросAPI-независимость).
Я вижу два основных способа сделать это:
Решение 1 : при запросе элемента или тега, количество и группаголосов и выберите те, которые соответствуют критериям в пункте 3 выше.
Решение 2 : Когда пользователи голосуют, сделайте те же вычисления и сохраните теги в соединительной таблице.
Насколько я вижу, MWE-конфигурация базы данных имеет следующие 4 таблицы:
user TABLE
- id
- (...)
question TABLE
- id
- (...)
tag TABLE
- id
- (...)
votes TABLE
- user_id
- question_id
- tag_id
и, если выбрано решение 2, добавляется 5-я таблица:
question_tag TABLE
- question_id
- tag_id
Мне удалось заставить обе установки работать во время разработки.
Для решения 1 мне нравится, что нет избыточности данных.Однако взаимосвязь определяется не так прямо, и запросы к «другим» данным немного беспорядочные - и так должно быть в обоих направлениях.
Для решения 2 я (по сути) храню одни и те же данные дважды.Однако запрос отношения гораздо проще и, вероятно, более производительный (я ожидаю гораздо более простых представлений как элементов, так и тегов, чем голосов).
Итак, по сути, мой вопрос сводится к следующему: что считается лучшей практикой- и есть ли еще лучший способ добиться этого?
Спасибо!