Моделирование базы данных: 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 ответов
во-первых, несколько ответов на небольшие вопросы, чтобы держать вас на прямом и узком пути реляционных баз данных и проектирования БД.
вся идея состоит в том, чтобы разместить как можно больше правил прямо в базе данных, в одном месте и не в коде. Почти все можно сделать через ограничения DDL: FK;
CHECK
ограничения; иRULES
(все требования ISO/IEC / ANSI SQL). Затем все пользователи (ваше приложение является пользователем) могут видеть все правила и понимать лучшему базе. Это защищает БД, независимо от того, какой клиент используется для выполнения кода. Поставщики БД (то есть коммерческие, а не бесплатные) реализация этих ограничений более надежна, чем код.требование (не Соглашение) для вставки строк в дочернюю таблицу заключается в том, что родительская строка должна существовать первой. Это то, что делает ограничение FK, оно гарантирует, что родительская строка существует. В таблице "многие ко многим" обе родительские строки должны существовать до дочернего элемента (с двумя ключами, один для каждого родителя) может быть вставлен.
types_id
ужасная идея, потому что вы нарушили правила проектирования и удалили возможность RI. Лучше иметь отдельные столбцы с ri (ограничения FK для каждого родителя). (Но есть еще лучший способ.)все
Id
столбцы, PKs, должны быть переименованыTableId
. Каждый должен иметь частный тип данных с тем же именем. Имя столбца используется без изменений, где бы оно ни находилось существует, как ФК. Единственным исключением является то, где у вас есть два FKs в одной родительской таблице: там должно бытьRoleTableId
.
что бы быть лучший способ решить эту проблему?
нормализуется. И у вас будут проблемы, которые подвергаются, которые вам нужно решить. Поэтому Нормализуйте снова. И продолжайте делать это, пока у вас нет проблем для решения.
-
ваша одиночная таблица сообщений уже наполовину там. Вы интуитивно нормализовали две таблицы в одну. Но есть проблемы, которые нужно решить, так что давайте с ними разберемся.
- Себастьян предоставил две таблицы "многие ко многим", поэтому я не буду повторять.
.
- Себастьян предоставил две таблицы "многие ко многим", поэтому я не буду повторять.
-
прежде чем вы решите, что это окончательно (и, следовательно, две таблицы "многие ко многим" являются окончательными), я предлагаю вам нормализовать
Wall
иMedia
. Мне кажется, что есть много общих столбцов. Если вы нормализуете это, вы получите один стол. Поскольку это вещь, которая выставлена или обставленаPerson
С целью приглашенияMessages
, и тип может быть{ Photo | Album | Mailbox | Wall }
, Я бы назвал этоPersonFurniture
илиPersonObject
.- если это заканчивается как одна таблица, то вам не понадобятся две таблицы "многие ко многим", только одна.
ответы на комментарии
- легче и быстрее нарисовать модель, чем печатать долго обсуждения. Я обдумал большинство ваших вопросов. Пожалуйста, проверьте это и задайте конкретные вопросы о том, что вы не понимаете.
ссылка на модель данных социальной сети (стр. 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. Вы можете хранить все эти комментарии прямо на стене или мультимедийные документ. Таким образом, у вас нет всех необходимых запросов на соединение, а комментарии связаны с медиа или стеной.