[PHP-MySQL]Enquête Project - tabelstructuur v/d antwoorden

Pagina: 1
Acties:

  • Elvis
  • Registratie: Juli 2002
  • Laatst online: 18-11-2017

Elvis

Echo Lima Victor India Sierra

Topicstarter
Hallo Tweakers, :w

Ik ben momenteel aan het werken aan een enquête-systeem. De programmatie in PHP is helemaal Objectgeoriënteerd en werkt (tot nu toe iig) zoals ik het wil.
Waar nou een beetje mee zit, is hoe ik alles moet bijhouden in de database...
Ik heb nu de volgende tabellen (telkens met een voorbeeld, de primary key van elke tabel staat in rood)

Enquetes: hier worden de verschillende enquêtes in opgeslagen.
idnaamaangemaaktDoortimeStamp
enq01Mijn Enquete 1Elvis*timestamp*

Vragen: Hier worden de verschillende vragen uit opgehaald
idenqidvraagTextmogelijkeAntwoorden
vraag01enq01Is dit een vraag?Ja,Nee,Misschien,Weet Niet
Nota: De string in mogelijkeAntwoorden dient om meerdere antwoorden te definieren bij een meerkeuzevraag.

Users: Alle users die de enquêtes kunnen bekijken en invullen.
idnaampass
user01Proleet*encrypted pass*

Tot hier toe werkt alles nogal naar behoren. Ik kan met PHP de enquête-objecten (en hun bijhorende vraag-objecten) uit de database halen.
Het probleem stelt zich voor als een user een enquête ingevuld heeft.
Waar of hoe slaag ik zijn antwoorden op? Ik zelf dacht aan het volgende:

Antwoorden: Alle antwoorden van alle users
enqidvraagiduseridantwoord
enq01vraag01user01Ja
Nota: Hier dienen de kolommen enqid, vraagid & userid tesamen als primary key.

Als we er vanuitgaan dat elke user maar 1 keer op elke vraag mag antwoorden, dan zou in principe zou de tabel voor de antwoorden zoals hierboven beschreven werken, toch?

Maar als er nu, na een tijdje, 30 users en 5 enquêtes met elk 20 vragen zijn.
Dan wordt de antwoordentabel wel ongelooflijk groot, wat het doorzoeken hiervan niet vergemakelijkt wss. (3000 entries, 1 tabel) :)

Is er misschien een betere manier om alle antwoorden op te slaan? Misschien een aparte antwoordentabel per enquête(600 entries, 5 tabellen) of per user(100 entries, 30 tabellen)? Of heeft iemand nog een ander (misschien beter) idee?

[GoT] TF2 Clan


  • daniëlpunt
  • Registratie: Maart 2004
  • Niet online

daniëlpunt

monkey's gone to heaven

3000 entries (rows) valt best wel mee hoor. :) MySQL kan best wel wat hebben.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Elvis schreef op donderdag 12 juni 2008 @ 14:53:
Dan wordt de antwoordentabel wel ongelooflijk groot, wat het doorzoeken hiervan niet vergemakelijkt wss. (3000 entries, 1 tabel) :)
Da's voor jouw (menselijke) begrippen misschien wel groot, maar voor een beetje RDBMS peanuts. Bij 3 miljard rijen begint er misschien wat meer mee te spelen (en dan nog niet écht), maar 3000 ...pff :P
Elvis schreef op donderdag 12 juni 2008 @ 14:53:
Is er misschien een betere manier om alle antwoorden op te slaan? Misschien een aparte antwoordentabel per enquête(600 entries, 5 tabellen) of per user(100 entries, 30 tabellen)?
Juist niet, je opzet zoals 'ie nu is is goed. Je moet ver, vér van dit soort ideeën vandaan blijven (aparte tabellen voor iedere scheet).

Het enige wat je moet doen is zorgen dat je indexes goed staan (en dat zijn ze sowieso al als je de rode velden (combined) keys maakt. Dus je bent klaar.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Elvis
  • Registratie: Juli 2002
  • Laatst online: 18-11-2017

Elvis

Echo Lima Victor India Sierra

Topicstarter
Woot! *O*
Thanks for the quick replies!
De lessen Datamodeleren en SQL zijn toch niet nutteloos geweest (in tegenstelling tot wat ik een heel schooljaar gedacht heb :))

