Struktura bazy dla aplikacji quiz

0

Cześć,
potrzebuje porady odnośnie struktury bazy, a mianowicie tego jak będzie wygodniej i wydajniej. Głównie chodzi o odpowiedzi z forma w formie booleanów, których może być około 50.

Zebrać wszystkie odpowiedzi i pakować do jednej kolumny z użyciem datatransformera czy seralizera, czy lepiej tworzyć kolumny osobno dla każdej odpowiedzi? Jeżeli jedno lub drugie to dlaczego?

Później te dane będą wykorzystywane do podsumowania.

0
kakaraper napisał(a):

Cześć,
potrzebuje porady odnośnie struktury bazy, a mianowicie tego jak będzie wygodniej i wydajniej. Głównie chodzi o odpowiedzi z forma w formie booleanów, których może być około 50.

Zebrać wszystkie odpowiedzi i pakować do jednej kolumny z użyciem datatransformera czy seralizera, czy lepiej tworzyć kolumny osobno dla każdej odpowiedzi? Jeżeli jedno lub drugie to dlaczego?

Później te dane będą wykorzystywane do podsumowania.

Z punktu widzenia aplikacji to i tak wszystko jedno, bo powinieneś mieć odpowiednio odseparowaną warstwę persystencji od logiki.

Z punktu widzenia samej bazy, to pytanie czy będziesz chciał pisać zapytania bazodanowe mające różne zasady dla różnych kolumn, czy raczej będziesz traktował je tak samo. Jeśli tak samo, to możesz wrzucić do "jednego wora".

0

Tak, logika będzie odseparowana. Chyba zrobię jak mówisz, ale do tego dorzucę segregacje "worów". Czy byłby osobno czy w jednym i tak byłby zawsze grupowane, więc wydaje mi się, że to będzie odpowiednie podejście.

0

skąd te booleany ci się biorą? W sensie zakładasz, że każde pytanie będzie miało 2 możliwe odpowiedzi tak lub nie?

0

@kakaraper: Ale czemu chcesz utrudniać sobie pakując wszystko do jednego wora? Ja bym odrzucił i pierwszy i drugi pomysł szczególnie, że chcesz później to podsumowywać. Masz tabelę quizy i do niej relacje quizy_pytania oraz quizy_odpowiedzi. Później robienie jakichkolwiek statystyk (czy tam sumowań) będzie już bardzo proste.

0
leonpro778 napisał(a):

@kakaraper: Ale czemu chcesz utrudniać sobie pakując wszystko do jednego wora? Ja bym odrzucił i pierwszy i drugi pomysł szczególnie, że chcesz później to podsumowywać. Masz tabelę quizy i do niej relacje quizy_pytania oraz quizy_odpowiedzi. Później robienie jakichkolwiek statystyk (czy tam sumowań) będzie już bardzo proste.

Ale praca z wieloma tabelami i kolumnami też ma swoje problemy, których by nie miał gdyby miał wszystko w jednym worku.

Tak na prawdę wszystko się sprowadza czy te dane są do siebie sampodobne (i wszystkie/większość operacji i tak będzie agregowana), czy są od siebie różne i operacje nie będą takie same. Jeśli tak, to lepiej wszystko do jednego wora, jeśli nie to lepiej zrobić osobne kolumny.

0

@Riddle: Ale trzy tabele w takich relacjach to moim zdaniem mniejsze problemy niż trzymanie wszystkich odpowiedzi w "jednym woroku". Weź sobie później sytuację, że chcesz wyświetlić ile osób z quizu szóstego wybrało odpowiedź NIE w pytaniu 17. Trzymając to w "jednym worku" to dopiero będzie problemów. Można by się jeszcze pokusić o Data Type JSON w MySql i dopiero wrzucać to do wora.

Jedno się na pewno zgadzam, nie znamy jakie to będą pytania i co później ma się z tym dziać.

0
leonpro778 napisał(a):

