Projekt bazy danych dla ankiety [zamknięty]

129

Muszę utworzyć ankietę, w której odpowiedzi są przechowywane w bazie danych. Zastanawiam się tylko, jaki byłby najlepszy sposób zaimplementowania tego w bazie danych, a konkretnie w wymaganych tabelach. Ankieta zawiera różne rodzaje pytań. Na przykład: pola tekstowe na komentarze, pytania wielokrotnego wyboru i ewentualnie pytania, które mogą zawierać więcej niż jedną odpowiedź (tzn. Zaznacz wszystkie pasujące odpowiedzi).

Wymyśliłem dwa możliwe rozwiązania:

  1. Utwórz olbrzymią tabelę zawierającą odpowiedzi dla każdego przesłanego ankiety. Każda kolumna odpowiadałaby odpowiedzi z ankiety. tj. SurveyID, Answer1, Answer2, Answer3

    Nie sądzę, aby to był najlepszy sposób, ponieważ w tej ankiecie jest wiele pytań i nie wydaje się zbyt elastyczna, jeśli ankieta ma się zmienić.

  2. Inną rzeczą, o której myślałem, było utworzenie tabeli pytań i tabeli odpowiedzi. Tabela pytań zawierałaby wszystkie pytania do ankiety. Tabela odpowiedzi zawierałaby indywidualne odpowiedzi z ankiety, a każdy wiersz byłby powiązany z pytaniem.

    Prosty przykład:

    tblSurvey : SurveyID

    tblQuestion : QuestionID, SurveyID , QuestionType, Pytanie

    tblAnswer : AnswerID, UserID , QuestionID , Answer

    tblUser : ID użytkownika, nazwa użytkownika

    Mój problem z tym polega na tym, że może istnieć mnóstwo odpowiedzi, co spowodowałoby, że tabela odpowiedzi byłaby całkiem ogromna. Nie jestem pewien, czy to takie świetne, jeśli chodzi o wydajność.

Byłbym wdzięczny za wszelkie pomysły i sugestie.

Michael
źródło
Ile jest „całkiem duże”? Daj nam oszacowanie, czy mówimy o milionie czy tysiącach milionów?
Jorge Córdoba
1
Serwery SQL są tak naprawdę zaprojektowane do pracy z „tonami” danych. Nie powinieneś mieć większych problemów z pracą ze schematem, o którym mówiłeś.
Chris

Odpowiedzi:

122

Myślę, że twój model nr 2 jest w porządku, jednak możesz przyjrzeć się bardziej złożonemu modelowi, który przechowuje pytania i gotowe odpowiedzi (oferowane odpowiedzi) i pozwala na ich ponowne wykorzystanie w różnych ankietach.

- Jedna ankieta może mieć wiele pytań; jedno pytanie może zostać (ponownie) użyte w wielu ankietach.
- Na wiele pytań można udzielić jednej (gotowej) odpowiedzi. Jedno pytanie może mieć wiele odpowiedzi. Pytanie może mieć różne odpowiedzi oferowane w różnych ankietach. W różnych ankietach można udzielić odpowiedzi na różne pytania. Istnieje domyślna odpowiedź „Inne”, jeśli osoba wybierze inną, jej odpowiedź jest zapisywana w Answer.OtherText.
- Jedna osoba może uczestniczyć w wielu ankietach, jedna osoba może odpowiedzieć na określone pytanie w ankiecie tylko raz.

Survey_model_02

Damir Sudarevic
źródło
1
jakiego narzędzia użyłeś do stworzenia schematu bazy danych?
AndHeiberg
Używam Altova UModel. Jest szybki, oferuje szeroki wybór struktur modelowania i zapisuje w prawie każdym formacie. Chociaż to kosztuje.
obimod
9
Możesz także skorzystać z draw.io. Jest darmowy bez rejestracji i łatwy w użyciu.
usr4896260
3
Dlaczego mamy Survey_Question_Answeri Answer? Czy to nie Answerwystarczy?
Abubakar Ahmad
1
Myślę, że Answerwystarczy, Survery_question_answerjest zbędny
Batman
62