[GoT] TF2 Clan


  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ik zou het totaal anders doen. Je krijgt dan een quiztabel, een vragentabel, een antwoordentabel en een gebruikers-antwoordentabel.

Dus:
Quiz
QuizID, Titel, AanmakerID, AanmaakTijd
AanmakerID linkt naar gebruikerstabel op UserID

Vraag
VraagID, QuizID, VraagNr, Tekst
VraagID is unique, QuizID linkt vraag aan quiz, VraagNr gaat per quiz, bijvoorbeeld vraag 1-10 van quiz 2

Antwoord
AntwoordID, VraagID, Tekst
AntwoordID is uniek, VraagID linkt antwoord aan vraag

GebruikersAntwoord
GebruikersID, AntwoordID

Simpel, en met de juiste indexen razendsnel tot miljoenen antwoorden. Iemand commentaar? ;)

:w Cheatah, kuddos voor de duidelijkere notatie :P

[ Voor 4% gewijzigd door CodeCaster op 12-06-2008 15:21 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Verwijderd

Nota: De string in mogelijkeAntwoorden dient om meerdere antwoorden te definieren bij een meerkeuzevraag.
Slechte oplossing. Maak een tabel aan voor de antwoorden, dan wordt de tabel GebruikersAntwoorden een koppeltabel tussen gebruikers en vragen.

survey (survey_id, name, user_id, timestamp)
question (question_id, survey_id, question)
answer (answer_id, question_id, answer)
user (user_id, username, password)
user_answer (user_id, question_id, answer_id, timestamp)

Gebruik als keys gewoon integers, dus geen string als "enq01". Onderstreepte velden zijn primary key. Schuingedrukte velden zijn een foreign key, en daar zou ik ook een index op zetten.

[edit]
De suggestie van CodeCaster is ook goed, maar ik zou ervoor zorgen dat het technisch onmogelijk is om meerdere antwoorden op een vraag te hebben van dezelfde gebruiker. Anders moet je dat op applicatie-niveau gaan doen. Dat is wel een mogelijkheid, maar ik zou daar niet voor kiezen.

@CodeCaster: Enigszins, Professioneel, Sindsdien, Desalniettemin, Verrassend ;)

[ Voor 20% gewijzigd door Verwijderd op 12-06-2008 15:31 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:13

Creepy

Tactical Espionage Splatterer

* Creepy mept Rob|||. Kijk nog eens goed naar de kolom "mogelijke antwoorden", daar staan komma gescheiden waardes in ;)

edit: spuit 12......

[ Voor 52% gewijzigd door Creepy op 12-06-2008 15:30 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Elvis
  • Registratie: Juli 2002
  • Laatst online: 18-11-2017

Elvis

Echo Lima Victor India Sierra

Topicstarter
Verwijderd schreef op donderdag 12 juni 2008 @ 15:18:
[...]

Slechte oplossing. Maak een tabel aan voor de antwoorden, dan wordt de tabel GebruikersAntwoorden een koppeltabel tussen gebruikers en vragen.

survey (survey_id, name, user_id, timestamp)
question (question_id, survey_id, question)
answer (answer_id, question_id, answer)
user (user_id, username, password)
user_answer (user_id, question_id, answer_id, timestamp)

Gebruik als keys gewoon integers, dus geen string als "enq01". Onderstreepte velden zijn primary key. Schuingedrukte velden zijn een foreign key, en daar zou ik ook een index op zetten.
*knip*
Ik begrijp wat je bedoelt, maar ik ga me toch houden aan de structuur die ik nu heb.
Het veld "mogelijkeAntwoorden" gaat wss toch vooral leeg zijn omdat de meeste vragen op de enquête(s) geen meerkeuzevragen gaan zijn. En als het veld word leeggelaten, maakt de constructor van de Klasse MeerkeuzeVraag de mogelijke antwoorden automatisch van 1 tot 10.

Ik denk dat ik het onbedoeld moeilijker ga maken om een extra tabel te maken die weinig gebruikt gaat worden.
(damn, bedenk net dat ik nog geen code heb die van een opgehaald Vraag-object bekijkt of het nou een meerkeuzevraag is of niet 8)7 :P)

