BCNF и 4NF для базы данных

Итак, я начал с этих трех таблиц, и мне сказали изменить их в BCNF и 4NF:

PRIVATE_SESSION (Тренер, Телефон, Электронная почта, Плата, ClientLastName, ClientFirstName, ClientPhone, ClientEmail, Дата, Время)

CLUB_MEMBERSHIP (ClientNumber, ClientLastName, ClientFirstName, ClientPhone, ClientEmail, MembershipType, EndingDate, Street, City, State, Zip)

КЛАСС (имя класса, тренер, дата начала, дата окончания, стоимость)

* Также предложите новую таблицу для отслеживания клиентов, подписки на классы и уплаченной суммы, сохраняя при этом все в BCNF и 4NF.

=================================================================

Итак, я превратил их в эти 7 таблиц, чтобы попытаться соответствовать BCNF и 4NF. Вопрос в том... это хотя бы отдаленно правильно? Определение BCNF удовлетворяется, если каждый детерминант является ключом-кандидатом, что, похоже, так и есть. Я считаю, что 4NF удовлетворяется, если он не содержит многозначных зависимостей... и я попытался разделить таблицы, чтобы они не

ТРЕНЕР

ID (primary key),
TrainerLastName,
TrainerFirstName,
TrainerEmail,
TrainerPhone

TRAINER_SESSION

ID (primary key),
ID (foreign key from CLIENT_INFO.ID)
TrainingStartTime,
TrainingStartDate,
TrainingFee

CLIENT_INFO

ID (primary key),
ClientLastName,
ClientFirstName,
ClientPhone,
ClientEmail,

MEMBER_ADDRESS

ID (primary key),
ID (foreign key to CLIENT_INFO.ID),
State,
City,
Street,
Zip

ЧЛЕНСТВО_INFO

ID (primary key),
ID (foreign key to CLIENT_INFO.ID),
MembershipType,
MembershipStartDate,
MembershipEndDate

CLUB_CLASS

ID (primary key),
TrainerID (foreign key to  TRAINER.ID),
ClassName,
ClassStartDate,
ClassEndDate,
ClassCost

CLASS_ENROLLMENT

(ClassID, MemberID) composite primary keys
TotalClasses,
TotalPaid

person user2503165    schedule 19.06.2013    source источник
comment
Почему TRAIN_SESSION содержит TrainerFirstName, TrainerLastName? (то же самое касается CLUB_CLASS) Из-за этого мне он не кажется 2nf.   -  person Matthew    schedule 20.06.2013
comment
Потому что я был глуп и неправильно скопировал то, что сделал раньше. Конечно, это относится только к этим двоим… все остальное было… или, скорее, ошибкой.   -  person user2503165    schedule 20.06.2013
comment
Не вижу смысла в CLASS_EXPENSE. Во-первых, исходные таблицы не моделируют эти данные — предполагается ли добавлять новые концепции в исходную модель? Во-вторых, вместо того, чтобы хранить совокупные данные напрямую (AmountofClassesTaken, TotalAmountPaid), вы должны смоделировать Class_Member_Enrollment (ClassID, MemberID) и суммировать эти записи, чтобы получить итоги.   -  person mbeckish    schedule 20.06.2013
comment
Ах, извините, я забыл добавить, что мы также должны были предложить новую таблицу для отслеживания клиентов, подписки на классы и уплаченной суммы, сохраняя при этом все в BCNF и 4NF. Хотя мне нравится идея составного ключа :D   -  person user2503165    schedule 20.06.2013
comment
@ user2503165 - Итак, вторая часть моего комментария остается в силе - вы не моделируете, какие участники зачислены в какие классы.   -  person mbeckish    schedule 20.06.2013
comment
Если я понимаю, куда вы идете, вы имеете в виду изменить его на CLASS_MEMBER_ENROLLMENT(ClassID,MemberID) ‹ - составные первичные ключи и что-то вроде ClassSum, а также Total Amount?   -  person user2503165    schedule 20.06.2013
comment
Нет, вам не нужно отслеживать количество пройденных занятий или общую стоимость. Каждая запись в CLASS_MEMBER_ENROLLMENT записывает один экземпляр члена, посещающего класс. Так что, если вы подсчитаете эти записи, вы узнаете, сколько уроков посещал участник. Вы можете использовать ClassID для присоединения к CLUB_CLASS, где вы можете получить CLUB_CLASS.ClassCost.   -  person mbeckish    schedule 20.06.2013
comment
Правильно ли это: Покажите этапы вашей работы, следуя вашему справочнику/учебнику, с обоснованием - не все термины/обозначения являются стандартными, и мы не знаем точно, какому алгоритму/методу вы следуете, и мы хотим проверить вашу работу, но не переделывать и нам нужен ваш выбор, когда процесс позволяет их и в противном случае мы не можем сказать вам, где вы сделали правильно или неправильно, и мы не хотим переписывать ваш учебник. См. раздел Как задать вопрос, нажмите "Домашнее задание stackexchange" и наведите указатель мыши на текст со стрелкой голосования. Если вы не уверены, что это правильно, задайте 1 конкретный исследовательский вопрос, не повторяющийся, о том, где вы застряли.   -  person philipxy    schedule 02.08.2020