Mój projekt jest pokazany poniżej.

Najnowszy skrypt tworzenia znajduje się pod adresem https://gist.github.com/durrantm/1e618164fd4acf91e372

Skrypt i plik mysql workbench.mwb są również dostępne pod
adresem https://github.com/durrantm/survey wprowadź opis obrazu tutaj

Michael Durrant
źródło
Cześć, podoba mi się twój projekt. Czy masz jakieś próbki danych (zrzuty) dla tabel? Naprawdę doceni
Emeka Mbah
Cześć! Po pierwsze dzięki za Twoją pracę. Czy rozważałeś może hierachie w jednym ze swoich szablonów? Użytkownicy zwykle podają informacje o swoim przywódcy, a ci liderzy mają informacje o swoich liderach i tak dalej. Użytkownicy pracują w różnych sekcjach (HR, produkcja) i te również mogą mieć hierarchię. Dlatego podczas raportowania często konieczne jest rozróżnienie między tymi poziomami organizacji.
ruedi
@michael: To naprawdę pomocne. czy masz jakieś referencje / linki github do java przy użyciu spring?
Sagar Panda
Ja wciąż próbuje dowiedzieć się, jaka jest różnica między option_groupsa option_choicesi jakie ma to zastosowanie.
PHPnoob
@PHPnoob Myślę, że to, jak nazwa sugeruje, po prostu grupuje opcje. Więc jeśli możesz np. Ocenić od 1 do 5, to option_groupspowinieneś pozwolić ci dokładnie to, jeśli robię to dobrze.
displayname
18

Zdecydowanie opcja nr 2, również myślę, że możesz mieć przeoczenie w obecnym schemacie, możesz potrzebować innej tabeli:

+-----------+
| tblSurvey |
|-----------|
| SurveyId  |
+-----------+

+--------------+
| tblQuestion  |
|--------------|
| QuestionID   |
| SurveyID     |
| QuestionType |
| Question     |
+--------------+

+--------------+
| tblAnswer    |
|--------------|
| AnswerID     |
| QuestionID   |
| Answer       |
+--------------+

+------------------+
| tblUsersAnswer   |
|------------------|
| UserAnswerID     |
| AnswerID         |
| UserID           |
| Response         |
+------------------+

+-----------+
| tblUser   |
|-----------|
| UserID    |
| UserName  |
+-----------+

Każde pytanie będzie prawdopodobnie miało określoną liczbę odpowiedzi, z których użytkownik może wybrać, a następnie rzeczywiste odpowiedzi będą śledzone w innej tabeli.

Bazy danych są zaprojektowane do przechowywania dużej ilości danych, a większość z nich jest bardzo dobrze skalowalna. Nie ma już rzeczywistej potrzeby używania mniejszego, normalnego formularza, aby zaoszczędzić miejsce.

tplaner
źródło
Cześć, mam pytanie. Czy SurveyId nie powinien być obecny również w tabeli odpowiedzi, czy przynajmniej znacznik czasu odpowiadający czasowi wersjonowania ankiety? Jeśli wstawisz pytanie do swojej oryginalnej ankiety, questionIds ulegną zmianie, a odpowiedzi staną się niemożliwe do zidentyfikowania. A jeśli jest zbędny, czy mógłbyś wyjaśnić, jak to zrobić?
Shubham
3

Zasadniczo modyfikowanie schematu w oparciu o coś, co użytkownik mógłby zmienić (na przykład dodanie pytania do ankiety), należy uznać za dość śmierdzące. Są przypadki, w których może to być odpowiednie, szczególnie w przypadku dużych ilości danych, ale zanim się zagłębisz, wiedz, w co się pakujesz. Posiadanie tylko tabeli „odpowiedzi” dla każdej ankiety oznacza, że ​​dodawanie lub usuwanie pytań jest potencjalnie bardzo kosztowne i bardzo trudno jest przeprowadzać analizy w sposób niezależny od pytań.

