2013-02-06 14 views
6

Aktualnie pracuję nad aplikacją do tworzenia/administrowania ankietami z PHP/MySQL. Przeszedłem kilka poprawek tabel bazy danych i ponownie stwierdziłem, że potrzebuję ponownie przemyśleć przechowywanie pewnego rodzaju odpowiedzi.Optymalny sposób przechowywania odpowiedzi ankiety wielokrotnego wyboru w bazie danych

Teraz mam tabeli, który wygląda tak:

survey_answers

id   PK 
eid 
sesid 
intvalue Nullable 
charvalue Nullable 

id = unikalną wartość przypisaną do każdego wiersza

eid = Survey wątpliwości, że ten odpowiedź jest odpowiedzią na

sesid = Badanie "sessio" n”(informacja o czasie i dacie odbierającym ankietowych) id

intValue = Wartość odpowiedź czy jest to wartość liczbowa

charvalue = wartość odpowiedź czy jest to reprezentacja tekstowa

Pozwoliło mi to na dalsze korzystanie z funkcji matematycznych MySQL w celu przyspieszenia przetwarzania.

Jednak znalazłem nowe wyzwanie: przechowywanie pytań z wieloma odpowiedziami. Przykład może wyglądać następująco:

Który z poniższych produktów sprawia przyjemność? (Wybierz wszystkie zastosowania)

  • Girl Scout Cookies
  • boczek
  • Corn
  • tłuszczu wieloryba

Teraz, gdy chcę zapisać wynik, nie jestem pewny najlepszego sposobu, by sobie z tym poradzić. Obecnie mam tabeli tylko dla wielu opcji wyboru, który wygląda tak:

survey_element_options

id  PK 
eid 
value 

id = wyjątkowa wartość związana z każdym rzędzie

eid = pytanie/elementu ta opcja jest powiązana z wartością

wartość = wartość tekstowa tej opcji

Za pomocą tej konfiguracji przechowuję zwrócone odpowiedzi wielokrotnego wyboru w "survey_answers" jako ciągi oddzielonych przecinkami identyfikatorów wierszy element_options wybranych w ankiecie.(np. "4,6,7,9") Zastanawiam się, czy to rzeczywiście najlepsze rozwiązanie, czy też byłoby bardziej praktyczne stworzenie nowej tabeli, która zawierałaby każdą wybraną odpowiedź, a następnie odniesienie do dany wiersz odpowiedzi, który z kolei odwołuje się do elementu i ostatecznie do ankiety.


EDIT

dla wszystkich zainteresowanych, tutaj jest podejście skończyło się na wyciągnięciu (w phpMyAdmin Relations View):

Database Relationships and Table Structure

I prymitywny zapytania zebrać liczniki dla pytania wielokrotnego wyboru wyglądałoby następująco:

SELECT e.question AS question, eo.value AS value, COUNT(eo.value) AS count 
FROM survey_elements e, survey_element_options eo, survey_answer_options ao 
WHERE e.id = 19 
AND eo.eid = e.id 
AND ao.oid = eo.id 
GROUP BY eo.value 

Odpowiedz

4

To naprawdę zależy od wielu rzeczy.

  1. Generalnie przechowywania listy oddzielonych przecinkami wartości w bazie danych jest złe, zwłaszcza jeśli planujesz robić nic zdalnie inteligentną z tymi danymi. Szczególnie jeśli chcesz robić zaawansowane raporty na temat odpowiedzi.
  2. najlepszym sposobem przechowywania tego jest zdefiniowanie odpowiedzi w drugiej tabeli, a następnie połączenie ich z odpowiedzią użytkowników na pytanie w trzeciej tabeli (z wieloma wpisami na pytanie użytkownika lub ewentualnie z użytkownikiem). ankieta - pytanie, czy użytkownik może wykonać wiele ankiet z tym samym pytaniem.

ten może się nieco skomplikowana, ponieważ aa scenariuszy jako prosty przykład

