#mysql #database #database-design #constraints #relationship
Вопрос:
У меня есть следующая схема базы данных, которую я придумал:
Таблицы:
сотрудники(id_pk, имя)
employees_attend_at_service_desk(employee_id_pk_fk, service_desk_id_pk_fk не является нулевым) ссылается на сотрудника и службу поддержки
service_desk(id_pk, имя, shop_id_fk не является нулевым) ссылается на магазин
работы(employee_id_pk_fk,shop_id_pk_fk не являются нулевыми) ссылаются на магазин и сотрудника
магазин(id_pk, идентификатор компании не равен нулю)
компания(id_pk, название)
Эта база данных будет запрашиваться с веб-сайта и из настольного приложения.
Поэтому примите во внимание этот пример: в магазине 1 есть служба поддержки 1 и 2, а в магазине 2 есть служба поддержки 3. Сотрудник 1 работает только в цехе 1.
Я хочу приписать службу поддержки из магазина 1 сотруднику 1, но я хочу добавить какое-то ограничение, которое не позволит мне добавить службу поддержки 3, например, потому что эта служба поддержки принадлежит магазину 2, а сотрудник 1 работает только в магазине 1. Является ли тринарная связь единственным способом получить то, что мне требуется при рассмотрении дизайна базы данных?
То, о чем я думал, — это запросить базу данных, чтобы получить всех сотрудников магазина 1, а затем снова запросить базу данных, чтобы узнать service_desks магазина. Затем я могу распределить сотрудников магазина 1 по соответствующим сервисным заданиям.
Выполнение этого таким образом означает, что база данных не очень надежна? Или этот дизайн в порядке? И мое приложение может справиться с необходимыми мне ограничениями?
Заранее большое всем спасибо!
Комментарии:
1. Возможно, вам будет интересно прочитать о en.wikipedia.org/wiki/Fifth_normal_form
2. Спасибо, что указали мне на эту статью. Вы указали мне на эту статью, потому что я разбиваю свою схему БД на множество таблиц? И, возможно, вместо того, чтобы иметь так много сущностей, я мог бы иметь меньше? Например, вместо того, чтобы иметь службу поддержки, я, возможно, мог бы сделать что-то подобное? сотрудник(id_pk, имя, service_desk_number)… Еще раз спасибо!
3. Нет, только то, что в основе правила принудительного применения, которое вы пытаетесь реализовать, лежит теория отношений. И вы не должны верить людям, которые утверждают, что правила нормализации выше 3-й нормальной формы не нужны.
Ответ №1:
Один из вариантов состоит в том, чтобы:
- добавить
shop_id_pk_fk
кemployees_attend_at_service_desk
- Добавьте
employees_attend_at_service_desk (shop_id_fk)
ссылку на внешний ключshop (id_pk_)
- Создайте уникальный ключ
service_desk (id_pk, shop_id_fk
. (Требуется для шага 4). - Добавьте внешний ключ для
employees_attend_at_service_desk (service_desk_id_pk_fk, shop_id_fk)
ссылкиservice_desk (id_pk, shop_id_fk)
, чтобы убедиться, что для службы поддержки введен допустимый магазин. - Добавьте
employees_attend_at_service_desk (employee_id_pk_fk, shop_id_fk)
ссылку на внешний ключworks (employee_id_pk_fk, shop_id_pk_fk)
Это приведет к дублированию некоторых данных, но только одного столбца int, и будет означать, что вы можете создать необходимые ограничения, чтобы убедиться, что у вас есть действительный сотрудник в службе поддержки.
Вы также можете оставить проверку на усмотрение вашего приложения. Я не думаю, что это особенно плохая практика в любом случае.
Комментарии:
1. Привет, большое спасибо, что нашли время ответить на мой вопрос. Но на шаге 1 разве это не создаст тринарные отношения? Поскольку при добавлении shop_id_pk_fk в employees_attend_at_service_desk у меня будет: employees_attend_at_service_desk(employee_id_pk_fk, service_desk_id_pk_fk не равно нулю, shop_id_pk_fk) ссылки на сотрудника и службу поддержки и магазин … верно?
2. И да, и нет. Он имеет 3 базовых отношения в
service_desk
иshop
иemployee
, но это не единственные ограничения. Они даже не требуются (но все равно хорошая идея). Составные ключи ссылаютсяservice_desk
иworks
выполняют здесь тяжелую работу, и являются единственными необходимыми отношениями, например, пример на db-fiddle . Так что да, есть 3 основных отношения, но имеют значение только два.3. Вам не обязательно строго использовать внешний ключ, определенный на шаге 2. С помощью внешнего ключа, который вы добавляете на шаге 4, вы можете ссылаться только на допустимые пары сервисных центров и магазинов, и, естественно, в таблице service desk все еще будет внешний ключ для магазина, гарантирующий, что идентификатор магазина действителен.
4. Большое спасибо @GarethD. Я приму ваш ответ, поскольку он помог мне в дальнейшем понимании всей рассматриваемой проблемы. Возможно, я буду использовать свое приложение для проверки необходимых мне ограничений, так как это уменьшит сложность базы данных.