@Riddle: Ale trzy tabele w takich relacjach to moim zdaniem mniejsze problemy niż trzymanie wszystkich odpowiedzi w "jednym woroku". Weź sobie później sytuację, że chcesz wyświetlić ile osób z quizu szóstego wybrało odpowiedź NIE w pytaniu 17. Trzymając to w "jednym worku" to dopiero będzie problemów. Można by się jeszcze pokusić o Data Type JSON w MySql i dopiero wrzucać to do wora.

Jedno się na pewno zgadzam, nie znamy jakie to będą pytania i co później ma się z tym dziać.

Czy Ty rozumiesz co napisałem wyżej?

Riddle napisał(a):

Tak na prawdę wszystko się sprowadza czy te dane są do siebie samopodobne (i wszystkie/większość operacji i tak będzie agregowana), czy są od siebie różne i operacje nie będą takie same. Jeśli tak, to lepiej wszystko do jednego wora, jeśli nie to lepiej zrobić osobne kolumny.

Zwłaszcza zwróć uwagę na tekst "czy te dane są do siebie samopodobne (...), czy są od siebie różne i operacje nie będą takie same."

Ty, pisząc "Weź sobie później sytuację, że chcesz wyświetlić ile osób z quizu szóstego wybrało odpowiedź NIE w pytaniu 17" mówisz o sytuacji w których te dane są różne od siebie, i trzymanie ich w osobnych kolumnach ma sens.

Ale nie wiemy jaki jest zamysł aplikacji autora, bo możliwe że to będą pytanie które spokojnie można reprezentować listą key-value pair, i wtedy dodawanie kolumn i relacji to będzie niepotrzebny narzut pracy.

0

@Riddle: Ja zrozumiałem co napisałeś i to bardzo dokładnie ale chyba Ty nie zrozumiałeś komplikacji "pakowania wszystkiego do jednego wora". Uprośćmy ten quiz najbardziej jak się da, czyli. Mamy w jednym quizie DWA pytania. Na każde pytanie dajesz TAK lub NIE. Mamy dwóch użytkowników, którzy wypełnili quiz i teraz wrzuć wyniki tego quizu "do jednego wora". Przecież to już jest pomieszane.

0
leonpro778 napisał(a):

@Riddle: Ja zrozumiałem co napisałeś i to bardzo dokładnie ale chyba Ty nie zrozumiałeś komplikacji "pakowania wszystkiego do jednego wora". Uprośćmy ten quiz najbardziej jak się da, czyli. Mamy w jednym quizie DWA pytania. Na każde pytanie dajesz TAK lub NIE. Mamy dwóch użytkowników, którzy wypełnili quiz i teraz wrzuć wyniki tego quizu "do jednego wora". Przecież to już jest pomieszane.

Nie zrozumiałeś i myślę, że jesteś bardzo nierozważny, jeśli myślisz że zasugerowałbym rozwiązanie, które nie będzie działać - np nie będzie się dało rozróżnić który użytkownik udzielił odpowiedzi.

Mówiąć "dodać do jednego wora" miałem na myśli wrzucenie użytkowników, odpowiedzi i pytań do jednej tabelki: możesz to trzymać w tabelce data, z kolumnami user, question oraz answer - w takiej tabelce widać który user udzielił jakiej odpowiedzi na które pytanie, nie ma żadnego pomieszania. Nie potrzebujesz do tego robić tabelek: users, questions oraz answers każdej ze swoim id i wartościami, dodawać do nich indeksów, relacji, autoincreamentów i pisać JOIN'ów żeby coś wyciągnąć.

0

@Riddle: Zasugerowałem się tym "Zebrać wszystkie odpowiedzi i pakować do jednej kolumny z użyciem datatransformera czy seralizera" i przy tym odpisałeś "to możesz wrzucić do "jednego wora"."

