Хранение сложной структуры в mysql. Как?

Приветствую.
Имеется проект, посвященный кино, написан на php, js, данные храню в mysql.

Сейчас пишется сервис, который позволит просить совета — «а какой бы фильм мне посмотреть?».

Собственно, логика сервиса такова:
пользователь пишет пожелание, выбирает из списка фильмы, которые ему нравятся и на какие из них он хочет видеть похожим советуемый фильм.
Вопрос: как это хранить в БД наиболее хорошим образом?
Сейчас это выглядит так:
таблица с комментарием пользователя, таблица со строками похожих фильмов (хранятся ID фильмов — сервис имеет свою базу фильмов для просмотра)

Ответ происходит следующим образом:
пользователь пишет коммент к своему ответу и советует парочку фильмов

Главный вопрос: как хранить?

Делать 4 таблицы (коммент запроса, похожие фильмы запроса, коммент ответа, фильмы ответа) не очень хочется во нескольким причинам:
слишком много запросов в БД будет на получение списка запросов на просмотр (запрос, фильмы, кто, что советует)
слишком много лишних телодвижений будет и при ответе

Спасибо.

Скриншоты для лучшего восприятия информации:
image
image
  • Вопрос задан
  • 3563 просмотра
Пригласить эксперта
Ответы на вопрос 9
@kliss
Сделай пока как знаешь. Авось сойдет. Ибо джойны — зло, а premature optimization is the root of all evil :)
Ответ написан
denver
@denver
Делать 4 таблицы (коммент запроса, похожие фильмы запроса, коммент ответа, фильмы ответа) не очень хочется во нескольким причинам:
слишком много запросов в БД будет на получение списка запросов на просмотр

Ерунда, тут всё можно получить в один запрос. И не слишком-то медленный.
Вообще, у вас странная формулировка. Правильно хранить так, как удобнее доставать. Но как доставать нужно вам пишете только мельком. Поэтому пока храните в mysql нормализированно, 4 таблицы это правильно. Если (точнее когда) надо будет ускорить — денормализируйте, только в ту сторону в которую вам надо, а пока не ясно куда.
Ответ написан
Shedal
@Shedal
Делать 4 таблицы (коммент запроса, похожие фильмы запроса, коммент ответа, фильмы ответа) не очень хочется во нескольким причинам:
слишком много запросов в БД будет на получение списка запросов на просмотр (запрос, фильмы, кто, что советует)
слишком много лишних телодвижений будет и при ответе
Что значит слишком много? По сравнению с чем?

Вообще, 4 таблицы — это будет нормализированный способ хранения ваших данных. Можно и денормализировать, но это ухудшит расширяемость и возможности по манипуляци данными средствами SQL. Иногда денормализация приемлема, просто нужно в полной мере осознавать, какими будут последствия.

Например, можно сделать две таблицы: Comments и CommentMovies. В Comments добавить поле IsQuestion, в котором хранить TRUE, если это вопрос и FALSE, если это ответ. CommentMovies будет хранить фильмы как для вопросов, так и для ответов.
Минусом такого подхода будут проблемы функциональной расширяемости. То есть, если вы захотите добавить в таблицу Comments поле, присущее только вопросам, то у вас будет, по сути, три пути:
1) Рефакторинг структуры: разделение на ваши исходные 4 таблицы. Это трудозатратно;
2) Добавление ещё одной таблицы: QuestionCommentFields. Структура получается корявой;
3) Создание поля, которое будет хранить значения только для одного типа строк. Это уже денормализация.

Можно фильмы хранить в виде строки в основной таблице, перечисленными через запятую. Это денормализация, она упростит структуру, но усложнит и замедлит изменение и поиск данных.

В общем, выделите для себя какие-то приоритеты и путеводные камни. Будет ли структура часто меняться в будущем, важна ли простота поддержки? Важна ли скорость выполнения запросов, важна ли возможность менять данные напрямую SQL'ем? И т.п.
Ответ написан
Vidog
@Vidog
Может быть посмотреть в сторону noSQL, например mongoDB или redis. У монго неплохой map/reduce.
Еще можно попробовать postgreSQL — там очень хорошо со структурами таблиц, есть массивы и свои типы — связи между таблицами достаточно просто сделать на нативном уровне.
Ответ написан
@ComodoHacker
Запрос и ответ можно хранить в одной таблице. Списки фильмов, из них — тоже. Получаем две таблицы вместо четырех.
Годится?
Ответ написан
@Neir0
NOSql решения не рассматриваются?
Ответ написан
Сначала напишите на PHP в каком видите вы хотите работать с данными (иерархию объектов, вложенность массивов и т. п.), прикиньте как будете расширять «поля» при необходимости, чтобы не ломать весь код), и только потом думайте как это отобразить на БД. Хотя бы потому что одни и те же отношения между сущностями PHP можно реализовать в БД разными способами, например наследование (от абстрактного «коммента» наследуются «вопрос» и «ответ») отображается минимум тремя способами, а создавая их на основе базы можно просто не заметить, что имеет место какое-то удобное и понятное отношение.

Абстрагируясь от схемы БД вы можете инкапсулировать работу с ней в функции/методы типа $answers = get_answers($question_id) или $answers = Answer.getByQuestion($question) и в них привязывать любую схему БД, или вообще не схему и не БД. Поменяете схему — нужно будет поменять только эти реализации, не трогая основную логику, в ней так и будете обращаться к названию фильма как $questions[$question_id]['answers'][0]['films'][0]['name'] или $questions[$question_id].answers[0].films смотря предпочтётё вы хранить сушности в массивах или объектах.
Ответ написан
Комментировать
ainu
@ainu
Всё уже придумано до нас. Есть схемы связей many_to_many, one_to_many, many_to_one. Комбинируя их, можно легко реализовать схему. Большинство систем для работы с БД (имею в виду AcriteRecord и ORM — составляющие) это умеют.
Кстати, 4 запроса, каждый из которых просматривает 1 строку при поиске, лучше, чем один запрос, просматривающий 10000.
Ответ написан
Комментировать
bergsteiger
@bergsteiger
Попробуйте 1 таблицу для комментов с флагом, означающим «запрс/ответ» и одну таблицу для «прикрепляемых» фильмов… как вариант для «подумать».
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
24 апр. 2024, в 20:57
3000 руб./за проект
24 апр. 2024, в 20:35
5000 руб./за проект