Реализация комментариев и лайков в базе данных - PullRequest
118 голосов
/ 13 ноября 2011

Я разработчик программного обеспечения.Я люблю кодировать, но ненавижу базы данных ... В настоящее время я создаю веб-сайт, на котором пользователю будет разрешено отмечать сущность как понравившийся (как в FB), tag это и комментарий .

Я застрял в дизайне таблиц базы данных для обработки этой функции.Решение тривиально, если мы можем сделать это только для одного типа вещей (например, фотографии).Но мне нужно включить это для 5 разных вещей (на данный момент, но я также предполагаю, что это число может расти по мере роста всего сервиса).

Я нашел несколько подобных вопросов здесь, но ни один из них не имеетудовлетворительный ответ, поэтому я снова задаю этот вопрос.

Вопрос в том, как правильно эффективно и упруго проектировать базу данных, чтобы она могла хранитькомментарии для разных таблиц , лайков для разных таблиц и тегов для них.Какой-то шаблон дизайна в качестве ответа будет лучшим;)

Подробное описание : у меня есть таблица User с некоторыми пользовательскими данными и еще 3 таблицы: Photo с фотографиями , Articles с артикулами , Places с местами .Я хочу, чтобы любой зарегистрированный пользователь мог:

  • комментировать любую из этих 3 таблиц

  • пометить любую из них как понравившуюся

  • пометить любого из них каким-либо тегом

  • Я также хочу подсчитать количество лайков для каждого элемента и количество раз, которое данный тег использовался.

1 st подход :

a) Для тегов я создам таблица Tag [TagId, tagName, tagCounter], тогда я создам отношения многие ко многим отношения таблицы для: Photo_has_tags, Place_has_tag, Article_has_tag.

b) То же самое для комментариев.

c) Я создам таблицу LikedPhotos [idUser, idPhoto], LikedArticles[idUser, idArticle], LikedPlace [idUser, idPlace].Количество лайков будет рассчитываться по запросам (что, я полагаю, плохо).И ...

Мне действительно не нравится этот дизайн для последней части, он плохо пахнет для меня;)

2 и подход :

Я создам таблицу ElementType [idType, TypeName == some table name], которая будет заполнена администратором (мной) с именами таблиц это может быть понравилось , прокомментировано или помечено .Затем я создам таблицы :

a) LikedElement [idLike, idUser, idElementType, idLikedElement] и то же самое для комментариев и тегов с соответствующими столбцами для каждого.Теперь, когда я хочу сделать понравившуюся фотографию, я вставлю:

typeId = SELECT id FROM ElementType WHERE TypeName == 'Photo'
INSERT (user id, typeId, photoId)

и для мест:

typeId = SELECT id FROM ElementType WHERE TypeName == 'Place'
INSERT (user id, typeId, placeId)

и так далее ... Я думаю, что второй подход лучше, но я также чувствую, что чего-то не хватает в этом дизайне ...

Наконец, мне также интересно, какое лучшее место для хранения счетчика, сколько раз этот элемент понравился.Я могу думать только о двух путях:

  1. в таблице элементов (Photo/Article/Place)
  2. с помощью select count ().

Я надеюсь, что мойОбъяснение проблемы теперь более основательно.

Ответы [ 7 ]

165 голосов
/ 13 ноября 2011

Самое расширяемое решение - иметь только одну «базовую» таблицу (связанную с «лайками», тегами и комментариями) и «наследовать» от нее все остальные таблицы.Добавление нового типа сущности включает в себя просто добавление новой «унаследованной» таблицы - она ​​затем автоматически подключается ко всему механизму типа / tag / comment.

Термин отношения сущности для этого - «категория» (см. Руководство по методам ERwin , раздел "Отношения подтипов").Символ категории:

Category

Если предположить, что пользователю могут нравиться несколько объектов, один и тот же тег можно использовать для нескольких объектов, но комментарий зависит от объекта, ваша модель можетВыглядит так:

ER Diagram


Кстати, существует примерно 3 способа реализации «категории ER»:

  • Все типы в одномтаблица.
  • Все конкретные типы в отдельных таблицах.
  • Все конкретные и абстрактные типы в отдельных таблицах.

Если у вас нет очень строгих требований к производительности, третий подходвероятно, лучший (имеется в виду, что физические таблицы соответствуют 1: 1 объектам на диаграмме выше).

20 голосов
/ 13 ноября 2011

Поскольку вы «ненавидите» базы данных, почему вы пытаетесь их реализовать?Вместо этого попросите помощи у кого-то, кто любит и дышит этим материалом.

