БД Дизайн - Связь с родителем без циклических ссылок - PullRequest
1 голос
/ 29 апреля 2010

У меня возникли проблемы с решением следующей проблемы.

Допустим, у меня есть БД, которая выглядит примерно так:

Таблица вопросов

Id | Details | CreateDate | ClosedDate

Таблица примечаний к выпуску

Id | ObjectId | Notes | NoteDate

Таблица присвоений проблем

Id | ObjectId | AssignedToId| AssignedDate

Я бы хотел разрешить привязку проблемы к другой проблеме. Я думал о добавлении столбца в таблицу Issue под названием ParentIssueId, и это позволило бы мне связывать проблемы, но я предвижу циклические ссылки, встречающиеся в таблице проблем, если я пройду с этой реализацией. Есть ли лучший способ сделать это, и если да, то как?

Спасибо

Ответы [ 3 ]

1 голос
/ 29 апреля 2010

Создать таблицу:

LinkedIssues
IssueIDa    pk composite primary key, fk to Issue table
IssueIDb    pk composite primary key, fk to Issue table

PK будет держать некоторые дубликаты подальше, но создайте проверочное ограничение: IssueIDa<IssueIDb, чтобы вы не получили дубликат, такой как:

row 1 IssueIDa=123
      IssueIDb=987

row 2 IssueIDa=987
      IssueIDb=123

однако, чтобы предотвратить такой круг, как:

row 1 IssueIDa=123
      IssueIDb=987

row 2 IssueIDa=987
      IssueIDb=456

row 3 IssueIDa=456
      IssueIDb=123

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

1 голос
/ 29 апреля 2010

Вы можете добавить соединение / таблицу ссылок, которая будет выглядеть примерно так:

IssueLink

IssueId | LinkedIssueId

Где оба столбца являются внешними ключами таблицы проблем.

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

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

IssueId & LinkedIssueId = LinkedIssueId & IssueId

(что приведет к логическому дублированию)

Смотрите здесь: http://en.wikipedia.org/wiki/Junction_table Единственное отличие состоит в том, что таблица Junction указывает на одну и ту же таблицу для создания отношения один ко многим.

0 голосов
/ 29 апреля 2010

Если проблема может быть связана с еще одной «родительской» проблемой, то наличие столбца «ParentId» в таблице - это хорошо (если NULL означает отсутствие родителя). Если проблема может быть связана с несколькими другими проблемами, потребуется новая таблица «многие ко многим» (или «ссылка»).

В случае или проверка и предотвращение циклических ссылок (особенно когда «круг» охватывает три или более вопросов) будет сложным. Либо вы проверяете круг во время ОБНОВЛЕНИЯ, основывая обновление на CTE, который проверяет циклические ссылки и не выполняет обновление, если таковые обнаружены, или вы можете обновить хранимую процедуру, которая сначала проверяет круги и выдает обновление только в том случае, проверка проходит. (Конечно, вам нужно беспокоиться о проблемах параллелизма - что если данные изменятся между вашей проверкой и вашим обновлением - что делает обновление на основе CTE предпочтительным, если более сложным.)

...