설문 조사, 질문 및 응답에 대한 데이터베이스에서 중복 외래 키를 처리하는 최상의 데이터 모델링 방법


13

설문 조사, 질문 및 응답을 저장하기위한 최상의 관계형 모델링 방법에 대한 조언을 찾고 있습니다.

아래 두 가지 방법 중 어느 것이 가장 적합한 지 또는 다른 방법 중 하나를 찾고 있습니다.

나는 적어도 다음과 같은 엔티티를 가지고 있습니다.

  • 질문
  • 서베이
  • 사람

그리고 적어도 이러한 관계 :

  • 각 설문 조사에는 하나 이상의 질문이 있습니다.
  • 각 질문은 0 개 이상의 설문 ​​조사에 사용될 수 있습니다.
  • 각 사람은 0 회 이상의 설문 ​​조사를 할 수 있습니다.

여기 내가 곤경에 처한 곳이 있습니다 : 사람이 만든 설문 조사 질문에 대한 응답을 모델링하는 방법.

여기에 내가 생각한 두 가지 접근법이 있는데, 그 중 어느 것도 나에게 좋지 않은 것 같습니다. 여기의 다이어그램은 문제를 설명하기 위해 크게 단순화되었습니다.

접근법 1 : 접근법 1

이 접근법에 대해 내가 싫어하는 것 :

  • survey_person_question_response표는 설문 조사를 참조 두 개의 서로 다른 열이 survey_question_survey_idsurvey_person_survey_id
    • survey_id이 두 열에 대해 한 행에서 서로 다른 참조 를 갖는 것은 오류 입니다. survey_question은 사용자가 survey_person에 참여한 것과 동일한 설문 조사에서 가져와야합니다. 이것을 시행하는 좋은 방법을 볼 수 없습니다.
  • 내가 여기서하고있는 일은 두 관계를 맺는 것 같습니다. 어떤 이유로 든 나에게 잘못 느낍니다.

접근법 2 :

접근법 1에서 동일한 값을 참조해야하는 두 개의 FK를 피하십시오. 여기에 이미지 설명을 입력하십시오

이 접근법에 대해 내가 싫어하는 것 :

  • question_idsurvey_idFK가 유효한 survey_question쌍 에서 온다는 강제는 없습니다
  • survey_idperson_idFK가 유효한 survey_person쌍 에서 온다는 강제는 없습니다

다음에 대한 조언 :

  • 이러한 접근법 중 하나가 일반적인 접근법인지 여부
  • 이러한 접근법 중 하나의 장단점
  • 이 데이터를 완전히 정리하는 더 좋은 방법

크게 감사하겠습니다!

답변:


12

귀하의 사양에 대한 나의 이해에 따라 귀하의 비즈니스 환경에는 개념적 수준의 삼항 관계가 포함 됩니다. 이와 관련하여 다음을 정의해야합니다.

  1. 엔티티 유형 PersonSurvey 사이 의 관계 (또는 연관 ) 유형 ;
  2. 설문질문 의 관계 유형 ;
  3. 앞서 언급 한 두 가지 관계 유형과 그 결과 Person , SurveyQuestion 사이의 연결을 설정하는 관계 유형 , 즉 응답 (내 관점에서 해석을 단순화하는 더 짧은 이름).

따라서 접근 방식 1을 올바르게 사용하고 있지만 더 정확한 결과를 얻으려면 약간의 (중요하지만) 미세 조정이 필요합니다. 다음 섹션에서 이러한 개선 및 기타 관련 고려 사항을 자세히 설명합니다.

비즈니스 규칙

해당 비즈니스 규칙을 약간 확장하고 다음과 같은 방식으로 규칙을 재구성 해 보겠습니다.

  • 사람의 제로 일 또는 일대에서 레지스터 설문 조사
  • 설문 조사 제로 일 또는 일대의 등록 얻는 사람을
  • 조사는 일대에 의해 통합되어 질문
  • 일대 다 설문 조사를 통합 한 질문
  • 질문은 제로 일 또는 일대 수신 응답
  • 응답 정확히-하나에 의해 제공됩니다 사람이 정확히-하나의 맥락에서 설문 조사

설명 IDEF1X 다이어그램

그런 다음 IDEF1X 를 그림 1에 표시된 다이어그램으로 작성했습니다. 다이어그램은 위에서 공식화 된 비즈니스 규칙을 종합합니다.

그림 1 단순화 된 측량 IDEF1X


정보 모델링을위한 통합 정의 ( IDEF1X는 )이 설립되었다 매우 추천 모델링 기술이다 표준 미국 국립 표준 기술 연구소 (12 월 1993 년 NIST ). 그것은 단단하게 저술 이론적 연구를 기반으로 유일한 창립자 관계형 모델 즉, 박사 EF 커드 온도 및 개체 - 관계보기 가 개발 한 박사 PP 첸 .


PersonSurvey의 관계

내가 본 것처럼 PersonSurvey 관계는 개인 이 주어진 설문 조사 에 참여할 수 있도록 권한 부여 수단을 제공해야합니다 . 이런 식으로 특정 개인 이 특정 설문 에 등록 되면 해당 설문 을 통합하는 질문 에 대한 답변 을 제공 할 권한이 있습니다 .

SurveyQuestion의 관계

나는 다이어그램에서 suvery_question.question_number 라는 속성 (또는 속성) 이 특정 Survey 와 관련하여 주어진 Question 인스턴스 의 표시 순서 를 나타내는 데 사용 된다고 가정합니다 . 보시다시피 SurveyQuestion.PresentationOrder 와 같은 속성을 표시 했으며 (i) 둘 이상의 Question.QuestionNumber 값이 (ii) (iii) 동일한 SurveyQuestion 발생 에서 동일한 PresentationOrder 값을 공유 하지 않도록해야한다고 생각합니다 .

