2016-01-21 5 views
1

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

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

На том, как моя система будет работать:

  • Все участники (студенты или преподаватели) являются частью виртуального класса.
  • Учителя могут создавать задания и упражнения в этих классах и назначать их одному или нескольким ученикам (member_task таблица не показана).
  • Студент может запросить помощь для конкретной задачи или упражнения, отправив сообщение учителям классной комнаты.
    • Сообщения, отправленные студентами, отправляются всем учителям. Они не могут адресовать сообщение конкретному учителю.
    • Сообщения, отправленные учителями, могут быть адресованы одному или нескольким ученикам.
    • Студенты не могут отправлять сообщения другим студентам.
    • Сообщения ведут себя как чат, что означает, что частный разговор начинается между учеником и всеми учителями, когда они отправляют сообщение.

Вот ER диаграмма я сделал:

enter image description here

Так что мой вопрос, как эта таблица нормализована должным образом для моей цели? Есть ли что-то, что можно сделать для сокращения избыточности данных по моим таблицам? И из любопытства, это в BCNF?

Другой вопрос: я не намерен когда-либо реализовывать функции удаления в моей системе. Только «архивирование», когда указанная класс/задача/член/сообщение/все просто скрыто/деактивировано. Так есть ли какая-то причина для использования FK?

EDIT: Кроме того, мой знакомый привлек мое внимание, что стол Conversations может быть избыточным, и это похоже на это. Мысли?

Спасибо.

ответ

1

Единственное, что у меня есть, это то, что я не вижу таблицу Users, в которой будут храниться все данные о студентах и ​​преподавателях (логин, адрес электронной почты, идентификатор системы, роль и т. Д.), Но я предполагаю, что в нашей системе что-то похожее?

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

Members 
============= 
PK member_id 
FK class_id 
FK user_id 
-------------- 
join_date 
leave_date 
active 
role 

Последние два поля могут быть избыточными:

  • active: альтернативное решение, если вы хотите, чтобы избежать использования даты. Это станет false, когда пользователь перестанет быть членом этого класса.Поскольку функция удаления не существует, запись Members должна быть сохранена для целей архивации (и исторического журнала).
  • role: В зависимости от того, как вы устанавливаете таблицу и роли в вашей системе. Если у пользователя есть поле role, тогда это не нужно. Однако это поле позволяет одному и тому же пользователю принимать разные роли в разных классах. Пример: студент 3 курса, который был членом этого класса 2 года назад, теперь работает в качестве TA/LA (преподаватель/лаборант) для того же класса. Это зависит от того, как работает учреждение ... в моем BSc у нас было «правило»: любой, у кого есть grade > 8.5/10 на Java, мог добровольно провести семинары для других студентов (используя лаборатории Uni). Наконец, это поле, если оно используется в качестве маски или константы, допускает расширение ролей (в будущем)

Что касается FK, я всегда предлагаю использовать их для согласования данных. Вещи могут стать действительно уродливыми очень быстро без FK. Ограничения, которые они налагают, могут быть проработаны, и они обычно необходимы. Какова цель архивирования сообщения с sender_id, если отправитель был удален случайно? Также обратите внимание, что в большинстве систем индексируются FK, что повышает производительность запросов/соединений.

Надежда выше помогает и не запутать :)

+0

Спасибо за ваш вклад. Да, таблица 'members' имеет' id' PK, а также 'user_id' FK, который ссылается на идентификатор пользователя нашей веб-платформы. Таблица 'members' имеет свойство, которое определяет, является ли пользователь учителем или учеником. Вероятно, я также добавлю свойство 'active', чтобы отделить старые от текущих пользователей и, таким образом, также предотвратить удаление сообщений из каскада, если член случайно удаляется из класса. – Chris

+0

PS: Все еще интересно, какая нормальная форма моей схемы :) – Chris

2

В ответ на ваш акцент на «модифицируемость», который я везу в виду относительно применения и эволюции схемы на самом деле я собираюсь предложить довольно экстремальное решение. Перед этим некоторые замечания некоторые аспекты вы упомянули. Во-первых, внешние ключи представляют значимые ограничения в ваших данных. Их всегда следует определять и применять. Внешних ключей нет только для каскадного удаления. Во-вторых, таблица «Беседы», возможно, избыточна. Было бы разумно, если бы у вас было понятие «сеанс» чата, который бы соответствовал разговору. В противном случае у вас просто есть куча сообщений в течение всего времени. Таблица разговора также может включать взаимосвязь «многие-ко-многим» между сообщениями и задачами/упражнениями, если вы хотите, например, иметь чаты, которые одновременно охватывали несколько упражнений.

Теперь для крайнего предложения. Вы можете использовать 6NF. В частности, вы можете посмотреть на его воплощение в anchor modeling. Наиболее заметным отличием этого подхода является то, что каждый атрибут моделируется как другая таблица. 6NF поддерживает временные базы данных (поддерживается в привязном моделировании через «историзированные» атрибуты/связи). Это означает, что такие ситуации, как учащийся, связанный с задачей сейчас, но не позже, не заставят все их сообщения исчезнуть. Наиболее важными для вас, все модификации схемы являются неразрушающими и аддитивными, поэтому старый код не прерывается при внесении изменений.

Есть недостатки. Во-первых, это немного странно, и, в частности, привязка моделирования (несколько безвозмездно?) Представляет собой набор новых терминов. Во-вторых, он создает странные запросы для большинства реляционных баз данных, которые они могут не оптимизировать хорошо. Иногда это можно решить с помощью материализованных представлений. В-третьих, на физическом уровне каждый атрибут эффективно обнуляется. Наконец, инструментарий и поддержка, пока они представлены, довольно молоды. В частности, для MySQL вы можете быть «вдохновлены» тем, что предусмотрено на сайте моделирования якоря.

Что касается фактической модели базы данных, она будет выглядеть примерно аналогичной. Моделирование якоря использует термин «якорь» примерно для того же объекта, что и сущность, и «связывает» примерно то же, что и отношение. Для простоты, отбрасывая отношение «Беседа» (и, таким образом, напрямую связав сообщение с задачей), изображение будет похоже: у вас будет привязка к классу, члену, сообщению и задаче, а привязка, заменяющая Получателя, которую вы можете назвать ReceivedMessage, представляющая отношение "член получил сообщение сообщение". Атрибутами ваших объектов будут атрибутные узлы. Создание атрибута сообщения в хронологическом объявлении Message позволило бы редактировать сообщения, если это необходимо, и поддерживать историю изменений.

+0

Спасибо за ваш вклад. В таблице разговоров сохраняется «сеанс чата» или поток между преподавателем и учеником, поэтому я считаю, что имеет смысл сохранить его для этой цели. Но тот факт, что он фактически не содержит никаких данных, - это то, что, как мне кажется, беспокоит меня. Но я думаю, что нет ничего плохого в таблице, содержащей только ключи? Ваше предложение 6NF довольно экстремально. Определенно интересная концепция, но не соответствует остальной части нашей системы. Я думаю, что буду придерживаться 3,5 или ниже. – Chris

+1

Обычно таблицы, содержащие только внешние ключи, используются для обработки ограничений «многие-ко-многим», где их часто называют «[связывание таблиц] (https://en.wikipedia.org/wiki/Associative_entity)». Однако в случае сеанса в разговоре будет только одна Задача, поэтому она будет иметь отношение «много к одному» и может быть поглощена сообщением. Тем не менее, это, вероятно, лучше всего в виде отдельной таблицы, поэтому вы можете использовать поле автоматического увеличения или аналогично генерировать идентификаторы сеанса. –

Смежные вопросы