Я разработчик программного обеспечения. Я люблю кодировать, но ненавижу базы данных ... В настоящее время я создаю веб-сайт, на котором пользователю будет разрешено пометить объект как понравившийся (как в FB), пометить его и комментировать .
Я застрял в дизайне таблиц базы данных для обработки этой функции. Решение тривиально, если мы можем сделать это только для одного типа вещей (например, фотографий). Но мне нужно включить это для 5 разных вещей (на данный момент, но я также предполагаю, что это число может расти по мере роста всей службы).
Я нашел здесь несколько похожих вопросов, но ни на один из них нет удовлетворительного ответа, поэтому я задаю этот вопрос еще раз.
Вопрос в том, как правильно, эффективно и эластично спроектировать базу данных, чтобы она могла хранить комментарии для разных таблиц , лайки для разных таблиц и теги для них. Какой-нибудь шаблон дизайна в качестве ответа будет лучшим;)
Подробное описание : у меня есть таблица User
с некоторыми пользовательскими данными и еще 3 таблицы : Photo
с фотографиями , Articles
со статьями , Places
с местами . Я хочу разрешить любому зарегистрированному пользователю:
прокомментируйте любую из этих 3 таблиц
отметить любой из них как понравившийся
пометьте любой из них каким-нибудь тегом
Я также хочу подсчитать количество лайков для каждого элемента и количество раз, когда использовался этот конкретный тег.
1- й подход :
а) Для тегов , я создать таблицу Tag [TagId, tagName, tagCounter]
, то я буду создавать много-ко-многим отношения таблиц для: Photo_has_tags
, Place_has_tag
, Article_has_tag
.
б) То же самое относится к комментариям.
в) я создам таблицу 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)
и так далее ... Я думаю, что второй подход лучше, но я также чувствую, что в этом дизайне чего-то не хватает ...
Наконец, мне также интересно, где лучше всего хранить счетчик того, сколько раз понравился элемент. Я могу думать только о двух способах:
- в
Photo/Article/Place
таблице element ( ) - с помощью select count ().
Я надеюсь, что теперь мое объяснение вопроса более обстоятельно.
Ответы:
Наиболее расширяемое решение - иметь только одну «базовую» таблицу (связанную с «лайками», тегами и комментариями) и «наследовать» от нее все остальные таблицы. Добавление нового типа сущности включает в себя просто добавление новой «унаследованной» таблицы - затем она автоматически подключается ко всему подобному / tag / comment механизму.
Термин отношения сущностей для этого - «категория» (см. Руководство по методам ERwin , раздел «Отношения подтипов»). Символ категории:
Предполагая, что пользователю может нравиться несколько сущностей, один и тот же тег может использоваться для нескольких сущностей, но комментарий зависит от сущности, ваша модель может выглядеть следующим образом:
Кстати, есть примерно 3 способа реализовать «категорию ER»:
Если у вас нет очень строгих требований к производительности, третий подход, вероятно, является лучшим (это означает, что физические таблицы соответствуют 1: 1 объектам на диаграмме выше).
источник
BIGINT
- 9223372036854775807. Предполагая, что вы вставляете одну строку каждую секунду, вы исчерпаете доступные значения через ~ 300 миллиардов лет. Конечно, к тому времени вы сможете портировать на 128-битные целые числа!Если вы «ненавидите» базы данных, почему вы пытаетесь их реализовать? Вместо этого попросите помощи у того, кто любит это и дышит этим.
В противном случае научитесь любить свою базу данных. Хорошо спроектированная база данных упрощает программирование, проектирование сайта и упрощает его дальнейшую работу. Даже у опытного d / b-дизайнера не будет полного и идеального предвидения: некоторые изменения схемы потребуются в будущем по мере появления шаблонов использования или изменения требований.
Если это проект одного человека, запрограммируйте интерфейс базы данных на простые операции с использованием хранимых процедур: add_user, update_user, add_comment, add_like, upload_photo, list_comments и т. Д. Не встраивайте схему даже в одну строку кода. Таким образом, схему базы данных можно изменить, не затрагивая какой-либо код: о схеме должны знать только хранимые процедуры.
Возможно, вам придется несколько раз реорганизовать схему. Это нормально. Не беспокойтесь о том, чтобы сделать это идеально с первого раза. Просто сделайте его достаточно функциональным, чтобы создать прототип первоначального дизайна. Если у вас есть возможность потратить время, используйте его, а затем удалите схему и повторите попытку. Это всегда лучше второй раз.
источник
Это общая идея, пожалуйста, не обращайте особого внимания на стили имен полей, а больше на отношения и структуру
Этот псевдокод получит все комментарии к фотографии с ID 5
SELECT * FROM actions
WHERE 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"
источник
SELECT * FROM actions WHERE actions.id=133 AND actions.typeStuff = "comment" AND actions.typeAction = "like"
id_stuff
столбец будет содержать уникальные значения в каждой из трех таблиц?насколько я понимаю. требуется несколько таблиц. Между ними существует связь "многие ко многим".
источник
Посмотрите на шаблоны доступа, которые вам понадобятся. Кажется ли что-нибудь из них особенно сложным или неэффективным, когда я выбрал тот или иной дизайн?
Если нет, отдайте предпочтение тому, для которого требуется меньше таблиц
В этом случае:
Я думаю, что ваш «дискриминированный» подход, вариант 2, в некоторых случаях дает более простые запросы и не кажется намного хуже в других, поэтому я бы пошел с ним.
источник
Рассмотрите возможность использования таблицы для каждой сущности для комментариев и т. Д. Больше таблиц - лучшее сегментирование и масштабирование. Управлять множеством похожих таблиц для всех известных мне фреймворков - не проблема.
Однажды вам нужно будет оптимизировать чтение из такой структуры. Вы можете легко создать сводные таблицы поверх базовых и немного потерять при записи.
Одна большая таблица со словарем может однажды выйти из-под контроля.
источник
Определенно выберите второй подход, когда у вас есть одна таблица и храните тип элемента для каждой строки, это даст вам гораздо больше гибкости. В принципе, когда что-то логически можно сделать с меньшим количеством таблиц, почти всегда лучше использовать меньшее количество таблиц. Одно из преимуществ, которое приходит мне на ум прямо сейчас в вашем конкретном случае, учитывая, что вы хотите удалить все понравившиеся элементы определенного пользователя, с вашим первым подходом вам нужно выполнить один запрос для каждого типа элемента, но со вторым подходом это можно сделать только с одним запросом или подумайте, когда вы хотите добавить новый тип элемента, с первым подходом он включает создание новой таблицы для каждого нового типа, но со вторым подходом вы ничего не должны делать ...
источник