Согласно моему пониманию ваших спецификаций, ваша бизнес-среда подразумевает троичные отношения на концептуальном уровне . В связи с этим необходимо определить:
- тип связи (или ассоциации ) между типами сущностей Person и Survey ;
- тип отношений между опросом и вопросом ;
- тип отношений, который устанавливает связь между двумя вышеупомянутыми типами отношений и, как следствие, между человеком , опросом и вопросом , т. е. ответ (более короткое имя, которое упрощает интерпретацию, с моей точки зрения).
Итак, я считаю, что вы находитесь на правильном пути с вашим подходом 1 , хотя он требует некоторых небольших (но важных) уточнений, чтобы сделать его более точным. Я подробно опишу такие уточнения и другие соответствующие соображения в следующих разделах.
Бизнес правила
Давайте немного расширим применимые бизнес-правила и переформулируем их следующим образом:
- Person регистров в нуль один или-многих обследований
- Survey получает регистрацию нулевой один или-многих людей
- Survey интегрируется один-ко-многим вопросам
- Вопрос интегрирует нулевой один или многим Surveys
- Вопрос получает нуль-один или многих ответов
- Ответ обеспечивается точно-один Человек в контексте точно один год обследования
Описательная схема IDEF1X
Затем я создал IDEF1x на схему , что представлено на рисунке 1 , который синтезирует бизнес - правила , сформулированные выше:
Определение интеграции для информационного моделирования ( IDEF1X ) является весьма рекомендуется метод моделированиякоторый был созданкачестве стандарта в декабре 1993 года Национальным институтом Соединенных Штатов стандартов и технологий ( NIST ). Она прочно основана на теоретическую работе авторства единственным учредителем в реляционной модели , т.е. д - р Ф. Кодда , а также на взгляде сущности-связи , разработанный д - ром П. Чен .
PersonSurvey отношения
На мой взгляд, отношения PersonSurvey необходимы для предоставления средств авторизации, чтобы человек мог принять участие в данном опросе . Таким образом, после того, как определенное лицо было зарегистрировано в определенном опросе , он или она уполномочивается предоставлять ответы на вопросы, которые включают соответствующий опрос .
SurveyQuestion отношения
Я предполагаю, что свойство (или атрибут), называемое suvery_question.question_number в вашей диаграмме, используется для представления порядка представления данного экземпляра Вопроса в отношении конкретного опроса . Как вы можете видеть, я обозначил такое свойство как SurveyQuestion.PresentationOrder , и я думаю, что вы должны предотвратить, чтобы (i) два или более значения Question.QuestionNumber разделяли (ii) одно и то же значение PresentationOrder в (iii) одно и то же вхождение SurveyQuestion .
Чтобы изобразить эту потребность, я включил составной ALTERNATE KEY (AK) в поле, представляющее этот тип сущности, который состоит из комбинации свойств ( SurveyNumber, QuestionNumber, PresentationOrder ). Как вам хорошо известно, составной AK может быть объявлен в логической структуре DDL с помощью ограничения UNIQUE, состоящего из нескольких столбцов (как я показал в SurveyQuestion
таблице, которая является частью описательной схемы DDL, изложенной в нескольких разделах ниже).
Тип объекта ответа
Да, с типом объекта Ответ я изображаю отношения между двумя другими отношениями ; На первый взгляд это может показаться неловким, но в этом подходе нет ничего плохого, если он (а) точно представляет особенности интересующего бизнес-контекста и (б) правильно представлен в макете логического уровня.
Да, вы абсолютно правы, было бы ошибкой изображать эту часть сценария на логическом уровне абстракции с помощью двух Response.SurveyNumber
(или, скажем, Response.SurveyId
) значений, на которые ссылаются два разных столбца в одной Response
строке.
Производная логическая структура SQL-DDL
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE Person (
PersonId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
GenderCode CHAR(3) NOT NULL,
BirthDate DATE NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK UNIQUE (
FirstName,
LastName,
GenderCode,
BirthDate
)
);
CREATE TABLE Survey (
SurveyNumber INT NOT NULL,
Description CHAR(255) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Survey_PK PRIMARY KEY (SurveyNumber),
CONSTRAINT Survey_AK UNIQUE (Description)
);
CREATE TABLE PersonSurvey (
PersonId INT NOT NULL,
SurveyNumber INT NOT NULL,
RegisteredDateTime DATETIME NOT NULL,
--
CONSTRAINT PersonSurvey_PK PRIMARY KEY (PersonId, SurveyNumber),
CONSTRAINT PersonSurveyToPerson_FK FOREIGN KEY (PersonId)
REFERENCES Person (PersonId),
CONSTRAINT PersonSurveyToSurvey_FK FOREIGN KEY (SurveyNumber)
REFERENCES Survey (SurveyNumber)
);
CREATE TABLE Question (
QuestionNumber INT NOT NULL,
Wording CHAR(255) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Question_PK PRIMARY KEY (QuestionNumber),
CONSTRAINT Question_AK UNIQUE (Wording)
);
CREATE TABLE SurveyQuestion (
SurveyNumber INT NOT NULL,
QuestionNumber INT NOT NULL,
PresentationOrder TINYINT NOT NULL,
IsMandatory BIT NOT NULL,
IntegratedDateTime DATETIME NOT NULL,
--
CONSTRAINT SurveyQuestion_PK PRIMARY KEY (SurveyNumber, QuestionNumber),
CONSTRAINT SurveyQuestion_AK UNIQUE (
QuestionNumber,
SurveyNumber,
PresentationOrder
),
CONSTRAINT SurveyQuestionToSurvey_FK FOREIGN KEY (SurveyNumber)
REFERENCES Survey (SurveyNumber),
CONSTRAINT SurveyQuestionToQuestion_FK FOREIGN KEY (QuestionNumber)
REFERENCES Question (QuestionNumber)
);
CREATE TABLE Response (
SurveyNumber INT NOT NULL,
QuestionNumber INT NOT NULL,
PersonId INT NOT NULL,
Content TEXT NOT NULL,
ProvidedDateTime DATETIME NOT NULL,
--
CONSTRAINT Response_PK PRIMARY KEY (SurveyNumber, QuestionNumber, PersonId),
CONSTRAINT ResponseToPersonSurvey_FK FOREIGN KEY (PersonId, SurveyNumber)
REFERENCES PersonSurvey (PersonId, SurveyNumber),
CONSTRAINT ResponseToSurveyQuestion_FK FOREIGN KEY (SurveyNumber, QuestionNumber)
REFERENCES SurveyQuestion (SurveyNumber, QuestionNumber)
);
Два составных ИНОСТРАННЫХ КЛЮЧА в Response
таблице
Это, пожалуй, самый важный момент для обсуждения: ссылки на данную Response
строку
SurveyQuestion.SurveyNumber
, и
SurveyPerson.SurveyNumber
должны иметь совпадающие значения . Насколько мне известно, лучший вариант для принудительного применения этого условия декларативным способом - использование двух составных FOREIGN KEY (FK).
Как показано в дизайне DDL, первый FK делает ссылку на PersonSurvey
таблицу PRIMARY KEY (PK), т. (PersonId, SurveyNumber)
Е. И соответствует столбцам Response.PersonId
и Response.SurveyNumber
.
Второй FK указывает на SurveyQuestion
таблицу PK, т. Е. (SurveyNumber, QuestionNumber)
И, соответственно, состоит из столбцов Response.SurveyNumber
и Response.QuestionNumber
.
Таким образом, Response.SurveyNumber
столбец весьма полезен, поскольку он используется как часть ссылки FK в двух разных ограничениях.
С помощью этого метода гарантируется, что система управления базами данных гарантирует ссылочную целостность от
- (а)
Response
к PersonSurvey
;
- (б)
Response
к SurveyQuestion
; и
- (c) каждая из таблиц, представляющих тип ассоциативного объекта для таблиц, обозначающих независимые типы объектов, а именно
Person
, Survey
и Question
.
Производные данные, чтобы избежать обновления аномалий
Я заметил на вашей диаграмме два элемента, которые я считаю заслуживающими упоминания. Эти элементы связаны с двумя PersonSurvey
столбцами, которые могут (должны) быть получены .
В связи с этим, вы можете получить PersonSurvey.IsStarted
данные путем запроса, если конкретное Person
вхождение предоставило одно или несколько значений Responses
для Questions
интегрирования точного Survey
через SurveyQuestion
таблицу.
И вы также можете получить PersonSurvey.IsCompleted
точку данных, определив, предоставил ли данный Person
экземпляр Response
всем, Questions
что совпадает со значением «ИСТИНА» в IsMandatory
столбце в определенной SurveyQuestion
строке.
Путем получения этих значений вы предотвращаете некоторые аномалии обновления, которые могли бы в конечном итоге возникнуть, если бы вы сохранили такие значения в SurveyQuestion
столбце.
Важное соображение
Как правильно заметил в своем комментарии @Dave , если вы столкнетесь с будущим требованием, требующим управления различными типами ответов, которые предполагают управление датами, числовыми значениями, множественным выбором и другими возможными аспектами, вам придется расширить этот макет базы данных.
ID
иNumber
, но в остальном это фантастика. Спасибо.