In un questionario online, qual è il modo migliore di progettare un database per tenere traccia degli utenti tutti i tentativi?

4

Abbiamo un'app Web in cui gli utenti possono sostenere esami online.

L'amministratore dell'esame creerà un questionario. Un questionario può avere molte domande. Ogni domanda è una domanda a scelta multipla (MCQ).

Diciamo che un amministratore crea un questionario con 10 domande. Gli utenti tentano queste domande. Ora, a differenza degli esami reali, gli utenti possono tentare un singolo questionario più volte. E dobbiamo tenere traccia dei suoi tutti i tentativi.

es.

 +-------+-----------------+------------+-------+------------+----------+
 |User_id|Questionnaire_id |question_id |answer |attempt_date|attempt_no|
 +-------+-----------------+------------+-------+------------+----------+
 |1      |1                |1           |a      |1 June 2013 |1         |
 |1      |1                |2           |b      |1 June 2013 |1         |
 |1      |1                |1           |c      |2 June 2013 |2         |
 |1      |1                |2           |d      |2 June 2013 |2         |
 +-------+-----------------+------------+-------+------------+----------+

Ora può succedere anche che dopo che l'utente abbia tentato due volte lo stesso questionario, admin può cancellare una domanda dallo stesso questionario, ma la cronologia dei tentativi degli utenti dovrebbe comunque fare riferimento a quella in modo che l'utente possa vedere la sua domanda nella sua cronologia dei tentativi in Nonostante l'amministratore, l'eliminazione di quella domanda.

Se l'utente tenta ora questo questionario modificato, dovrebbe vedere solo 1 domanda.

 +-------+-----------------+------------+-------+------------+----------+
 |User_id|Questionnaire_id |question_id |answer |attempt_date|attempt_no|
 +-------+-----------------+------------+-------+------------+----------+
 |1      |1                |1           |a      |3 June 2013 |3         |
 +-------+-----------------+------------+-------+------------+----------+

Inoltre, dopo che questo utente ha modificato una parte della domanda, gli utenti tentano la cronologia dovrebbero mostrare la domanda prima della modifica, mentre ogni nuovo tentativo dovrebbe mostrare la domanda modificata.

Come gestirlo a livello di database?

Il mio primo istinto era quello,

Per le eliminazioni, non eseguire l'eliminazione fisica, basta rendere una domanda inattiva in modo che la cronologia possa ancora tenere traccia degli tentativi degli utenti.

Per le modifiche, crea versioni per domande e ogni nuovo tentativo aggiorna all'ultima versione di ogni domanda e cronologia, facendo riferimento alla versione della domanda al momento del tentativo.

    
posta user1990525 24.05.2013 - 05:08
fonte

4 risposte

2

Se si aggiunge solo il timestamp alla tabella answer , allora ci si sta impegnando su più query o si stanno ripristinando dati aggiuntivi quando è necessario solo l'ultimo. Ecco una query di esempio con una sottoquery (che è lenta):

select * from answer
    where question_id = ? and user_id = ?
        and update_time =  (select max(update_time) from answer
                                where question_id = ? and user_id = ?)

Per evitare ciò, puoi dichiarare una tabella separata per la cronologia. Ad esempio, se le tue ultime risposte sono nella tabella answer , potresti avere una tabella answer_history che è esattamente la stessa (entrambe le tabelle dovrebbero avere una colonna% tim_amp% timestamp). In questo modo puoi memorizzare tentativi di risposta illimitati e le tue domande rispetto alle ultime risposte non rallenteranno mai dalla cronologia della cronologia e non restituiranno mai record extra.

Non sei sicuro di quanto sei distante dal tuo progetto, ma hai pensato di utilizzare Datomic ? Memorizza tutta la cronologia per impostazione predefinita e ha la capacità di interrogare la cronologia in modi diversi. Non penso che tu debba dichiarare alcuno schema. Rompe le strutture dati nelle loro parti componenti al momento del salvataggio e riassembla quelle che hai bisogno di leggere. È compatibile con la maggior parte delle lingue JVM, sebbene sia stato sviluppato dalla comunità Clojure. Non è SQL, e non è il No-SQL basato su record che è attualmente popolare. Il suo design dovrebbe essere in grado di gestire carichi elevati confrontabili con i database SQL. Estraendo il "transactor" dal resto del database, consente di ridimensionare il tuo motore di archiviazione su istanze cloud che vengono attivate in base alle esigenze per gestire il carico.

    
risposta data 21.10.2013 - 14:43
fonte
1

Alcune cose:

  • Ogni risposta riceve un timbro di data. Il tipico timbro di tipo DD / MM / YY HH: MM: SS andrà bene. Assicurati di indicizzare questo campo.
  • Nel determinare quale risposta ha dato un utente, si cerca l'ultima.
  • Ogni domanda riceve una data di inizio e un timbro della data di fine.
  • Ora puoi modificare le domande e avere le risposte ancora significative, dato che puoi recuperare le risposte entro l'intervallo di date valido per quella domanda.

Per la cancellazione, basterà semplicemente contrassegnare quella domanda come "Eliminata". E manterrà la cronologia di quella domanda in giro a scopo di segnalazione.

    
risposta data 23.06.2013 - 10:46
fonte
0

Per quanto riguarda le eliminazioni, il tuo suggerimento è giusto. Una best practice comune è usare i flag per dichiarare una proprietà. In questo esempio nella tabella delle domande (ovunque memorizzi le domande) aggiungi un nuovo campo chiamato isDeleted . Imposta su 0 per impostazione predefinita quando inserisci una nuova voce e aggiorni a 1 quando elimini una domanda.

Ora alle modifiche. Il tuo suggerimento mi sembra giusto (per quanto ho capito correttamente la tua spiegazione). Puoi farlo aggiungendo un nuovo campo alla tua tabella di domande chiamato qualcosa come parent , che dovrebbe fare riferimento all'id della domanda aggiornata. Consiglio vivamente di utilizzare chiavi esterne a questo punto, poiché è essenziale per mantenere l'integrità dei dati.

    
risposta data 24.05.2013 - 10:00
fonte
0

Contrassegna i record come inattivi usando un flag "attivo" (impostato su falso) e ...

crea viste del database che mostrano tutti i record, i record attivi e i record inattivi (usando quel contrassegno "attivo") e poi li usi nella tua applicazione come desiderato.

    
risposta data 21.10.2013 - 14:14
fonte

Leggi altre domande sui tag