2010-04-12 9 views
7

Tło
Piszę ankietę, która trafi do dużej grupy odbiorców. Zawiera 15 pytań i jest pięć możliwych odpowiedzi na każde pytanie wraz z potencjalnymi komentarzami.Jaki byłby najlepszy sposób przechowywania pytań i odpowiedzi w ankiecie, w której muszę ograniczyć ruch do bazy danych do minimum?

Użytkownik może przejrzeć wszystkie 15 pytań odpowiadających na nie w dowolnej kolejności i może opuścić ankietę w dowolnym momencie i wrócić, aby odpowiedzieć na pozostałe pytania.

Po udzieleniu odpowiedzi na wszystkie 15 pytań pojawia się przycisk przesyłania, który pozwala przesłać pytania jako ostateczne odpowiedzi. Do tego etapu wszystkie odpowiedzi są wymagane do odzyskania za każdym razem, gdy użytkownik załaduje stronę ankiety.

Wymagane jest, aby użytkownik widział tylko jedno pytanie na stronie, a przyciski "Poprzedni" i "Następny" pozwalają użytkownikowi przewijać pytania.

Wymagania
mogę zażądać Pytanie każdym razem, gdy użytkownik kliknie przycisk i zapisać aktualną odpowiedź i tak dalej, ale to byłoby dużą liczbę trafień w bazie danych, która jest już w dużym stopniu wykorzystywane. Nie mam czasu, aby zdobyć nowy serwer itp., Więc muszę zrobić z tym, co mam. Czy istnieje sposób na buforowanie pytań na komputerze użytkownika i/lub odpowiedziach? Oczywiście potrzebuję danych z odpowiedzi, aby były bezpieczne i znane tylko użytkownikowi, więc czuję, że utknąłem w najmniej korzystny sposób. Jakieś wskazówki?

Jestem gotów zaoferować nagrodę w wysokości 100 punktów na ten temat, jeśli to oznacza, że ​​będę mieć dobrą dyskusję i opinie.

+1

Dlaczego należy minimalizować dostęp do bazy danych? wydajność ? To nie wygląda na to, że powinno być intensywne DB, jeśli jest odpowiednio zaprojektowane. –

+0

Czy chcesz rozszerzyć Romain? –

Odpowiedz

1

Masz trzy warunki, które muszą być zrównoważone:

  • użytkownicy muszą być w stanie powrócić do ich badania w dowolnym momencie
  • Odpowiedzi wpisane przez użytkowników muszą być zachowane przy najmniejszym możliwym przypadkiem utraty danych
  • trzeba zminimalizować bazie uderza

każde rozwiązanie, które wymaga odpowiedzi buforowania w lotnym miejscu (ciasteczka, sesji itp) zwiększa ryzyko utraty danych. Ostateczne rozwiązanie zależy od tego, jak rangujesz trzy ważne wymagania. Jeśli problem związany z db jest na górze, musisz albo zaryzykować utratę danych, albo poświęcić dużo czasu na kodowanie rozwiązania za pomocą jakiegoś schematu tymczasowego przechowywania (jak na przykład płaski pomysł Kevina).

Kilka osób zasugerowało, że możesz przedwcześnie zoptymalizować optymalizację. Proponuję, żebyś najpierw rozważył ten pomysł - może ta cała sprawa jest dyskusyjna.

Jednak zakładając, że twoja sytuacja db jest prawdziwym problemem, myślę, że twoja najlepsza równowaga wymagań będzie systemem, który natychmiast zapisuje odpowiedź na db (aby zapobiec utracie danych), ale ostrożnie zarządza, kiedy faktycznie musisz uderzyć db.

  1. Po uruchomieniu aplikacji (lub gdy pierwszy użytkownik poprosi o ankietę) załaduj ankietę i jej pytania do pamięci podręcznej aplikacji. Jeśli którekolwiek z pytań zawiera listę możliwych odpowiedzi, należy je również załadować. Będziesz musiał uderzyć w bazę danych raz podczas okresu życia aplikacji (lub czasu trwania pamięci podręcznej), aby załadować dane z ankiety.
  2. Gdy użytkownik rozpoczyna swoją ankietę, uruchom pojedyncze zapytanie, aby załadować wszystkie istniejące odpowiedzi (w przypadku, gdy są powracającym użytkownikiem) do obiektu w sesji - może być tak proste jak <List>string. (Jeśli możesz w jakiś sposób zidentyfikować nowego użytkownika bez konieczności uderzania w bazę danych, możesz pominąć ten krok dla nowych użytkowników.)
  3. Użyj obiektu odpowiedzi na sesję wraz z obiektem zapytania ankiety w pamięci podręcznej aplikacji, aby wypełnić każdą stronę bez uderzania db ponownie.
  4. Gdy użytkownik przesyła odpowiedź, porównaj ją z obiektem odpowiedzi na sesję, aby sprawdzić, czy się zmieniła (może to być po prostu kliknięcie "dalej" na stronie z wcześniej wprowadzoną odpowiedzią). Jeśli odpowiedź jest nowa lub uległa zmianie, zapisz ją w db i w obiekcie odpowiedzi na sesję.
  5. Po opuszczeniu ankiety użytkownik nie musi nic robić - wszystko jest już zapisane.

