Anketler, Sorular ve Yanıtlar hakkında bir veritabanında gereksiz yabancı anahtarları işlemek için en iyi veri modelleme yaklaşımı


13

Mağaza anketleri, sorular ve yanıtlar için en iyi ilişkisel modelleme yaklaşımı hakkında tavsiye arıyorum.

Aşağıdaki iki yaklaşımdan hangisinin en iyi göründüğünü ya da her ikisine alternatif bir yaklaşım arıyorum.

En azından şu varlıklarım var:

  • soru
  • anket
  • kişi

Ve en azından şu ilişkiler:

  • Her anketin 1 veya daha fazla sorusu vardır.
  • Her soru 0 veya daha fazla ankette kullanılabilir.
  • Her kişi 0 veya daha fazla anket alabilir.

İşte burada sorun yaşıyorum: Bir kişi tarafından yapılan anket sorularına verilen yanıtların modellenmesi.

İşte, ikisi de benim için çok iyi gözükmeyen iki yaklaşım. Buradaki diyagramlar sorunu göstermek için büyük ölçüde basitleştirilmiştir.

Yaklaşım 1: Yaklaşım 1

Bu yaklaşımla ilgili sevmediğim şeyler:

  • survey_person_question_responseTablo anket için iki farklı sütun vardır: survey_question_survey_idvesurvey_person_survey_id
    • Bu survey_idiki sütun için bir satırda farklı referanslara başvurmak hata olur . Anket_sorusu, ankete katılan kişinin aldığı anketle aynı olmalıdır. Bunu uygulamak için iyi bir yol göremiyorum.
  • Burada yaptığım iki ilişki arasında bir ilişki kurmak gibi görünüyor. Bu bir sebepten dolayı bana yanlış geliyor.

Yaklaşım 2:

Aynı değere değinmesi gereken yaklaşım 1'den iki FK'den kaçınmaya çalışın ... resim açıklamasını buraya girin

Bu yaklaşımla ilgili sevmediğim şeyler:

  • question_idVe survey_idFK'lerin geçerli bir survey_questionçiftten geldiği konusunda bir yaptırım yoktur
  • survey_idVe person_idFK'lerin geçerli bir survey_personçiftten geldiği konusunda bir yaptırım yoktur

Herhangi bir tavsiye:

  • Bu yaklaşımlardan birinin tipik bir yaklaşım olup olmadığı
  • Bu yaklaşımlardan birinin diğerine artı ve eksileri
  • Bu verileri tamamen düzenlemenin daha iyi bir yolu

Büyük mutluluk duyacağız!

Yanıtlar:


12

Şartnameleri anladığım kadarıyla, iş ortamınız kavramsal düzeyde üçlü bir ilişki içerir . Bu bağlamda, şunları tanımlamanız gerekir:

  1. Kişi ve Anket varlık türleri arasındaki ilişki (veya ilişki ) türü ;
  2. Anket ve Soru arasındaki ilişki türü ;
  3. söz konusu iki ilişki türü arasındaki bir ilişkiyi ve sonuç olarak Kişi , Anket ve Soru , yani Yanıt (benim görüşüme göre yorumu basitleştiren daha kısa bir ad) arasındaki ilişki türü .

Bu nedenle, Yaklaşım 1'inizle doğru yolda olduğunuzu düşünüyorum , ancak daha doğru hale getirmek için bazı küçük (ancak önemli) ayrıntılandırmalar gerektiriyor. İlerleyen bölümlerde bu tür ayrıntılandırmaları ve diğer ilgili hususları ayrıntılarıyla açıklayacağım.

İş kuralları

Geçerli iş kurallarını biraz genişletelim ve bunları aşağıdaki şekilde yeniden formüle edelim:

  • Bir Kişi Sıfır Bir veya Çok Ankete Kayıt Olur
  • Bir Anket , sıfır bir veya birçok Kişinin kaydını alır
  • Bir Anketi bire birçok kişi tarafından entegre edilmiştir Sorular
  • Bir Soru, sıfır bir veya birçok Anketi entegre eder
  • Bir Soruya sıfır bir veya birden fazla Yanıt verilir
  • Tam olarak bir Kişi tarafından tam olarak bir Anket kapsamında bir Yanıt verilir

