Реализация комментариев и комментариев в базе данных

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

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

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

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

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

  • комментарий к любой из этих трех таблиц

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

  • пометить любой из них некоторым тегом

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

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 nd:

Я создам таблицу 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)

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

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

  • в элементе (Photo/Article/Place) table
  • выбрав count().

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

Ответ 1

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

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

Category

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

ER Diagram


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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

enter image description here

Этот псевдокод получит все комментарии к фотографии с ID 5
  SELECT * FROM действия
  WHERE actions.id_Stuff = 5
  И actions.typeStuff = "фото"
  И actions.typeAction = "комментарий"

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

SELECT * FROM actions  
WHERE actions.id_Stuff = 5  
AND actions.typeStuff="photo"  
AND actions.typeAction = "like"  

Ответ 4

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

Ответ 7

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

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

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