I z tego mi wyszło, że dla Ciebie również kolumna === "jeden wór" a teraz ok, widzę, że Tobie również chodziło o to, że tabela === "jeden wór". W tym momencie w moim pomyśle tabela quizy_odpowiedzi jest odpowiednikiem tabeli data z Twojego pomysłu z tą różnicą, że ja swoje rozwiązanie rozszerzyłem o tabelę quizy i quizy_pytania (a to tylko dlatego, że wiem jakby mi było łatwiej przedstawić to po froncie ewentualnie później modyfikować).

0
leonpro778 napisał(a):

I z tego mi wyszło, że dla Ciebie również kolumna === "jeden wór" a teraz ok, widzę, że Tobie również chodziło o to, że tabela === "jeden wór". W tym momencie w moim pomyśle tabela quizy_odpowiedzi jest odpowiednikiem tabeli data z Twojego pomysłu z tą różnicą, że ja swoje rozwiązanie rozszerzyłem o tabelę quizy i quizy_pytania (a to tylko dlatego, że wiem jakby mi było łatwiej przedstawić to po froncie ewentualnie później modyfikować).

No i właśnie to rozszerzenie o tabelę quizy i quizy pytania moim zdaniem może być nadmiarowe, i właśnie tego sugerowałem nie robić. A to czy byłoby to łatwiej przedstawić na froncie nie ma znaczenia, bo i tak struktura tabeli w żaden sposób nie powinna wpyłnąć na to co front dostaje.

0

Rozwieje wątpliwości odpowiedzią na to jak ma działać:
każdy użytkownik udziela odpowiedzi na 3 zestawy pytań (po x w każdym), tylko i wyłącznie w postaci tak/nie. Wynik na końcu jest na zasadzie zsumowania (stad booleany). Nic skomplikowanego. Sprawdzam dane konkretnego usera z tabeli i na ich podstawie prezentuje wynik. Raczej zdecyduje się na jedna tabele w której będą paczki odpowiedzi.

Teraz pytanie numer dwa, w sumie może ciekawsze. Gdzie czasowo przechować dane usera, żebym mógł je dalej złapać na samym końcu po zapisaniu bazy.
Czy wepchanie tego do requesta będzie złym pomysłem? (Symfony)

0
kakaraper napisał(a):

Teraz pytanie numer dwa, w sumie może ciekawsze. Gdzie czasowo przechować dane usera, żebym mógł je dalej złapać na samym końcu po zapisaniu bazy.
Czy wepchanie tego do requesta będzie złym pomysłem? (Symfony)

Jeśli userzy mają być zalogowani, to w sesji.

0

Jeśli userzy mają być zalogowani, to w sesji.

Właśnie nie, nie loguje ich. Trzymam ich dane, uzupełniają formy i tyle.
O to chodzi, żeby wrzucili raz informacje o sobie i nie musieli na wstępie każdego forma wpisywać tego samego od nowa, a ja żebym wiedział kto uzupełnił.

0
kakaraper napisał(a):

Jeśli userzy mają być zalogowani, to w sesji.

Właśnie nie, nie loguje ich. Trzymam ich dane, uzupełniają formy i tyle.
O to chodzi, żeby wrzucili raz informacje o sobie i nie musieli na wstępie każdego forma wpisywać tego samego od nowa, a ja żebym wiedział kto uzupełnił.

No, w porządku, ale tak zapytam tylko profilaktycznie: Wiesz, że jeśli ich nie zalogujesz to jeden user może wysłać swoje odpowiedzi każdą jako inny user? Innymi słowy userzy będą się mogli bez żadnych przeszkód podszywać pod siebie.

Mógłbyś temu przeciwdziałać, że w momencie w którym user zaczyna uzupełniać quiz, to server odsyła na front pewien token, i każda kolejna odpowiedź musi zawierać ten token - bez niego odpowiedź nie jest zaliczana. Oczywiście jeśli nie logujesz, to jeśli ktoś zgubi ten token (zamknie karte, będę chciał odpowiedzieć z innego komputera), to będzie musiał zacząć od nowa jako zupełnie nowy user. Temu mógłbyś przeciwdziałać dodając nazwę usera, tylko wtedy znowu można się pod siebie podszywać, więc musiałbyś dodać też hasło, i wtedy w zasadzie masz logowanie.