이러한 필요성을 설명하기 위해이 엔티티 유형을 나타내는 상자에 복합 대체 키 (AK)를 포함 시켰으며, 이는 속성 조합 ( SurveyNumber, QuestionNumber, PresentationOrder )으로 구성됩니다. 잘 아시다시피, 복합 AK는 다중 열 UNIQUE 제약 조건을 사용하여 논리 DDL 디자인에서 선언 할 수 있습니다 ( SurveyQuestion아래 설명에서 설명하는 DDL 레이아웃의 일부인 표에 나와있는 것처럼).

응답 개체 유형

예, 응답 엔터티 유형으로 다른 두 관계 간의 관계 를 나타냅니다 . 그것은 첫눈에 어색한 보이지만 아무것도 잘못은 오래 (a)는 정확하게이자와 (b)의 비즈니스 컨텍스트의 기능을 나타내는 논리적 수준의 레이아웃에 제대로 표현으로,이 접근 방식이있다.

예, 당신은 완전히 정확 합니다. 동일한 행 의 두 개의 다른 열에서 참조되는 두 개의 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표 에있는 두 개의 복합 FOREIGN 키

이것은 아마도 논의해야 할 가장 중요한 점일 것입니다. 주어진 Response행에서

  1. SurveyQuestion.SurveyNumber,
  2. SurveyPerson.SurveyNumber

일치하는 값이 있어야합니다 . 내가 아는 한,이 조건을 선언적으로 적용하는 가장 좋은 옵션은 두 개의 복합 FOREIGN KEY (FK)를 사용하는 것입니다.

DDL 디자인에서 볼 수 있듯이 첫 번째 FK는 PersonSurveyPRIMARY KEY (PK) 테이블에 대한 참조를 작성하며 (PersonId, SurveyNumber)Response.PersonId및을 따릅니다 Response.SurveyNumber.

제 FK가 가리키는 SurveyQuestion즉, 테이블 PK (SurveyNumber, QuestionNumber)하고, 따라서 열 구성된다 Response.SurveyNumber하고 Response.QuestionNumber.

이러한 방식으로, Response.SurveyNumber컬럼은 두 가지 다른 제약 조건 에서 FK 참조의 일부로 사용되므로 상당히 유용 합니다.

이 방법을 사용하면 데이터베이스 관리 시스템에서 보장 된 참조 무결성 을 보장 할 수 있습니다.

  • (a) Response받는 PersonSurvey;
  • (b) ResponseSurveyQuestion; 과
  • (c) 독립 엔티티 유형, 즉 방치 테이블에 연관 엔티티 유형을 나타내는 각 테이블 Person, SurveyQuestion.

업데이트 이상을 피하기위한 파생 데이터

나는 당신의 다이어그램에서 내가 언급 할 가치가있는 두 가지 요소를 발견했습니다. 이러한 요소는 파생PersonSurvey 될 수있는 두 개의 열과 관련 이 있습니다 .

그 점에서, 당신은 유도 할 수 PersonSurvey.IsStarted주어진 경우 질의에 의해 자료를 Person발생이 더 하나를 제공하고 있습니다 ResponsesQuestions그 정확한 통합 Survey비아 SurveyQuestion테이블.

또한 PersonSurvey.IsCompleted주어진 Person인스턴스가 특정 행 의 열에서 'TRUE'값을 갖는 Response모든 인스턴스에 a 를 제공 했는지 여부를 판별 하여 데이터 포인트를 얻을 수 있습니다 .QuestionsIsMandatorySurveyQuestion

이러한 값을 파생 시키면 해당 값을 SurveyQuestion열에 유지 한 경우에 발생할 수있는 일부 업데이트 이상을 방지 할 수 있습니다 .

중요한 고려 사항

따라 @ 데이브는 당연히 자신의 의견에서 지적 당신이 관리하는 날짜, 숫자 값, 다중 선택, 그리고 다른 가능한 측면을 의미하는 응답의 다른 종류의 관리를 요구하는 미래의 요구 사항에 직면하는 경우, 당신은이 데이터베이스 레이아웃을 확장해야합니다.


1
와우, 이것은 내 머리 속에있는 질문에 완벽하게 대답하고 나에게 더 많은 것을 가르쳐주었습니다! 주석은 개선을 제안해야하기 때문에 키가 ID및로 끝나는 것이 약간 혼란 스럽지만 Number그렇지 않으면 환상적입니다. 감사합니다.
Zach Mierzejewski

@Zach 가장 환영합니다. 게시물이 도움이 되었기 때문에 기쁩니다. 의견을 보내 주셔서 감사합니다.
MDCCL

1

이것이 외래 키로 마이그레이션 할 때 열 앞에 접두사를 붙이고 싶지 않은 이유입니다. 첫 번째 경우 모델링 도구 survey_id를 사용하여 survey_person_question_response테이블 의 열 중 하나를 접두어로 사용할 수 있습니다 . 관계를 만든 후에이를 조정할 수 있습니다.

필요한 경우 중복 열이 필요하지 않은 실제 모델을 작성할 때 중복 측량 ID 필드를 제거하십시오. 아시다시피, 두 모델 모두 문제가 있지만 첫 번째 모델이 전반적으로 더 좋습니다.


통찰력에 감사드립니다-물리적 모델에서 1 열로 축소하여 원하는 모든 것을 시행했습니다.
deadcode
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.