Дизайн базы данных социальных веб-приложений: как улучшить эту схему?

фон

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

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

Текущие Нужды

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

  • создание и изменение сведений о профиле и учетной записи настройки
  • пост, помечать и классифицировать их писать!--12-->
  • читать, комментировать и "любимые" сообщения других пользователей
  • "следуйте" другим пользователям, чтобы получать уведомления о своей деятельности
  • поиск и просмотр контента и получить предлагаемые сообщения / пользователей (хотя мы будем использовать сервер поиска Solr для индексации данных БД и запуска этих типов запросов)

- схемы

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

Schema Image

вопросы

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

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

2 ответов


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

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

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

ваши таблицы "многие ко многим" не нуждаются в дополнительном PK (e.g PostFavoriteID). Комбинированный первичный из обоих PostID и UserID было бы достаточно, так как PostFavoriteID никогда не используется нигде. Это касается всех таблиц join

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

как с prev. ответа, я не вижу advatanage или недостаток. Я!--18-->мая поместите оба в одну таблицу с NULL (или, может, лучше -1) значения не беспокоили бы меня.

есть ли причина, по которой я не должен объединять таблицу PostStats в стол "постов"?

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

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

вы используете схемы normalsied поэтому любые дополнения можно сделать в в любой момент.

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

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

должен ли я использовать более естественные первичные ключи, такие как Username вместо Имя пользователя или почтовый код вместо суррогатное LocationID в местах стол?

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

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

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


Я не понимаю, что происходит с вашими пользовательскими таблицами* - они настроены так, как будто они 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