@Codecaster:
Jou systeem werkt ook, maar het is (zoals cheatah zegt) idd de bedoeling dat elke user elke vraag maar 1 keer beantwoordt (of zijn antwoord aanpast).
Creepy schreef op donderdag 12 juni 2008 @ 15:29:
[...]

* Creepy mept Rob|||. Kijk nog eens goed naar de kolom "mogelijke antwoorden", daar staan komma gescheiden waardes in ;)
Is dat dan zo'n heidense praktijk (ook als je de uitleg hierboven leest)? :$

[ Voor 9% gewijzigd door Elvis op 12-06-2008 15:45 ]

[GoT] TF2 Clan


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:13

Creepy

Tactical Espionage Splatterer

Jup, het gaat tegen de normalisatie regels in :) Zaken die herhaardelijk voorkomen in je structuur (dus meerdere zaken in 1 veld of kolommen met de naam veld1, veld2, veld3 etc) is over het algemeen not done.
Een extra optie erbij betekent dan vaak je tabel structuur aanpassen terwijl dit met een extra tabel helemaal niet hoeft en je oneindig kan uitbreiden. Probeer voor de gein ook eens een query te schrijven die uit je komma gescheiden waarde altijd 1 specifieke waarde pakt. Je gaat dan al snel rommelen met zaken als 'where iets LIKE "%,waarde,% OR iets LIKE "waarde,%"' wat erg rommelig is en ook nog eens langzaam.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Elvis
  • Registratie: Juli 2002
  • Laatst online: 18-11-2017

Elvis

Echo Lima Victor India Sierra

Topicstarter
Creepy schreef op donderdag 12 juni 2008 @ 15:48:
Jup, het gaat tegen de normalisatie regels in :) Zaken die herhaardelijk voorkomen in je structuur (dus meerdere zaken in 1 veld of kolommen met de naam veld1, veld2, veld3 etc) is over het algemeen not done.
Een extra optie erbij betekent dan vaak je tabel structuur aanpassen terwijl dit met een extra tabel helemaal niet hoeft en je oneindig kan uitbreiden. Probeer voor de gein ook eens een query te schrijven die uit je komma gescheiden waarde altijd 1 specifieke waarde pakt. Je gaat dan al snel rommelen met zaken als 'where iets LIKE "%,waarde,% OR iets LIKE "waarde,%"' wat erg rommelig is en ook nog eens langzaam.
Ahja, nu snap ik waar je vandaan komt. :)
Die kolom mogelijkeAntwoorden word echter altijd helemaal als String uitgelezen.
De constructor van de Klasse MeerkeuzeVraag maakt dan van die string via een tokenize-functie een array van Strings die de verschillende antwoorden bevatten.
Er moet dus nooit een query gemaakt worden om een vraag te selecteren op basis van de mogelijke antwoorden.

[GoT] TF2 Clan


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
:'( * RobIII moet met de billen bloot :P
Creepy schreef op donderdag 12 juni 2008 @ 15:29:
Kijk nog eens goed naar de kolom "mogelijke antwoorden", daar staan komma gescheiden waardes in ;)
:X Daar had ik inderdaad overheen gekeken :X 8)7 :P
Hebben ze eindelijk eens een mooie "user-antwoorden tabel", verknoeien ze de voorzet :P
Wat Cheatah dus zegt :P

* RobIII nog even een middagdutje doen gaat :+