W tym schemacie trafiasz raz do bazy danych, aby załadować ankietę, raz dla każdego użytkownika, gdy rozpoczyna (lub ponownie uruchamia) ankietę, i raz dla każdej nowej lub zmodyfikowanej odpowiedzi. Prawdopodobnie nie taka redukcja, na jaką liczyłeś, ale zapewnia najlepszą ochronę danych.

1

Jeśli przyczyną problemów z bazą danych jest ich przenoszenie, można je buforować na serwerze internetowym (lub w dowolnym miejscu, w którym znajduje się aplikacja), ale wydaje się, że każda odpowiedź musi zostać zapisana, gdy użytkownik przejdzie do następnego pytania.

Jeśli pytania i możliwe odpowiedzi są identyczne dla wszystkich, zdecydowanie buforowałbym je w warstwie aplikacji - może to być przechowywane w obiekcie Application. W każdym przypadku z pewnością można zoptymalizować wywołania bazy danych, aby zwracać wyniki tak skutecznie, jak to możliwe - tj. Wiele zestawów wyników lub połączony zestaw wyników z pojedynczego zapisanego procesu. Jeśli nie masz nic przeciwko wielokrotnym kopiom dla każdej sesji (lub jeśli istnieje zmienność), możesz zapisać ją w obiekcie Session. Przechowywanie go na kliencie (to znaczy na cookie) nie jest tak naprawdę bezpieczne i bezsensowne z powodu oszczędzania przepustowości serwera serwer-klient.

Dla mnie jednak brzmi to jak przedwczesna optymalizacja.

+0

Nie sądziłem, że przepustowość jest problemem. obawy wydają się być mocno uderzoną bazą danych –

+0

@ David Nie jestem pewien, dlaczego buforowanie go na kliencie jest lepsze od serwera WWW/aplikacji w tym momencie. –

+0

Jestem otwarty na sugestie dotyczące buforowania na serwerach aplikacji, o ile ruch nie jest w bazie danych (SQL Server), to jest zwycięzca. –

0

czy masz na myśli ... ciasteczko?

+0

Bezpieczeństwo jest koniecznością - w jaki sposób mogę zapewnić bezpieczeństwo plików cookie? –

+1

szyfrowanie. szyfrować zawartość pliku cookie. – aepheus

+0

Mam złe doświadczenia z przeglądarką Safari i zmieniając wartości plików cookie. Nawet z aktualnym rev. Coś, o czym należy pamiętać, jeśli musisz obsługiwać tę przeglądarkę. – NotMe

1

Jest to klasyczny problem związany z utrzymaniem stanu między stronami w systemie opartym na przeglądarce. Zakładam również, że chcemy, aby te dane się utrzymywały, nawet jeśli użytkownik wyloguje się i wróci później. Oto opcje:

  • z wysokim serwerze dostępności możemy zachować jeden zbiór 15 odpowiedzi w pamięci (nie sesja) dla tego użytkownika (prawdopodobnie nie jest dobrym pomysłem i nie łatwo załadować zrównoważony)
  • Mamy zdenormalizuj 15 odpowiedzi w 1 wierszu tabeli sql
  • Utrzymujemy dane na kliencie za pomocą pliku cookie lub localStorage (IE8).

Mam wrażenie, że pierwsze dwie opcje prawdopodobnie nie są tym, czego szukasz, więc poznaj ostatnią opcję.

Można po prostu zapisać odpowiedzi w pliku cookie. Istnieje niewielka szansa, że ​​może się to zagubić, a użytkownik może zalogować się z innej maszyny, ale może to być dopuszczalne ryzyko. Wraz z najnowszymi przeglądarkami obsługującymi HTML5 (inc IE8 afaik) otrzymujesz korzyść localStorage, która nie jest tak łatwo usuwana jak cookie. Moglibyście wrócić do ciasteczek, gdyby to nie było dostępne.

Pliki cookie mogą być zaszyfrowane, jeśli jest to wymagane.

1

Nie jestem pewien języków, których używasz, ale większość ma pamięć podręczną aplikacji. Chciałbym zapisać tam te pytania i pobrać je z bazy danych i przechowywać je, gdy nie są w pamięci podręcznej (gdy aplikacja przetwarza).

Co do odpowiedzi, czy użytkownicy logują się w jakiś sposób? Czy możliwe jest zapisywanie odpowiedzi w pliku cookie do momentu odpowiedzi na wszystkie pytania?

Edycja: Jeśli pliki cookie nie są wystarczająco wiarygodne, można zapisać (w pamięci podręcznej aplikacji) listę zapytań (wstawień/aktualizacji) do wykonania, które nie zostaną wykonane, dopóki nie zostanie osiągnięty limit zapytań lub pod pewnymi warunkami (tj. wykonać listę zapytań, gdy użytkownik żąda odpowiedzi, które znajdują się na liście, wykonać listę, gdy aplikacja przetwarza, itd.).

