Проектирование базы данных социальных веб-приложений: как я могу улучшить эту схему? - PullRequest
11 голосов
/ 02 октября 2010

Фон

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

База данных MySQL, а приложение написано на PHP.Я еще не уверен, будем ли мы использовать библиотеку ORM или писать запросы SQL с нуля в приложении.Кроме веб-приложения, поисковый сервер Solr и, возможно, какой-нибудь клиент обмена сообщениями будут взаимодействовать с базой данных.

Текущие потребности

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

  • Создать и изменить данные профиля и настройки учетной записи
  • Публиковать, отмечать и классифицировать свои записи
  • Читайте, комментируйте и «добавляйте» посты других пользователей
  • «Следите» за другими пользователями, чтобы получать уведомления об их активности
  • Ищите и просматривайте контент и получайте предлагаемые посты / пользователей (хотя мы будемиспользовать поисковый сервер Solr для индексации данных БД и выполнения запросов такого типа)

Схема

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

Schema Image

Вопросы

  1. В общем, что-то я делаю неправильно или могу улучшить?
  2. Есть ли какие-либопричина, по которой я не должен объединять таблицу ExternalAccounts в таблицу UserProfiles?
  3. Есть ли причина, по которой мне не следует объединять таблицу PostStats в таблицу Posts?
  4. Должен ли я расширить дизайнвключить функции, которые мы делаем во второй версии, просто чтобы убедиться, что исходная схема может поддерживать ее?
  5. Могу ли я что-нибудь сделать, чтобы оптимизировать дизайн БД для индексации / производительности Solr / что угодно?
  6. Должен ли я использовать более естественные первичные ключи, например Имя пользователя вместо UserID, или zip / код зоны вместо суррогатного LocationID в таблице Locations?

Спасибо за помощь!

Ответы [ 2 ]

3 голосов
/ 02 октября 2010

В целом, что-то я делаю неправильно или могу улучшить?

В целом, я не вижу больших недостатков в вашей текущей настройке или схеме.

Что мне интересно, так это ваше разделение на 3 пользовательских таблицы.Я понимаю, что вы хотите, чтобы у вас были намерения (разные вещи, связанные с пользователем), но я не знаю, пойду ли я с той же самой вещью.Если вы планируете отображать на сайте только данные из таблицы User, это нормально, поскольку другая информация не требуется несколько раз на одной странице, но если пользователям необходимо использовать свое настоящее имя и отображать свое настоящее имя (например,John Doe вместо doe55), это замедлит процесс, когда данные станут больше, поскольку вам может потребоваться объединение.Наличие Preferences отдельно кажется личным выбором.У меня нет аргументов ни за, ни против.

Вашим таблицам «многие ко многим» не потребуется дополнительный PK (например, PostFavoriteID).Комбинированных первичных значений PostID и UserID будет достаточно, поскольку PostFavoriteID никогда не используется где-либо еще.Это относится ко всем таблицам соединения

Есть ли какая-либо причина, по которой мне не следует объединять таблицу ExternalAccounts в таблицу UserProfiles?

Как и в предыдущем случае.ответьте, я не вижу адванации или недостатка.Я могу поместить оба в одну и ту же таблицу, так как значения NULL (или, может быть, лучше -1) меня не будут беспокоить.

Есть ли причина, почему я не долженt объединить таблицу PostStats в таблицу Posts?

Я бы поместил их в ту же таблицу, используя триггер для обработки приращения таблицы ViewCount

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

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

Есть ли что-нибудь, что я могу сделать, чтобы оптимизировать дизайн БД для индексации / производительности Solr, чего угодно?

Не могу сказать, еще не сделал, ноЯ знаю, что Solr очень мощный и гибкий, поэтому я думаю, что у вас все должно быть в порядке.

Должен ли я использовать более естественные первичные ключи, такие как Имя пользователя вместо UserID или код zip / area вместосуррогатное LocationID в таблице Locations?

В SO обсуждается это много потоков.Лично мне больше нравится суррогатный ключ (или другой уникальный числовой ключ, если таковой имеется), поскольку он делает запросы более легкими и быстрыми, так как ищется int.Если вы разрешите изменить имя пользователя / адрес электронной почты / что-нибудь еще, чем ваш-PK-, то требуются значительные обновления.С суррогатным ключом вам не нужно беспокоиться.

Я бы также добавил, чтобы добавить такие вещи, как created_at, last_accessed at (лучше всего сделать с помощью триггеров или процедур IMO), чтобы получить некоторую статистикууже доступно.Это может действительно дать вам ценную статистику

Дальнейшие стратегии для увеличения производительности могут быть такими, как memcache, counter cache, многораздельные таблицы, ... Такие вещи могут обсуждаться, когда вы действительно перегружены пользователями, потому что могут бытьвещи / технологии / техники / ... которые очень специфичны для вашей проблемы.

1 голос
/ 03 октября 2010

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

Значения ExternalAccounts и UserSettings могут быть дополнительно нормализованы (в этом случае они будут 1-ко-многим!), Что даст вам более удобную конструкцию - вам не нужно будет добавлять дополнительные столбцы к вашемусхема для дополнительных внешних учетных записей или типов уведомлений (хотя это может быть менее масштабируемым с точки зрения производительности).

Например:

ExternalAccounts
    UserId int,
    AccountType varchar(45),  
    AccountIdentifier varchar(45)

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

UserSettings
    UserId int,  
    NotificationType varchar(45),  
    NotificationFlag ENUM('on','off')

hth

...