Вопрос

Я работаю над программой, в которой вы можете зарегистрировать жалобы. Есть три типа жалоб: internal (Ошибки от сотрудников), external (ошибки от другой компании) и supplier (Ошибки, сделанные поставщиком). Они держат разные данные, которые не могут быть разделены. У меня в настоящее время 4 столы (жалоба, сотрудника, компания и поставщик). Вот визуализация таблиц:

У меня есть базовое понимание подтипов, но я не могу перевести их из ERD в реальную базу данных SQL Server или, по крайней мере, в этом сценарии. Это примерно так, как выглядят 4 таблицы (неактуальные атрибуты опущены):

Жалоба
Жалоба PK

Работник
Employeeeid pk
Имя сотрудника

Компания
CompanyID PK.
Название компании

Поставщик
Приложение PK.
Наименование поставщика

При регистрации жалобы ошибка допускается любым из 3 типов, и все они хранят разные информации. Как лучше всего хранить информацию в этом случае? Я подумал о том, чтобы поместить 2 дискриминатора в столовую жалобу: ComplaintType и Id Таким образом, я могу указать на какой стол, чтобы проверить, и какой идентификатор нужен, но это не очень чисто, ни эффективно.

Пожалуйста помогите.

Это было полезно?

Решение

Я настоятельно рекомендую вам не использовать метод «2 дискриминатора». Вы будете эффективно иметь столбец внешнего ключа, который указывает на одну из трех таблиц, в зависимости от поля ComEttyPE. Если вы это сделаете, вы будете передавать проверки ссылочной целостности, поставляемой SQL Server и все преимущества, которые поставляются с внешними ключами. На моей предыдущей работе был таблица под названием EntitytypeindexLabel, которая была «мостовой таблицей», которая присоединила indexLabels (в основном метаданные) к различным «объектам», которые были много разных потенциальных таблиц (документ, связующее, рабочий процесс и т. Д.). Это было просто ужасно. FK в этой таблице может указывать на многие разные таблицы. Орфатические записи могут всплывать повсюду. Дополнительная логика должна была быть реализована для определения того, на какой таблице присоединится. Присоединения были болью писать в целом. Это были все виды головной боли.

Я думаю, что ваши два варианта:

-3 колонны в жалобе: rameeeComplineaintID, CompanyComplaintID, поставщик Комплектурид. CELETIDS должны быть уникальными во всех таблицах (думайте, что GUID здесь вместо столбцов идентификации). Каждая строка в жалобе будет иметь только одну из этих удостоверенных личности, остальные два будут нулевыми. Затем вы можете просто оставить внешнее соединение в этих таблицах в каждом запросе, чтобы получить необходимые вам данные.

-One Гигантская таблица со всеми возможными полями, которые вам нужны для каждого типа жалоб, устанавливая неиспользуемые поля других типов жалоб в NULL.

Другие советы

Смотрите несколько действительно хороших ресурсов по теме:

В основном есть три известных подхода:

  • Таблица на подкласс
  • Таблица на иерархию
  • Таблица на бетон

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

Является ли основной проблемой, который вам нужен какой-то «серийный номер», чтобы уникально определить жалобу, независимо от того, какой тип? В основном, потом вам нужен стол для каждого типа жалобы (как у вас будет, я думаю), а также таблица Master «Жалоба» с жалобами. Каждый из таблиц, специфичных к типам будет иметь внешний ключ для Tellaint.comLaintID. Возможно, вам полезно иметь поле «тип» в жалобе, но это на самом деле не требуется для модели.

У вас может быть жалобы, с которыми сталкивается FK, отношение к PK всех трех ваших подтипов- сотрудника, компании и поставщика.

В ответ вам комментарий к принятому ответу:

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

alter table complaint_master 
    add constraint loc_attribute_has_one_value 
    check ( 
        (case when complaint_employee is null then 0 else 1 end) + 
        (case when complaint_supplier is null then 0 else 1 end) + 
        (case when complaint_external is null then 0 else 1 end)  = 1 
    ); 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top