0

No, w porządku, ale tak zapytam tylko profilaktycznie: Wiesz, że jeśli ich nie zalogujesz to jeden user może wysłać swoje odpowiedzi każdą jako inny user? Innymi słowy userzy będą się mogli bez żadnych przeszkód podszywać pod siebie.

Mam tego świadomość. Takie są wymagania, nie ja je ustalałem. Nie ma logowania, „walidacja usera” to te podawane na początku dane, które co ciekawe na samym końcu można zresetować i wypełnić jeszcze raz jako ten sam albo inny user

0
kakaraper napisał(a):

No, w porządku, ale tak zapytam tylko profilaktycznie: Wiesz, że jeśli ich nie zalogujesz to jeden user może wysłać swoje odpowiedzi każdą jako inny user? Innymi słowy userzy będą się mogli bez żadnych przeszkód podszywać pod siebie.

Mam tego świadomość. Takie są wymagania, nie ja je ustalałem. Nie ma logowania, „walidacja usera” to te podawane na początku dane, które co ciekawe na samym końcu można zresetować i wypełnić jeszcze raz jako ten sam albo inny user

A są jakieś restrykcje na temat np kolejności odpowiadania na pytania, nt tego czy można nadpisać jedno konkretne pytanie, etc.? Czy całkowicie wolna amerykanka?

0

@Riddle:
Pytania będą pogrupowane w paczki, nie da się zapisać bez przejścia przez cały jeden segment. Na którym zaczniesz i którym skończysz nie ma znaczenia, wynik jest i tak na końcu jak całość jest wypełniona.

Moze do jakiegoś local storage wrzucić te ich dane, wtedy mógłbym je łapać po tym jak zamknie kartę i wróci w innym terminie.

0
kakaraper napisał(a):

@Riddle:
Pytania będą pogrupowane w paczki, nie da się zapisać bez przejścia przez cały jeden segment. Na którym zaczniesz i którym skończysz nie ma znaczenia, wynik jest i tak na końcu jak całość jest wypełniona.

Moze do jakiegoś local storage wrzucić te ich dane, wtedy mógłbym je łapać po tym jak zamknie kartę i wróci w innym terminie.

No pytanie też czy chcesz zapisać w bazie niedokończone zestawy.

0

@Riddle:

Jeśli miałbym chcieć to musiałbym zrezygnować z booli, bo one domyślnie byłyby wypełnione na nie i psułyby wynik.

W sumie mógłbym je zapisywać jako tekst z domyślnym nullem i wartościami tak/nie.

0
kakaraper napisał(a):

@Riddle:

Jeśli miałbym chcieć to musiałbym zrezygnować z booli, bo one domyślnie byłyby wypełnione na nie i psułyby wynik.

W sumie mógłbym je zapisywać jako tekst z domyślnym nullem i wartościami tak/nie.

Ale czemu, mógłbyś po prostu nie dodawać recordu dla pytania które nie ma odpowiedzi? Brak rekordu == brak odpowiedzi.

0

zwyczajnie do odpowiedzi o danhm id wstawiasz do tabeli klucz => wartosc.
Tabela z pytaniami

Id Question
1 Czy lubisz ibisza?

Tabela z odpowiedziami

Id Id_Question key value
1 1 an_yes 0
2 1 an_no 1
0

@Riddle:
Ale czemu, mógłbyś po prostu nie dodawać recordu dla pytania które nie ma odpowiedzi? Brak rekordu == brak odpowiedzi.

Do tego musiałbym już operować na dwóch tabelach, co w sumie nie było by problemem.

Na początku myślałem, że wrzucę wszystko do jednego rowa, dane usera + paczki pytań wypełnione jako arraye (w osobnych kolumnach). Jakieś rozwiązanie to jest, ale zastanawiam się teraz nad zapisaniem usera i nadaniem mu uuid, a potem to id dodawać do odpowiedzi tak jak zasugerował @chomikowski ale już w postaci kolejnych rekordów w innej tabeli.

