Чтобы полностью обеспечить вашу модель данных или Не полностью обеспечить вашу модель данных - PullRequest
1 голос
/ 17 июля 2009

http://weblogs.sqlteam.com/jeffs/archive/2008/08/13.aspx:

Рассмотрим следующую логическую модель данных:
* Есть несколько компаний
* У каждой компании есть много проектов
* У каждого проекта много задач
* Каждая задача имеет статус, выбранный из глобального списка предварительно определенных статусов.

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

Итак, в основном у нас есть 4 таблицы:
Статус (PK: StatusID)
Компании (PK: CompanyID)
Проекты (ПК: ProjectID, FK: [Компании] .CompanyID)
Задачи (ПК: TaskID, FK: [Проекты] .ProjectID, [Статус] .StatusID).

Теперь позвольте мне добавить одну маленькую морщинку. Предположим, что доступные Статусы для каждой Задачи определены не глобально, а на уровне Компании. То есть каждая компания имеет свой собственный список статусов, которым может быть назначено задание.

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

Компании (PK: CompanyID)
Статус (PK: StatusID, FK: [Companies] .CompanyID)
Проекты (ПК: ProjectID, FK: [Компании] .CompanyID)
Задачи (ПК: TaskID, FK: [Проекты] .ProjectID, [Статус] .StatusID).

Есть ли какие-либо другие изменения, которые мы должны внести в эту модель данных? Или достаточно просто добавить столбец CompanyID в таблицу Status, чтобы облегчить это изменение? Помните, что нашей целью, как всегда, является полная ссылочная целостность с использованием ограничений первичного и внешнего ключей, где это возможно.

Ну, есть проблема:

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

Это очень легко исправить, но это можно сделать, только нарушив правило "всем таблицам нужен только первичный ключ идентификации".

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

Далее он указывает, как составные ключи можно использовать для полного применения и ограничения вашей модели данных примерно так:

Компании (PK: CompanyID)
Статус (PK: CompanyID, StatusID, FK: [Companies] .CompanyID)
Проекты (ПК: CompanyID, ProjectID, FK: [Companies] .CompanyID)
Задачи (ПК: TaskID, FK: [Проекты]. (CompanyID, ProjectID), [Status]. (CompanyID, StatusID)).

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

Для обеспечения полного или не полного применения.

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

Теперь я знаю, что не обязательно «правильный» дизайн, но для подобных ситуаций ... Я ищу отзывы с точки зрения лучших практик.

Преимущества, недостатки и общие соображения по поводу этого дизайна или полного обеспечения реализации вашей модели данных?

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

1 Ответ

2 голосов
/ 17 июля 2009

Я бы создал таблицу CompanyStatus, которая составляет от многих ко многим между Company и Status и описывает, какие из статусов применимы для данной компании. Затем задачам присваивается CompanyStatusID, а не StatusID.

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

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

...