Моделирование базы данных: Facebook как сообщения

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

===========================
wall_message
===========================
- id (PK)
- parent_id (FK)
- wall_owner_profile_id (FK, identify whose wall the message is for)
- poster_profile_id (FK)
- message
- timestamp

===========================
media_message
===========================
- id (PK)
- parent_id (FK)
- media_id (FK, identify which photo, video, etc.)
- poster_profile_id (FK)
- message
- timestamp

parent_id позволяет "группировать" сообщения в соответствующее обсуждение. Первое сообщение parent_id будет 0, а последующие сообщения будут иметь PK как parent_id value (создание отношения "родитель-потомок").

poster_profile_id определяет, кто выложил сообщение.

выше две таблицы очень похожи. Было бы неплохо объединить их, например:

===========================
message
===========================
- id (PK)
- parent_id (FK)
- type (ENUM: "wall", "media", etc.)
- types_id (FK, see explanation below)
- poster_profile_id (FK)
- message
- timestamp

в этом случае, если, скажем, type - это "стена", потом types_id равно "wall_owner_profile_id" первой таблицы. Если, скажем,type это "медиа", затем types_id равно второй таблице media_id.

я немного обеспокоен тем, что второй подход требует столбца для объяснения значения другого столбца. Недостаток в этом, я предположим, что для types_id не будет ссылочной целостности (в отличие от "wall_owner_profile_id" и "media_id").

что бы быть лучший способ решить эту проблему?

EDIT 1:

кажется, что это решение до сих пор:

===========================
message
===========================
- message_id (PK)
- parent_message_id (FK)
- profile_id (FK, referring to who posted the message)
- message
- subject (applicable only for emails)
- timestamp

===========================
wall_message
===========================
- message_id (FK)
- profile_id (FK, referring to who received the message/owner of wall)

===========================
media_message
===========================
- message_id (FK)
- media_id (FK)

===========================
email_message
===========================
- message_id (FK)
- profile_id (FK, referring to who received the message)

2 ответов


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

  1. вся идея состоит в том, чтобы разместить как можно больше правил прямо в базе данных, в одном месте и не в коде. Почти все можно сделать через ограничения DDL: FK;CHECK ограничения; и RULES (все требования ISO/IEC / ANSI SQL). Затем все пользователи (ваше приложение является пользователем) могут видеть все правила и понимать лучшему базе. Это защищает БД, независимо от того, какой клиент используется для выполнения кода. Поставщики БД (то есть коммерческие, а не бесплатные) реализация этих ограничений более надежна, чем код.

  2. требование (не Соглашение) для вставки строк в дочернюю таблицу заключается в том, что родительская строка должна существовать первой. Это то, что делает ограничение FK, оно гарантирует, что родительская строка существует. В таблице "многие ко многим" обе родительские строки должны существовать до дочернего элемента (с двумя ключами, один для каждого родителя) может быть вставлен.

  3. types_id ужасная идея, потому что вы нарушили правила проектирования и удалили возможность RI. Лучше иметь отдельные столбцы с ri (ограничения FK для каждого родителя). (Но есть еще лучший способ.)

  4. всеId столбцы, PKs, должны быть переименованы TableId. Каждый должен иметь частный тип данных с тем же именем. Имя столбца используется без изменений, где бы оно ни находилось существует, как ФК. Единственным исключением является то, где у вас есть два FKs в одной родительской таблице: там должно быть RoleTableId.

что бы быть лучший способ решить эту проблему?

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

  1. ваша одиночная таблица сообщений уже наполовину там. Вы интуитивно нормализовали две таблицы в одну. Но есть проблемы, которые нужно решить, так что давайте с ними разберемся.

    • Себастьян предоставил две таблицы "многие ко многим", поэтому я не буду повторять.
      .
  2. прежде чем вы решите, что это окончательно (и, следовательно, две таблицы "многие ко многим" являются окончательными), я предлагаю вам нормализовать Wall и Media. Мне кажется, что есть много общих столбцов. Если вы нормализуете это, вы получите один стол. Поскольку это вещь, которая выставлена или обставлена Person С целью приглашения Messages, и тип может быть{ Photo | Album | Mailbox | Wall }, Я бы назвал это PersonFurniture или PersonObject.

    • если это заканчивается как одна таблица, то вам не понадобятся две таблицы "многие ко многим", только одна.

ответы на комментарии

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

ссылка на модель данных социальной сети (стр. 3)

ссылка на обозначение IDEF1X для тех, кто не знаком со стандартом реляционного моделирования.

  • выбрать свои собственные имена таблиц и столбцов
  • Message.Subject можно установить в CHAR(0) или игнорировать, если это не электронная почта.
  • это wall_message и email_message идентичны is не проблема, я нормализовал их в одну таблицу
  • ли wall_message или email_message или media_message вопрос в том, куда он "отправляется", верно ? Вы можете легко запретить любую функцию (например. группировка) для любого типа сообщения с помощью ограничения CHECK.
  • вы не ответили (2) выше
  • я думаю, что группировка сообщений отличается от медиа-группировки: подумайте о том, когда фотоальбом имеет список сообщений на нем.
  • ничего не проблема, вся идея моделирования, бумага дешева; вся идея реляционных dbs, чтобы сделать как можно больше, используя ограничения, проверки, правила. Если что-то не так, мы можем это изменить.

(вы хотите расу (3 уровня) или 2 уровня в вашем этническом вопросе ?)


у вас может быть сообщение таблицы, а затем N: M таблицы отношений, т. е.

message_to_wall:
- messageID
- wallID

message_to_media:
- messageID
- mediaID

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

это, конечно, технически позволит ему разместить сообщение на стене и на медиа-элементе (фото и т. д.). Поэтому вы не можете легко ограничить это.

в противном случае-если вам действительно не нужна реляционная база данных, вы можете подумать об использовании базы данных NoSQL, такой как CouchDB или В MongoDB. Вы можете хранить все эти комментарии прямо на стене или мультимедийные документ. Таким образом, у вас нет всех необходимых запросов на соединение, а комментарии связаны с медиа или стеной.