Моделирование базы данных: Facebook как сообщения - PullRequest
7 голосов
/ 26 ноября 2010

Я пытаюсь имитировать что-то похожее на 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 (создание отношения родитель-потомок).

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»).

Как лучше всего решить эту проблему?

РЕДАКТИРОВАТЬ 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 ]

3 голосов
/ 27 ноября 2010

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

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

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

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

  4. Все ваши Id столбцы, PK, должны быть переименованы в TableId.У каждого должен быть Private DataType с тем же именем.Имя столбца используется без изменений везде, где оно существует, как FK.Единственное исключение - когда у вас есть два FK для одной родительской таблицы: там должно быть RoleTableId.

Как лучше всего решить эту проблему?

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

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

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

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

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

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

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

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

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

(Вы хотите расу (3 уровня) или 2 уровня в вопросе об этнической принадлежности?)

1 голос
/ 26 ноября 2010

Вы можете получить сообщение таблицы, а затем таблицы отношений n: m, т.е.

message_to_wall:
- messageID
- wallID

message_to_media:
- messageID
- mediaID

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...