Przykład tabelach:

  • Users (Username, UserID)
  • Questions (qID, QuestionsText)
  • Answers (AnswerText [w ti Przykładem s sprawa może być wielokrotnego użytku, ale to powoduje dodatkową warstwę złożoności, jak również] aID)
  • Question_Answers ([Dostępne odpowiedzi na to pytanie, wiele wpisów na pytanie] qaID, qID, aID),
  • UserQuestionAnswers (qaID, uID)

Uwaga: pomyślany jako przykład, a nie zalecenie

+0

Twoje # 2 jest naprawdę tym, co starałem się uzyskać z moim pytaniem, myślałem, że to może być najlepszy sposób przechowywania danych, ponieważ znacznie ułatwiłoby to analizę w celach analitycznych. Sądzę, że prawdopodobnie tak będzie w moim przypadku, ponieważ uważacie, że to dobre rozwiązanie. – SamHuckaby

+0

@SamHuckaby zaktualizowano za pomocą przykładu (uwaga, nie rozwiązanie) – Matthew

-1

Jeśli nie używasz identyfikatora jako klucza obcego w innym zapytaniu lub jeśli możesz przesyłać wyniki za pomocą sesji, spróbuj relacji wiele do jednego. W przeciwnym razie zapisałbym odpowiedzi wielokrotnego wyboru w postaci szeregowej tablicy, takiej jak JSON lub funkcja serialize() php.

0

Konwertuj klucz podstawowy na unikatowy indeks i dodaj odpowiedzi dla tego samego pytania pod tym samym identyfikatorem.

Na przykład.

id | eid | sesid | intval | charval 
3  45  30  2 
3  45  30  4 

Nadal można dodać kolejną kolumnę dla regularnego unikalnego PK, jeśli jest to konieczne.

Utrzymuj rzeczy proste. Nie ma potrzeby relacji tutaj.

0

To konie na kursy cienkich g naprawdę.

Możesz przechowywać jako ciąg znaków oddzielonych przecinkami (ale co się stanie, gdy w jednej z twoich odpowiedzi znajdziesz literał przecinek).

można zapisać w postaci tabeli jeden-do-wielu, takich jak:

survey_element_answers

id    PK 
survey_answers_id FK 
intvalue   Nullable 
charvalue   Nullable 

a następnie w pętli nad tym stole. Jeśli wybierzesz jedną odpowiedź, utworzy on jeden wiersz w tej tabeli. Jeśli wybierzesz dwie odpowiedzi, utworzy on dwa wiersze w tej tabeli itp. Następnie usuniesz wartość intvalue i charvalue z tabeli survey_answers.

Kolejny wybór, ponieważ jesteś już przechowywania opcje element własnej tabeli, jest stworzenie wielu-do-wielu tabeli, takich jak:

survey_element_answers

id       PK 
survey_answers_id   FK 
survey_element_options_id FK 

Ponownie , jeden wiersz na wybraną opcję.

Kolejną opcją jest ponowne zapisanie wartości maski bitowej. Spowoduje to usunięcie potrzeby tabeli "wiele do wielu".

survey_element_options

id    PK 
eid    FK 
value   Text 
optionnumber unique for each eid 
optionbitmask 2^optionnumber 

optionnumber powinna być unikalna dla każdego identyfikacji elektronicznej i przyrost wychodząc z jednym. Jeśli użyjesz biginta, lub jeśli użyjesz int, nałożysz limit 63 opcji.

A potem w swoim survey_answers

id   PK 
eid 
sesid 
answerbitmask bigint 

Answerbitmask oblicza się dodając wszystkie z optionbitmask wraz dla każdej opcji wybranej przez użytkownika. Na przykład, jeśli 7 było przechowywanych w Maska odpowiedzi, oznacza to, że użytkownik wybrał pierwsze trzy opcje.

przyłącza może być wykonana przez:

GDZIE survey_answers.answerbitmask & survey_element_options.optionbitmask> 0

Więc tak, istnieje kilka opcji do rozważenia.

Powiązane problemy