Dość surowe, ale masz pomysł:

if (function == "get question" && userQuestionIsInQueue) || function == "finish survey" 
execute(Application["querylist"]); 
continue as normal... 

if function == "submit answer" 
if Application["querylist"] == null 
Application["querylist"] = newAnswerQuery; 
else 
Application["querylist"] += newAnswerQuery; 

że trzeba także dodać execute (Application [ „querylist”]) do zdarzenia obiegowego, wierzę, można go podłączyć w światowym .asax

Edycja 2: Chciałbym również gromadzić wszystkie transakcje bazy danych dla żądania na 1, jeśli musiałeś wykonać listę, a następnie uzyskać odpowiedź dla użytkownika, zrób to w tej samej transakcji i zapisz podróż. Typowa praktyka podczas optymalizacji.

+0

Używam ASP.NET, dlatego go oznaczyłem . Oznakowałem także VB.Net i C#, ale Adam je usunął. Czuję się komfortowo z kodowaniem, ponieważ zasady są takie same. –

+0

Dzięki za edycję - brzmi interesująco czy masz przykład takiej techniki? –

+0

Aplikacja ["moje_pytania"] = Pytania; – aepheus

2

O ile nie ma powodu do korzystania z bazy danych, zawsze można zapisać wyniki w plikach płaskich na samym serwerze. Nie wygląda na to, że dane, które przechowujesz, są w jakikolwiek sposób relacyjne. Najgorsze staje się najgorsze, zawsze można je włożyć do relacyjnej bazy danych jako zadanie wsadowe każdej nocy.

Inną opcją jest pamięć podręczna aplikacji. Jeśli jednak serwer internetowy nagle ulegnie awarii, ryzykujesz utratę informacji z tego miejsca.

Można również zapisać wartości w ciasteczkach użytkownika.

1

Twój scenariusz jest doskonałym kandydatem na Predictive Fetch Pattern. Sugerowałbym, abyś przechowywał wszystkie swoje pytania w pamięci podręcznej. Kiedy użytkownik zaloguje się, użyje wzorca, aby pobrać pierwsze 5 odpowiedzi (jeśli udzielił odpowiedzi) i na podstawie ich nawigacji (tam, gdzie jest to aktualne pytanie), uzyskać informacje z obiektu odpowiedzi lub z bazy danych.

HTH

1

Chciałbym zaoferować Państwu nową funkcję HTML5, które nazywa Magazyn DOM ale skoro tylko nowe przeglądarki wspierają go, to może być problem, używając go w tym momencie.

Za pomocą DOM Storage można przechowywać dane w przeglądarce użytkownika.Ponieważ może przechowywać do 5 MB na domenę w Mozilla Firefox [3], Google Chrome i Opera, 10 MB na obszar pamięci w Internet Explorerze, możesz przechowywać odpowiedzi i identyfikatory pytań w pamięci DOM.

Nawet przy korzystaniu z DOM Storage, nie mówiąc już o Database, możesz także zmniejszyć liczbę trafień serwera.

Ponieważ wszyscy wiemy, że praca z ciasteczkami jest czasami kłopotliwa i może przechowywać 4kb, najprostszym sposobem jest teraz przechowywanie informacji o wartościach klucz-wartość w DOM Storage.

Możesz przechowywać informacje o parach klucz-wartość specjalnie dla sesji, jak również lokalnie. Po zakończeniu sesji informacje dotyczące sesji zostaną usunięte z przeglądarki, ale jeśli przechowujesz wartości lokalne, nawet użytkownik zamknie kartę, a wartość klucza pozostanie na jakiś czas.

Przykład Kod:

<p> 
    You have viewed this page 
    <span id="count">an untold number of</span> 
    time(s). 
</p> 
<script> 
    var storage = window.localStorage; 
    if (!storage.pageLoadCount) storage.pageLoadCount = 0; 
    storage.pageLoadCount = parseInt(storage.pageLoadCount, 10) + 1; 
    document.getElementById('count').innerHTML = storage.pageLoadCount; 
</script> 

Możesz dowiedzieć się więcej na temat DOM Storage z poniższych linków:

2

Na podstawie mojego osobistego doświadczenia (serwowania tysięcy krótkich stron ankiet na sekundę) podejrzewam, że twoje obawy są bezpodstawne. Między innymi, DBMS będzie buforował tak małe ilości danych znacznie efektywniej, jak tylko możesz.

Przetestowałem to, ładując pytania i odpowiedzi do kolekcji Zakresu Aplikacji podczas uruchamiania, a następnie serwując je z pamięci - często nie miało to żadnej różnicy.

Alternatywą jest wysłanie wszystkiego do przeglądarki i zapisanie go jako aplikacji javascript, przechowywanie danych w (zaszyfrowanych) ciasteczkach i trafianie do bazy danych dopiero po wykonaniu całej czynności. Jest to żmudne, ale nie trudne.

Powiązane problemy