Açıklayıcı IDEF1X diyagramı

Daha sonra, IDEF1X'i yukarıda formüle edilen iş kurallarını sentezleyen Şekil 1'de sunulan bir diyagram oluşturdum :

Şekil 1 Basitleştirilmiş Anket IDEF1X


a Bilgi Modelleme için Entegrasyon Tanımı ( IDEF1X ),Aralık 1993'te Amerika Birleşik Devletleri Ulusal Standartlar ve Teknoloji Enstitüsü ( NIST )tarafından standart olarak oluşturulmuş, oldukça tavsiye edilebilir bir modelleme tekniğidir. Bu sağlam tarafından kaleme teorik çalışmalarına dayanan tek kurucusu ve ilişkisel modeli yani, Dr EF Codd da ve varlık-ilişki bakış tarafından geliştirilen Dr PP Chen .


PersonSurvey ilişki

Gördüğüm gibi, PersonSurvey ilişkisinin bir Kişinin belirli bir Ankete katılabilmesi için bir yetkilendirme aracı sağlaması gerekir . Belli bir kez bu şekilde, Kişi spesifik bir tescil edilmiştir Araştırması , o sunmaya yetkili Yanıtları için Sorular İlgili entegre Anketi .

SurveyQuestion ilişki

Şemanızda suvery_question.question_number adı verilen özelliğin (veya özniteliğin) belirli bir Ankete göre belirli bir Soru örneğinin sunum sırasını temsil etmek için kullanıldığını varsayıyorum . Gördüğünüz gibi, SurveyQuestion.PresentationOrder gibi bir özelliği gösterdim ve (i) iki veya daha fazla Question.QuestionNumber değeri (iii) aynı SurveyQuestion oluşumunda aynı PresentationOrder değerini paylaşmasını önlemeniz gerektiğini düşünüyorum .

İhtiyaç olanı tasvir etmek için, bu varlık türünü temsil eden, özelliklerin kombinasyonundan ( SurveyNumber, QuestionNumber, PresentationOrder ) oluşan bir kompozit ALTERNATE KEY (AK) ekledim . İyi bildiğiniz gibi, bir bileşik AK, çok sütunlu bir UNIQUE kısıtlaması yardımıyla mantıklı bir DDL tasarımında bildirilebilir ( SurveyQuestionaçıklayıcı DDL düzeninin bir parçası olan tabloda örneklediğim gibi, aşağıdaki birkaç bölüm açıklanmıştır).

Tepki varlık türü

Evet, Yanıt varlık türü ile diğer iki ilişki arasındaki ilişkiyi tasvir ediyorum ; o olabilir ilk bakışta garip görünebilir ama hiçbir şey yanlış sürece, (a) doğru çıkar ve (b) 'nin iş bağlamında özelliklerini temsil eden bir mantıksal düzey düzeninde düzgün temsil edilir edilmez, bu yaklaşımla yoktur.

Evet, tamamen haklısınız, senaryonun o kısmını mantıksal soyutlama düzeyinde aynı satırdaki iki farklı sütundan referans alan iki Response.SurveyNumber(veya, örneğin Response.SurveyId) değerle tasvir etmek hata olur Response.

Türetilmiş mantıksal SQL-DDL düzeni

-- 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)
);

ResponseTablodaki iki bileşik DIŞ ANAHTARLARI

Muhtemelen tartışılması gereken en önemli nokta budur: belirli bir Responsesatırdan yapılan referanslar

  1. SurveyQuestion.SurveyNumber, ve
  2. SurveyPerson.SurveyNumber

