2016-10-18 5 views
5

Чтобы дать представление о том, что я говорю, рассмотрим сущность (в моем случае это Task), которая может быть связана с любым количеством других объектов в системе. Для наших целей, скажем, задача может быть связана с:База данных SQL Server - Как обрабатывать таблицу, которая МОЖЕТ быть связана с любым количеством других таблиц?

  • Проект
  • Счет
  • билетов
  • Человек
  • т.д.

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

Теперь я рассмотрел несколько вариантов этого, однако я не считаю себя экспертом в области проектирования баз данных, поэтому я решил, что дойду до конца. Опции я Рассмотренный таким образом далеко включают в себя:

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

  • Один столбца в Task который выступает в качестве внешнего ключа, но включает в себя еще один столбец с указанием ссылки type, поэтому при запросе от него мы можем определить, какие JOIN и произойдут в зависимости от типа. Таким образом, оба идентификатора учетной записи и лица будут в этом столбце для своих задач, но столбец типа ссылки указывает, является ли идентификатор человеком или учетной записью. Это очень рискованно для меня, и, очевидно, ограничения не могут быть соблюдены в базе данных.

  • Другие варианты ??

Я хотел бы, если кто-то смог бы указать меня в направлении «чистого» дизайн, но если нет, то многочисленные колонны действуют как ограничения FK, но позволяя NULL быть лучшей?

Заранее благодарен!

+0

Я столкнулся с аналогичным вызовом несколько лет назад. Не задумываясь, я выбрал второй вариант. Вместо использования object_id в sys.object я создал новую таблицу, которая содержит константу, которая обозначает ту таблицу. Я где-то слышал, что этот дизайн плох, но я никогда не слышал, почему. Пять лет спустя этот тип ссылок использовался практически повсеместно в приложении (комментарии, документы, параметр и т. Д.). В некотором роде он стал ядром приложения. В то время я этого не ожидал, но мне стало интересно узнать, как развилось. – AXMIM

+0

Следуя моему предыдущему комментарию, так как я больше не работаю там, поэтому я не могу сказать, что они теперь наносят урон негативному эффекту. Он прочно удерживается в течение 5 лет. Тем не менее, я должен признать, что я видел, что SQL-сервер делает какой-то странный план запроса один или два из-за этого, и здесь есть некоторые небольшие недостатки. Кроме того, сущность-структура не была вокруг. Я не уверен, что буду доверять EF для обработки этих объединений. – AXMIM

+2

Это новый экземпляр вопроса о повторяющихся * полиморфных ассоциациях *. Как только вы знаете официальный термин, легко найти способы, как это сделать. –

ответ

0

Фактически, принятым стандартом является таблица REF или XREF. Так, например, между Task и Project, у вас будет таблица с идентификатором для таблицы, внешний ключ для задачи и внешний ключ для проекта.

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

3

Я использовал бы первый вариант.

Минусы:

  1. Добавить новый столбец, когда вы добавляете новую таблицу - Как Вы уже редактирования базы данных путем добавления новой таблицы, добавив один столбец не должен быть проблемой.
  2. Значения NULL во многих столбцах - Это не оказывает большого влияния на производительность или что-то еще. Вы можете использовать значения по умолчанию вместо NULL, если они вам подходят. Смотрите этот вопрос (SQL Server - Performance/Size Drawbacks of Null Columns) и ответы

Но с другой стороны, вы получаете более надежные отношения, понятно, присоединяется, гораздо более уместно рамочные объект отображения, проще запросы муравей и т.д.

+0

Согласен с этим - я считаю, что так я и собираюсь. Это может быть немного болью, пишущей против этого в нашем приложении, но, как вы указываете, преимущества намного перевешивают минусы. – CTDev

+0

@CTDev, я рад, что у меня сложилось какое-то мнение, но не забудьте тщательно изучить его до его внедрения. Попробуйте найти * полиморфные ассоциации *, как указал GiladGreen. –

+1

Я прочитал об этом и определенно нашел гораздо лучшее решение. Внедряя таблицу, похожую на интерфейс в ООП (я называл ее «Taskable»), мне удалось построить отношения, в которых на каждой вставке, чтобы сказать «Аккаунт», я также вставляю в Taskable, первичный ключ из Account, который был просто вставлено. Затем Task ссылается на идентификаторы в Taskable, и я реализую FK из PK в Account, Project и т. Д. Таким образом, если PK в моих таблицах являются GUID, у меня есть прямой путь с сохраненной ссылочной целостностью. Многому научились сегодня! – CTDev

1

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

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

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

Я узнал о правиле домена в колледже, но никогда не реализовывал его в реальном мире, поэтому я не знаю, как это можно сделать на SQL-сервере. В реальных сценариях он всегда срабатывал, как я указал в первом абзаце.

Надеюсь, это поможет. В противном случае два других ответа здесь имеют смысл.

+0

Спасибо за понимание - это странная позиция, где задача может быть привязана к проекту (который, в свою очередь, привязан к учетной записи), и поэтому он также привязан к учетной записи (косвенно). Тем не менее, они также хотят, чтобы задача могла быть напрямую привязана к учетной записи. Im не на 100% уверен, как это сделать, поскольку объект Task является тем же, независимо от того, к чему он привязан, поэтому я надеялся использовать единую таблицу Task, но в то же время проблема ссылочной целостности становится проблемой. Тем не менее, я рассмотрю правило домена, спасибо за информацию! – CTDev

+0

Я думаю, что ключом здесь является «они также хотят, чтобы задача могла быть напрямую привязана к учетной записи». Я обнаружил, что изучение бизнес-правил с заинтересованными сторонами почти всегда позволяет нормализовать дизайн. Обычно их можно обрабатывать через пользовательский интерфейс и отчетность, а большинство фреймворков подключаться к нормализованным базам данных, чтобы они платили в долгосрочной перспективе. –

Смежные вопросы