Ответы (1)


Для более поздней версии предложенной схемы (редакция 11)

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

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

Информация о членстве и адрес участника получили два столбца под названием ID, что сбивает с толку. Предположительно, второй должен быть помечен как Client ID в каждой таблице (это было бы более разумно). Теперь возникает вопрос: «Какова мощность отношений между информацией о членстве и информацией о клиенте, а также между адресом участника и информацией о клиенте?» Что касается адресов, может ли член существовать без указания адреса? Может ли член иметь два или более адресов? Если ответ на любой из этих вопросов «да», то с дизайном все в порядке. Если ответ «нет», неясно, нужны ли вам и информация о клиенте, и адрес участника. Аналогично с информацией о членстве и информации о клиенте.

Trainer Session имеет два поля ID. Второй предположительно является идентификатором клиента, но ему также требуется идентификатор тренера, чтобы определить, какой тренер провел сеанс.

Для оригинальной версии предложенной схемы (редакция 6)

Или "близкая к исходной" версия предложенной схемы.

Вы явно не создали декомпозицию без потерь, поскольку элемент «имя класса» отсутствует.

Таблица Class Expense не имеет аналога в исходных таблицах.

Неясно, гарантируется ли таблица Trainer исходными таблицами, хотя я согласен с большинством полей. Однако атрибут Fee здесь неуместен.

В таблице Train Session отсутствуют атрибуты, в большей или меньшей степени, как бы вы ни нарезали и не разрезали вещи. Если он предназначен для представления частных сеансов, вам не хватает идентификатора тренера, идентификатора клиента и платы. Если он предназначен для общих (клубных) сеансов, вам нужна таблица, в которой записываются частные сеансы.

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

Я думаю, что стол Club Class в порядке.

Занятия существуют и проводятся тренерами, но никто никогда не регистрируется как посещающий занятия.

person Jonathan Leffler    schedule 20.06.2013
comment
Я вернулся и сделал кучу правок, хотя есть большая вероятность, что я что-то напутал еще больше. Идея с разными таблицами (Client_INFO, MEMBER_ADDRESS и MEMBER_INFO) заключалась в том, чтобы разделить некоторые многозначные зависимости... но я не упомянул, что для того, чтобы иметь сессию частного тренера, вы должны быть членом клуба, но это просто дополнительная опция. Клубные занятия (также известные как классы) также требуют членства, но я считаю частные занятия и занятия на объектах разными вещами. - person user2503165; 20.06.2013
comment
Или другими словами... Когда человек регистрируется и становится членом этого Клуба, перед ним открываются две возможности. Они могут либо нанять независимого личного тренера за символическую плату в свое свободное время (Trainer_Session)... или они могут пройти курс, предлагаемый клубом и теми же тренерами за другую плату (Club_class). - person user2503165; 20.06.2013
comment
Я знаю, и мне действительно очень жаль, что я продолжаю пересматривать его, но я не хотел, чтобы он занимал 10000000000 строк страницы. Итак, переходя к CLIENTINFO и MEMBERADDRESS, причина, по которой я разделил их, заключалась в том, что я предполагал, что там будет многозначная зависимость. Для ИНФОРМАЦИИ О ЧЛЕНСТВЕ я сделал отдельную таблицу для ИНФОРМАЦИИ О ЧЛЕНСТВЕ, потому что (на мой взгляд) членство в клубе логически не сочеталось с общими данными о клиенте, даже если там есть косвенная связь. Не лучше ли просто объединить эти таблицы? - person user2503165; 20.06.2013
comment
Продолжая то, что вы сказали ранее ... конечно, у меня мог бы быть человек без адреса, но насколько вероятен сценарий, который был бы на самом деле? Это похоже на лейкопластырь - person user2503165; 20.06.2013
comment
Я понимаю необходимость редактирования схемы, но это также усложняет процесс ответа. Ссылки на исправления — это новинка (я не делал этого раньше и не видел, чтобы кто-то еще делал это), но они помогают тем, кто придет позже, понять, о чем я говорил. Для бизнеса: я думаю, что большинство клубов, вероятно, будут настаивать на адресе. Разделение таблиц, которые должны быть соединены 1:1 (не 0-или-1:0-или-1 или что-то в этом роде), обычно только усложняет жизнь без какой-либо пользы. (Исключение: если у вас есть большой столбец — BLOB или аналогичный — то, возможно, лучше хранить его отдельно, но это физический дизайн.) - person Jonathan Leffler; 20.06.2013
comment
Ах, тогда я, скорее всего, вернусь назад и объединим их, чтобы сделать его немного лучше, даже если это противоречит моей собственной логике. Частично потому, что это правда... я думаю, что дополнительная таблица делает ее более сложной, чем нужно. Тем не менее, я сделаю это позже, так что спасибо за всю помощь :) - person user2503165; 20.06.2013