[ Voor 5% gewijzigd door RobIII op 12-06-2008 16:10 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:13

Creepy

Tactical Espionage Splatterer

Elvis schreef op donderdag 12 juni 2008 @ 15:55:
[...]

Ahja, nu snap ik waar je vandaan komt. :)
Die kolom mogelijkeAntwoorden word echter altijd helemaal als String uitgelezen.
De constructor van de Klasse MeerkeuzeVraag maakt dan van die string via een tokenize-functie een array van Strings die de verschillende antwoorden bevatten.
Er moet dus nooit een query gemaakt worden om een vraag te selecteren op basis van de mogelijke antwoorden.
Dan nog is een varchar kolom vaak maar max 255 tekens waarbij je met veel en lange antwoorden al vrij snel tegen een limiet aan zit ;)
En als er ineens een tijd komt dat je toch iets wilt selecteren hieruit zit je alsnog met een probleem. Veranderingen gebeuren nu eenmaal dus kan je beter je datamodel direct goed opzetten i.p.v. achteraf rechttrekken indien nodig.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Johnny
  • Registratie: December 2001
  • Laatst online: 18-11 09:51

Johnny

ondergewaardeerde internetguru

Als het aantal queries en de snelheid daarvan een probleem is kan je ook beter je datamodel cachen in het filesystem. Je zei dat het op dit moment al helemaal object georienteerd was, dan kan je vrij makkelijk de klasse die dedata uit de database haalt uitbreiden zodat hij eerst checkt of er een cache-bestand is en deze dan opent in plaats van de database aan te spreken. Als er geen cache-bestand is kan je alsnog de data uit de database halen en verolgens opslaan in het cache voordat je de data teruggeeft. Op het moment dat je een wijziging maakt aan de enquete gooi je gewoon het cache-bestand weg en zal het vanzelf opnieuw worden aangemaakt wanneer dat nodig is.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


  • Elvis
  • Registratie: Juli 2002
  • Laatst online: 18-11-2017

Elvis

Echo Lima Victor India Sierra

Topicstarter
Creepy schreef op donderdag 12 juni 2008 @ 16:14:
[...]

Dan nog is een varchar kolom vaak maar max 255 tekens waarbij je met veel en lange antwoorden al vrij snel tegen een limiet aan zit ;)
En als er ineens een tijd komt dat je toch iets wilt selecteren hieruit zit je alsnog met een probleem. Veranderingen gebeuren nu eenmaal dus kan je beter je datamodel direct goed opzetten i.p.v. achteraf rechttrekken indien nodig.
Momenteel is mogelijkeAntwoorden een TEXT-kolom :Y)
Maar ik begrijp en erken jullie argumenten en zal dan ook mn structuur aanpassen.
Dan word het iig gemakkelijker om later een mogelijk antwoord voor een meerkeuzevraag toe te voegen, aan te passen of te verwijderen...
Johnny schreef op donderdag 12 juni 2008 @ 16:28:
Als het aantal queries en de snelheid daarvan een probleem is kan je ook beter je datamodel cachen in het filesystem. Je zei dat het op dit moment al helemaal object georienteerd was, dan kan je vrij makkelijk de klasse die dedata uit de database haalt uitbreiden zodat hij eerst checkt of er een cache-bestand is en deze dan opent in plaats van de database aan te spreken. Als er geen cache-bestand is kan je alsnog de data uit de database halen en verolgens opslaan in het cache voordat je de data teruggeeft. Op het moment dat je een wijziging maakt aan de enquete gooi je gewoon het cache-bestand weg en zal het vanzelf opnieuw worden aangemaakt wanneer dat nodig is.
Euh... Wat? :? :D

[GoT] TF2 Clan


  • remco_k
  • Registratie: April 2002
  • Laatst online: 23:10

remco_k

een cassettebandje was genoeg

Elvis schreef op donderdag 12 juni 2008 @ 16:52:
[...]

Momenteel is mogelijkeAntwoorden een TEXT-kolom :Y)
Maar ik begrijp en erken jullie argumenten en zal dan ook mn structuur aanpassen.
Dan word het iig gemakkelijker om later een mogelijk antwoord voor een meerkeuzevraag toe te voegen, aan te passen of te verwijderen...
... En nog ingewikkelder: tussenvoegen.
Dat los je met dit voorstel dan heel mooi op en is het tussenvoegen van een antwoord niet meer moeilijk.

Alles kan stuk.

Pagina: 1