Владельцы одного лица и владельцы группы лиц.Ограничения или отношения? - PullRequest
0 голосов
/ 07 февраля 2019

Легкая модель.Три простых основных объекта: Задача , Владелец , TasksGroup .

  • Многие Владельцы могут иметь много Задачи и наоборот (многие-ко-многим).
  • Задача может при желании принадлежать только одной TasksGroup , но TasksGroup может иметь много заданий (один ко многим)

А теперь сложная часть для меня. Владельцы каждого Задача в пределах TasksGroup должны быть одинаковыми.Также будет возможность изменить Владельцев из всех Задач в пределах TasksGroup или из одной Задачи , если она не принадлежит ни одному TasksGroup .

Должны ли быть проверочные ограничения?Или, может быть, должны быть установлены «основные» отношения между TasksGroup и Владельцами ?Как насчет отношений между Task и Owners , если Task принадлежит группе?Каков хороший способ создать это?

Ответы [ 4 ]

0 голосов
/ 27 февраля 2019

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

Кроме того, самый чистый подход - это дублирование внешних (супер) ключей.Вот реляционный подход с псевдокодом, который не требует NULL;типы данных и неинтересные атрибуты опущены:

create table Task {
  TaskId,
  key { TaskId }
};

create table Owner {
  OwnerId,
  key { OwnerId }
};

create table TaskOwner { /* Bog standard association table */
  TaskId,
  OwnerId,
  key { Taskid, OwnerId }
  reference TO_T { TaskId } references Task { TaskId },
  reference TO_O { OwnerId } references Owner { OwnerId }
};

create table TaskGroup {
  GroupId,
  OwnerId,
  key { GroupId }, /* Each group has exactly one owner */
  reference TG_O { OwnerId } references Owner { OwnerId }
};

create table TaskGroupTask {
  TaskId,
  GroupId,
  OwnerId,
  key { TaskId }, /* Each task may belong to at most one group */
  reference TGT_TO { TaskId, OwnerId } references TaskOwner { TaskId, OwnerId },
  /* Foreign superkey coming up */
  reference TGT_TG { GroupId, OwnerId } references TaskGroup { Group, OwnerId }
};

Подсказка в том, что TaskGroupTask.Ownerid выполняет двойную функцию как часть ссылок на TaskOwner и TaskGroup и тем самым гарантирует, что владелец группыидентичен владельцу каждой задачи в нем.Здесь есть иностранный суперключ - TGT_TG относится к надмножеству ключа TaskGroup, но если ваша СУБД возражает против этого, возможный обходной путь - создать (лишний) уникальный индекс для надмножества.

Наличие отдельной таблицы TaskGroupTask вместо обнуляемого атрибута TaskOwner.GroupId на первый взгляд может показаться излишним, но оно позволяет использовать простое ограничение ключа для применения правила, согласно которому задача может принадлежать не более чем одной группе.Кроме того, он избегает значений NULL.

Существует функциональная зависимость { GroupId } -> { OwnerId } в TaskGroupTask, которая нарушает нормальную форму Бойса-Кодда, но избыточность контролируется ссылкой TGT_TG, и необходимо применятьправила ситуации.

Смена владельца группы (и всех ее задач) включает обновление трех таблиц в одной и той же выписке / транзакции, но у правильной СУБД с этим не должно быть проблем.

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

0 голосов
/ 09 февраля 2019

Я бы пошел с RequiredOwners сортами на TaskGroup.Фактически, могут быть даже разные типы TaskGroup случаев, когда один тип требует, чтобы назначенные задачи имели соответствующих владельцев, тогда как другие могут иметь разные правила.Тем не менее, это зависит от домена, поэтому, если это реальный домен, на который вы ссылаетесь, вы должны знать:)

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

0 голосов
/ 16 февраля 2019

Владельцы каждой Задачи в TasksGroup должны быть одинаковыми

Для этого ограничения базы данных можно выполнить, предварительно определив класс / таблицу соединений между Task и Owner,TaskOwner, который является стандартным в отношении многих ко многим.

Если TaskGroup должен быть ограничен задачами одного владельца, естественным местом для его подключения является информация о задачах и владельцах.доступно, то есть соединительная таблица.Делать это только одним ФК, скажем GroupId, недостаточно.Сам TaskGroup должен быть ограничен одним владельцем.Для него требуется OwnerId, который является частью его PK, поэтому TaskOwner может ссылаться на него по OwnerId и GroupId.Наконец, TaskGroup s OwnerId должен быть от FK до Owner, чтобы убедиться, что TaskOwner и TaskGroup относятся к одному владельцу.Это соответствует этой модели базы данных:

enter image description here

Также будет возможность сменить владельцев всех задач в TasksGroup

Как часто строгие ограничения и гибкость являются взаимоисключающими.Это кольцо из OwnerId ссылок трудно сломать.OwnerId в TaskOwner необходимо изменить, но для этого нужно выполнить четыре шага:

  • установить GroupId в null
  • изменить OwnerId
  • изменить TaskGroup OwnerId
  • restore TaksOwner.GroupId

Достаточно сложно с SQL, но еще сложнее с Entity Framework, потому что EF не позволяет модифицировать основнойключевые свойства.С EF вы должны удалить TaskOwner s, создать новые, а затем установить TaskGroup.OwnerId и TaskOwner.GroupId.Не невозможно, но все, но гибкий!

0 голосов
/ 07 февраля 2019

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

...