eşleşen değerlere sahip olmalıdır . Bu konuda açıklayıcı bir şekilde bu koşulu uygulamak için en iyi seçenek iki kompozit YABANCI TUŞ (FK) kullanmaktır.

DDL tasarımında gösterildiği gibi, ilk FK PersonSurveytablo PRIMARY KEY (PK), yani (PersonId, SurveyNumber), ve referans sütunları ile uyumludur Response.PersonIdve ve Response.SurveyNumber.

İkinci FK, SurveyQuestionPK tablosunu işaret eder , yani (SurveyNumber, QuestionNumber), ve buna göre, sütunlardan Response.SurveyNumberve Response.QuestionNumber.

Bu şekilde, Response.SurveyNumbersütun iki farklı kısıtlamada FK referansının bir parçası olarak kullanıldığından oldukça etkilidir.

Bu yöntemle, tek garanti veri tabanı yönetim sistemi garantili bilgi tutarlılığı gelen

  • (a) Responseiçin PersonSurvey;
  • (b) Responseiçin SurveyQuestion; ve
  • (c) bağımsız bir varlık tür, yani bekletildikten tablolara bir birleştirici işletme türü temsil tabloların her birinde Person, Surveyve Question.

Güncelleme anormalliklerinden kaçınmak için türetilmiş veriler

Diyagramınızda saygın olduğum iki unsuru fark ettim. Bu öğeler türetilebilenPersonSurvey ( türetilmesi gereken) iki sütunla ilişkilidir .

Bu bağlamda, sen türetebilirsiniz PersonSurvey.IsStartedbir verilirse sorgulama tarafından verisini Personolay daha bir veya sağlamıştır Responsesiçin Questionso kesin bir entegre Surveyyoluyla SurveyQuestionmasaya.

Ayrıca , belirli bir satırdaki sütunda 'DOĞRU' değerini tutan tüm örneklere PersonSurvey.IsCompletedbelirli bir Personörneğin bir a sağlayıp sağlamadığını belirleyerek veri noktasını da elde edebilirsiniz .ResponseQuestionsIsMandatorySurveyQuestion

Bu değerlerin türetilmesi yoluyla, bu değerleri SurveyQuestionsütunda tutmanız durumunda ortaya çıkacak bazı güncelleme anormalliklerini önlersiniz .

Önemli husus

As @Dave haklı onun yorumunda işaret Yönetmeye tarihleri, sayısal değerler, çoktan seçmeli, ve başka olası yönlerini ima yanıtların farklı türde yönetimini talep eden bir gelecek talebi yüz ise, bu veritabanı düzenini uzatmak zorunda kalacaktır.


1
Vay, bu kafamdaki soruyu mükemmel bir şekilde yanıtladı ve sonra bana daha fazlasını öğretti! Yorumlar iyileştirme önerdiğinden: Anahtarların her ikisiyle de bitmesi biraz kafa karıştırıcıydı IDve Numberaksi halde bu harika. Teşekkür ederim.
Zach Mierzejewski

@Zach Çok hoş geldiniz, gönderinin size yardımcı olduğu için memnunum. Geri bildiriminiz için teşekkür ederiz, bazı ayrıntılandırmalar kesinlikle istenmektedir.
MDCCL

1

Bu, sütunları yabancı anahtar olarak taşırken önek eklemek istemememin bir nedenidir. İlk durumda, modelleme aracı sizi tablodaki survey_idsütunlardan birine önek eklemeye zorlayabilir survey_person_question_response. İlişki kurulduktan sonra bunu ayarlayabilirsiniz.

Gerekirse, çoğaltılan sütuna ihtiyacınız olmayan fiziksel modeli oluştururken yedek anket kimliği alanını kaldırın. Tanımladığınız gibi, her iki modelinizin de sorunları var, ancak ilk modelin genel olarak daha iyi olduğuna inanıyorum.


Anlayışınız için teşekkürler - Fiziksel modelde istediğim her şeyi uygulayan 1 sütuna çöktüm.
deadcode
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.