Проблема моделирования данных: слабый объект, принадлежащий двум несвязанным таблицам

#database-design

#проектирование базы данных

Вопрос:

Предположим, у меня есть следующие таблицы: «Пользователь», «Компьютер» и «Команда». Пользователи и компьютеры могут иметь 0 или 1 команды, связанные с ними. Команда всегда принадлежит одной (и только одной) из этих двух. Как я могу это смоделировать?

Я думал о чем-то подобном этому:

 user(id, command_id?, other1)
computer(id, command_id?, other2)
command(id, other3)
  

Это гарантирует, что пользователь / компьютер может иметь 0 или 1 команду, но позволяет команде иметь более одного владельца.

Но поскольку command является слабой сущностью (я полагаю, пожалуйста, поправьте меня, если я ошибаюсь), она должна ссылаться на своего владельца во внешнем ключе. Это приводит к следующей структуре:

 user(id, other1)
computer(id, other2)
command(id, owner_id, owner_type(user|computer), other3)
  

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

Предложения?

Ответ №1:

Вы можете использовать специализацию.

 User(id,other1)
Computer(id,other2)
Command(id,other3)

User_cmd(user_id,cmd_id)
Comp_cmd(comp_id,cmd_id)
  

Ответ №2:

Я не верю, что есть хороший способ сделать это с помощью стандартного SQL. Возможно, существует СУБД, которая предоставляет хорошее решение, о котором я просто не знаю.

Я видел, как оба ваших решения использовались в прошлом. Мне действительно не нравится второе решение, потому что вы не можете использовать истинные отношения FK. При определении ограничения FK таблица должна быть указана. Однако таблица определяется тем, что находится в столбце owner_type. Кроме того, если был определен третий тип владельца, вы должны ввести другую строку для представления вашей модели. Это начинает становиться беспорядочным.

Я предпочитаю первое решение, но с логическим столбцом is_owned в таблице команд. Это поле сообщает мне, владеет ли кто-то уже командой. Недостатком является то, что я не знаю, кому принадлежит команда, просто взглянув на запись команды. Положительным моментом является то, что я могу определить истинное ограничение FK, и если у меня когда-либо будет третий owner_type, я могу просто добавить дополнительную таблицу без каких-либо изменений в существующих моделях.

Ответ №3:

Похоже, что домен command — это множество, представляющее собой объединение users и computers . Вы могли бы добавить искусственный объект, представляющий этот набор, такой как command_owner :

 user(id, other1)
computer(id, other2)
command(id, other3)
command_owner(id, user_id, computer_id, command_id)
  

Вам понадобятся ограничения уникальности для command_id , user_id и computer_id в этой таблице. Но это вводит новый граничный случай, когда строка может быть computer_id и user_id указана, что, я думаю, не разрешено вашей моделью. Для обеспечения этого вам понадобится какое-то внемодельное правило, например триггер или программное ограничение.