Myślę, że twoje drugie podejście jest najlepsze, ale jeśli masz pewność, że będziesz mieć wiele problemów związanych ze skalą, jedną rzeczą, która zadziałała dla mnie w przeszłości, jest podejście hybrydowe:

  1. Utwórz szczegółowe tabele odpowiedzi, aby przechowywać odpowiedzi na pytania, jak opisano w punkcie 2. Te dane na ogół nie byłyby pobierane bezpośrednio z aplikacji, ale byłyby używane do generowania danych podsumowujących dla tabel raportowania. Prawdopodobnie chciałbyś również zaimplementować jakąś formę archiwizacji lub niszczenia tych danych.
  2. W razie potrzeby utwórz również tabelę odpowiedzi od 1. Można tego użyć, gdy użytkownicy chcą zobaczyć prostą tabelę wyników.
  3. W przypadku wszelkich analiz, które należy wykonać do celów raportowania, zaplanuj zadania, aby utworzyć dodatkowe dane podsumowujące na podstawie danych z 1.

Jest to absolutnie dużo więcej pracy do wykonania, więc naprawdę nie radziłbym tego, chyba że wiesz na pewno, że ta tabela napotka problemy na ogromną skalę.

Ryan Brunner
źródło
1

Drugie podejście jest najlepsze.

Jeśli chcesz go bardziej znormalizować, możesz utworzyć tabelę dla typów pytań

Proste rzeczy do zrobienia to:

  • Umieść bazę danych i zaloguj się na własnym dysku, a nie domyślnie na dysku C.
  • Utwórz bazę danych tak dużą, jak potrzeba, aby nie mieć przerw na rozbudowę bazy danych

Mieliśmy tabele dziennika w SQL Server Table zawierające 10 milionów wierszy.

Shiraz Bhaiji
źródło
1

Nr 2 wygląda dobrze.

W przypadku tabeli zawierającej tylko 4 kolumny nie powinno to stanowić problemu, nawet przy dobrych kilku milionach wierszy. Oczywiście może to zależeć od używanej bazy danych. Jeśli jest to coś w rodzaju SQL Server, nie byłoby problemu.

Prawdopodobnie chciałbyś utworzyć indeks w polu QuestionID w tabeli tblAnswer.

Oczywiście musisz określić, z jakiej bazy danych korzystasz, a także szacowane ilości.

kevchadders
źródło
0

Jak na prostą ankietę wygląda całkiem kompletnie. Nie zapomnij dodać tabeli dla „otwartych wartości”, w której klient może wyrazić swoją opinię za pośrednictwem pola tekstowego. Połącz tę tabelę kluczem obcym z odpowiedzią i umieść indeksy we wszystkich kolumnach relacyjnych, aby zwiększyć wydajność.

Ben Fransen
źródło
1
Czy istnieje powód, dla którego nie mogłem umieścić komentarzy również w tabeli odpowiedzi?
Michael
0

Numer 2 jest poprawny. Używaj prawidłowego projektu, dopóki nie wykryjesz problemu z wydajnością. Większość RDBMS nie będzie miała problemu z wąskim, ale bardzo długim stołem.

Larry Lustig
źródło
0

Posiadanie dużego stołu odpowiedzi samo w sobie nie stanowi problemu. Tak długo, jak indeksy i ograniczenia są dobrze zdefiniowane, wszystko powinno być w porządku. Twój drugi schemat wygląda dobrze.

Dave Swersky
źródło
0

Mając właściwy indeks, Twoje drugie rozwiązanie jest znormalizowane i dobre dla tradycyjnego systemu relacyjnych baz danych.

Nie wiem, jak ogromne jest ogromne, ale powinno bez problemu pomieścić kilka milionów odpowiedzi.

Jorge Córdoba
źródło
0

Możesz zapisać cały formularz jako ciąg JSON.

Nie jestem pewien co do Twoich wymagań, ale to podejście zadziała w niektórych okolicznościach.

mriiiron
źródło