Wtedy na podstawie uuid sprawdzam ile ma odpowiedzi i na co, a w users mam same dane użytkownika. Chyba, że źle to rozumuje, to proszę poprawcie mnie.

0
kakaraper napisał(a):

@Riddle:
Ale czemu, mógłbyś po prostu nie dodawać recordu dla pytania które nie ma odpowiedzi? Brak rekordu == brak odpowiedzi.

Do tego musiałbym już operować na dwóch tabelach, co w sumie nie było by problemem.

Na początku myślałem, że wrzucę wszystko do jednego rowa, dane usera + paczki pytań wypełnione jako arraye (w osobnych kolumnach). Jakieś rozwiązanie to jest, ale zastanawiam się teraz nad zapisaniem usera i nadaniem mu uuid, a potem to id dodawać do odpowiedzi tak jak zasugerował @chomikowski ale już w postaci kolejnych rekordów w innej tabeli.

Wtedy na podstawie uuid sprawdzam ile ma odpowiedzi i na co, a w users mam same dane użytkownika. Chyba, że źle to rozumuje, to proszę poprawcie mnie.

No możesz tak zrobić; ale nie sądzę że cokolwiek Ci to da. Tylko to że będziesz musiał zrobić JOIN'a podczas SELECT'a.

0

@Riddle:

Niby tak, ale posegreguje bazę przynajmniej. Pod względem performance’u pewnie wygodniej jednym selectem niż z joinem, ale tu nie będzie milionów rekordów, realnie parędziesiąt tysięcy, wiec nie biorę tego zbytnio pod uwagę.

Jak ty miałbyś zrobić to jak by to wyglądało?

0
kakaraper napisał(a):

@Riddle:

Niby tak, ale posegreguje bazę przynajmniej. Pod względem performance’u pewnie wygodniej jednym selectem niż z joinem, ale tu nie będzie milionów rekordów, realnie parędziesiąt tysięcy, wiec nie biorę tego zbytnio pod uwagę.

No, moim zdaniem takie "posegregowanie" nie ma specjalnego sensu u Ciebie.

kakaraper napisał(a):

Jak ty miałbyś zrobić to jak by to wyglądało?

Ja bym zaczął pisać testy od strony użytkowej, i zrobiłbym całą aplikację w ogóle bez bazy - wszystko in-memory. Potem mając aplikację działającą w pamięci, wiedziałbym dokładnie jak wygląda. Oczywiście jak zrestartuję apkę, to wszystkie dane znikają, więc krok drugi, trzeba dodać persystencję. Wybrałbym bazę która najbardziej pasuje do zadania, albo pliki, albo mongo, albo relacyjna, albo coś jeszcze innego. Pewnie wybrałbym mongo żeby zrobić to szybko, a potem ewentualnie dodałbym drugą implementację persystencji np na postgresie, gdzie byłaby jedna tabelka właśnie z wartościami user, question i answer. jeśli zajdzie potem potrzeba to zmienić, to nie będzie to specjalnie trudne.

0

@Riddle:
No, moim zdaniem takie "posegregowanie" nie ma specjalnego sensu u Ciebie.

gdzie byłaby jedna tabelka właśnie z wartościami user, question i answer. jeśli zajdzie potem potrzeba to zmienić, to nie będzie to specjalnie trudne.

User będzie mieć więcej danych niż samo username, będzie jeszcze mail, jakieś telefony i inne, stad pomysł o wyrzuceniu do „users”. Potem krótkie segmenty zakończone insertem do tabeli answers w której relacja będzie uuid.

Zastanawiam się jeszcze nad przesyłaniem informacji o userze między quizami, ale chyba zapakuje je do sesji i tyle. Powinno wystarczyć. Mogę jeszcze puszczać token, to do przemyślenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1