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.


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


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


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.


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ę.


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.


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.


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ść.


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.


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.


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.