В противном случае, научитесь любить свою базу данных.Хорошо спроектированная база данных упрощает программирование, разработку сайта и обеспечивает бесперебойную работу.Даже опытный проектировщик d / b не будет обладать полным и совершенным предвидением: по мере появления схем использования или изменения требований потребуются некоторые изменения схемы.

Если это проект с одним человеком, запрограммируйте интерфейс базы данныхв простые операции с использованием хранимых процедур: add_user, update_user, add_comment, add_like, upload_photo, list_comments и т. д. Не вставляйте схему даже в одну строку кода.Таким образом, схема базы данных может быть изменена без какого-либо влияния на код: о схеме должны знать только хранимые процедуры.

Возможно, вам придется реорганизовать схему несколько раз.Это нормально.Не беспокойтесь о том, чтобы сделать его идеальным с первого раза.Просто сделайте его достаточно функциональным, чтобы создать прототип исходного проекта.Если у вас есть время роскоши, используйте его немного, а затем удалите схему и сделайте это снова. всегда лучше во второй раз.

18 голосов
/ 15 ноября 2011

Это общая идея пожалуйста, не обращайте особого внимания на стилизацию имен полей, но больше на отношение и структуру

enter image description here

Этот псевдокод получит все комментарии к фотографии с идентификатором 5
ВЫБРАТЬ * ИЗ действий
ГДЕ actions.id_Stuff = 5
AND actions.typeStuff = "photo"
AND actions.typeAction = "comment"

Этот псевдокод получит все лайки или пользователи, которым понравилась фотография с идентификатором 5
(вы можете использовать count (), чтобы просто получить количество лайков)

SELECT * FROM actions  
WHERE actions.id_Stuff = 5  
AND actions.typeStuff="photo"  
AND actions.typeAction = "like"  
0 голосов
/ 13 ноября 2011

Обязательно перейдите ко второму подходу, когда у вас есть одна таблица, и сохраните тип элемента для каждой строки, это даст вам гораздо большую гибкость. По сути, когда что-то можно сделать логически с меньшим количеством таблиц, почти всегда лучше использовать меньшее количество таблиц. Одно преимущество, которое приходит мне на ум в связи с вашим конкретным случаем, заключается в том, что вы хотите удалить все понравившиеся элементы определенного пользователя. При первом подходе вам нужно выполнить один запрос для каждого типа элемента, но при втором подходе это можно сделать. только с одним запросом или рассмотрим, когда вы хотите добавить новый тип элемента, при первом подходе это подразумевает создание новой таблицы для каждого нового типа, но при втором подходе вы ничего не должны делать ...

0 голосов
/ 13 ноября 2011

Рассмотрите возможность использования таблицы для каждой сущности для комментариев и т. Д. Больше таблиц - лучше разделение и масштабирование.Нет проблем с управлением многими подобными таблицами для всех известных мне фреймворков.

Однажды вам нужно оптимизировать чтения из такой структуры.Вы можете легко создавать агрегирующие таблицы поверх базовых и немного терять при записи.

Одна большая таблица со словарем может однажды стать неуправляемой.

0 голосов
/ 13 ноября 2011

Посмотрите на шаблоны доступа, которые вам понадобятся. Кто-то из них, кажется, сделал особенно трудным или неэффективным мой выбор одного или другого?

Если не предпочитаете тот, который требует меньше столов

В этом случае:

  1. Добавить комментарий: вы либо выбираете конкретную таблицу много / много, либо вставляете в общую таблицу с известным определенным идентификатором того, что вам нравится, я думаю, что код клиента будет немного проще во втором случае.
  2. Поиск комментариев к элементу: здесь кажется, что использовать общую таблицу немного проще - у нас есть только один запрос, параметризованный по типу объекта
  3. Поиск комментариев человека об одном виде вещей: простой запрос в любом случае
  4. Найти все комментарии человека обо всех вещах: в любом случае это кажется немного грубым.

Я думаю, что ваш «дискриминированный» подход, вариант 2, в некоторых случаях дает более простые запросы, а в других не выглядит намного хуже, поэтому я бы с этим согласился.

0 голосов
/ 13 ноября 2011

насколько я понимаю. требуется несколько таблиц. Между ними существует связь между многими.

  • Таблица, в которой хранятся данные пользователя, такие как имя, фамилия, дата рождения, с полем идентификации.
  • Таблица, в которой хранятся типы данных. К этим типам могут относиться фотографии, акции, ссылки. каждый тип должен иметь уникальную таблицу. следовательно, существует связь между их отдельными таблицами и этой таблицей.
  • каждый отдельный тип данных имеет свою таблицу. например, обновления статуса, фотографии, ссылки.
  • последняя таблица для отношения многих ко многим хранит идентификатор, идентификатор пользователя, тип данных и идентификатор данных.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...