Riprogettazione tabella utenti

di il
10 risposte

Riprogettazione tabella utenti

Buongiorno a tutti,

ammetto di aver commesso una grossa leggerezza nella fase iniziale di definizione della tabella utenti della mia applicazione web.
Ora che il servizio sta riscontrando un bel successo ed aumentano le installazioni, emerge sempre più chiaramente la necessità di una rivisitazione, prima che sia troppo tardi.
Nella sostanza, l'applicazione gestisce delle persone che poossono essere studenti, insegnanti, oppure genitori.
Questa informazione, in una visione statica del mondo è stata inserita come ruolo direttamente nella tabella utenti.
Quindi un utente ha ruolo teacher, un altro student ed un altro parent.

Ovviamente questo è quanto di più distante dalla realtà. Potrei essere uno studente ma anche un docente, o diventarlo nel tempo.
Potrei essere un genitore ma voler frequentare come studente.

Vorrei quindi fare un refactoring, considerando però che ovviamente c'è tanto codice che usa la struttura attuale, filtra gli studenti in base al ruolo 'student', o i docenti per ruolo 'teacher'. La situazione è complessa fare delle modifiche che portino al risultato ottenuto, senza incidere peantemente nel codice esistente mi pare una sfida.

Qualche idea? Come potrebbe essere rivista la struttura del database?

Grazie,
Michele

10 Risposte

  • Re: Riprogettazione tabella utenti

    La domanda è banale: quanto è grande la tabella utenti, e quanto ragionevolmente potrà esserlo?
    perchè una modifica di impatto minimo richiede l'uso di un classico antipattern (se non disponi di indici fulltext efficienti).
    ovviamente l'antipattern va evitato sempre e comunque se ha un impatto rilevante, se invece è modesto ha un suo utilizzo.
  • Re: Riprogettazione tabella utenti

    Beh si potrei dirti che dipende.

    In genere si tratta di qualche centinaio di persone, massio un migliaio con lo storico ma abbiamo casi in cui possono essere tranquillamete 2, 300mila.
    Non si tratterà comunque di archivi con milioni di entry,

    MIchele
  • Re: Riprogettazione tabella utenti

    E' un pochino troppo generico, c'è una bella differenza tra 300 e 300 mila.
    nel primo caso puoi banalmente creare una tabella fittizia dinamica, stile json.
    trasformi il campo "ruolo" in caratteri, e ci metti dentro la lista dei ruoli ad esempio
    studente;docente;genitore;preside;
    in questo caso cambi poco le tue query: invece di ... where ruolo='studente' diventerà where ruolo LIKE '%studente;%'
    l'effetto negativo è che queste interrogazioni richiedono una full-scan.
    il che va bene, se le righe son poche.
    va male se son tante e frequentemente accedute.

    in alternativa potresti usare un engine che supporta le ricerche fulltext, magari mergia-to con l'RDBMS. Se usi mysql puoi usare anche mariadb+sphinx per questo genere di interrogazioni.
    però avrai gli indici che non saranno aggiornati automaticamente e così via.

    l'ulteriore possibilità, che incide però sulle query, è la codifica a bit.
    studente=1
    docente=2
    genitore=4
    preside=8

    in questo caso sommerai (OR) i ruoli per ottenere in forma codificata. Ad esempio ruolo=6 implica sia docente che genitore.
    le tue query attuali diventeranno AND maschera per identificare "spacchettando" i vari ruoli.

    ci sono poi alternative più hard core, ovvero usare rdbms con supporto per colonne dinamiche (es. ultime versioni di mariadb).

    poi c'è sempre la possibilità di normalizzazione con tabella separata e relazione uno-a-molti, dove però pagherai un join per ogni where.

    insomma le possibilità sono tante, ma devi avere le idee ben chiare su "quanti" dati hai, e come vorrai gestirli.
  • Re: Riprogettazione tabella utenti

    Ci sono installazioni con qualche centinaio di entry nella tabella utente ed altre che possono averne anche 200k.
    Non si tratta di un proggetto per un cliente specifico ma di un servizio cloud già avviato, che ha già decine di clienti, piccoli e grandi.
    Inevitabilmente dovrò rifarmi al caso peggiore e pensare una riprogettazione sul caso peggiore per così dire.

    Idealmete in effetti l'idea o di un campo con l'elenco dei ruoli o di una machera di bit (più impattante), potrebbero essere una opzione percorribile.
    Ovviamente un'assoziazione tramite una tabella terza sarebbe più pulita ma decisamente più impattante sia per le modifiche che per la necessita di avere sempre una join.

    Idea folle, riconvertire questi ruoli in flag expliciti sulla tabella... tipo role1, role2, role3 poi mappati con i ruoli effettivamente presenti e quindi flaggati di conseguenza.
    Soluzione forse (non forse) brutta stilisticamente ma che salverebbe parecchio l'efficienza, pur richiedendo un intervento sul codice esistente...

    Mah
  • Re: Riprogettazione tabella utenti

    mikele78 ha scritto:


    Ci sono installazioni con qualche centinaio di entry nella tabella utente ed altre che possono averne anche 200k.
    E allora sistema il codice.
    Se è un progetto così grande mi pare il lavoro di un pomeriggio, nel caso peggiore
    Ovviamente un'assoziazione tramite una tabella terza sarebbe più pulita ma decisamente più impattante sia per le modifiche che per la necessita di avere sempre una join.
    I join non è che siano poi così terribili, in questo caso.
    Cambiare il codice mi sembra la scelta più facile, basta che dai sotto di grep per il nome della tabella e inserisci la versione con join
    Idea folle, riconvertire questi ruoli in flag expliciti sulla tabella... tipo role1, role2, role3 poi mappati con i ruoli effettivamente presenti e quindi flaggati di conseguenza.
    non capisco cosa significhi, ma non è una soluzione.

    Il modo più logico sarebbe operare a oggetti, o simil oggetti, o comunque scrivere qualche funzione del tipo

    qualiruoli(i_codiceutente) => ritorna l'elenco dei ruoli per un utente
    hounruolo(i_codiceutente,i_ruolo) => ritorna vero o falso se ho il ruolo X
    con le ausiliarie
    aggiungiruolo(i_codiceutente,i_ruolo)
    rimuoviruolo(i_codiceutente,i_ruolo)

    mascherando il modo effettivo con il quale operano queste funzioni.
    inizialmente lasciale uguali (cioè reimplementa il meccanismo che hai ora), a scopo di debug.

    decidi poi se i ruoli sono qualcosa di statico, hardcoded nel sorgente, oppure se a sua volta li mantieni in una tabella.
    da quanto posso intuire hanno gestioni molto diverse, quindi hardcoded è forse meglio (ovviamente li metterai in un SOLO punto del sorgente)

    poi in un "colpo solo", quando l'utilizzo delle funzioni è "rodato", le cambi (aggiungi nuovi ruoli, cambi il db eccetera) et voilà dramma risolto.

    tra l'altro questo ti consente facilmente di porre in piedi meccanismi di logging, cosa molto interessante e in generale utile, soprattutto per i ruoli, livelli di accesso eccetera
  • Re: Riprogettazione tabella utenti

    mikele78 ha scritto:


    Nella sostanza, l'applicazione gestisce delle persone che poossono essere studenti, insegnanti, oppure genitori.
    Quindi, un ruolo per ogni utente. OK

    mikele78 ha scritto:


    Quindi un utente ha ruolo teacher, un altro student ed un altro parent.
    Corretto.

    mikele78 ha scritto:


    Ovviamente questo è quanto di più distante dalla realtà. Potrei essere uno studente ma anche un docente, o diventarlo nel tempo.
    Potrei essere un genitore ma voler frequentare come studente.
    Assolutamente no.
    Non ha senso che lo stesso utente possa ricoprire contemporaneamente più ruoli.
    Questo avrebbe senso solo in strutture gerarchiche in cui lo stesso utente, ad esempio, gestisce altri utenti, che a loro volta possano gestire altri utenti, e così via... Ma in questo caso si parla di gestione di LIVELLI, non di ruoli.

    Anche perché se, come immagino, ogni ruolo dispone di permessi differenti all'interno dell'applicazione, voglio poi vedere come li gestisci se l'account è uno solo...
  • Re: Riprogettazione tabella utenti

    gibra ha scritto:


    Assolutamente no.
    Non ha senso che lo stesso utente possa ricoprire contemporaneamente più ruoli.
    Questo avrebbe senso solo in strutture gerarchiche in cui lo stesso utente, ad esempio, gestisce altri utenti, che a loro volta possano gestire altri utenti, e così via... Ma in questo caso si parla di gestione di LIVELLI, non di ruoli.
    Beh no perdonami, ha assolutamente senso che una persona (diciamo un codice fiscale) possa ricoprire più ruoli, anche contemporaneamente.
    Potrei essere studente e genitore, oppure genitore e docente.
    Perchè no? Il mio errore è stato proprio non considerare quesato fin dall'inizio.

    gibra ha scritto:


    Anche perché se, come immagino, ogni ruolo dispone di permessi differenti all'interno dell'applicazione, voglio poi vedere come li gestisci se l'account è uno solo...
    Certo questo è un aspetto da tenere in considerazione. Una strada magari semplicistica è di chiederti, quando accedi al sistema, se vuoi accedere ad esempio come docente o come genitore.
  • Re: Riprogettazione tabella utenti

    mikele78 ha scritto:


    Beh no perdonami, ha assolutamente senso che una persona (diciamo un codice fiscale) possa ricoprire più ruoli, anche contemporaneamente.
    Potrei essere studente e genitore, oppure genitore e docente.

    mikele78 ha scritto:


    Certo questo è un aspetto da tenere in considerazione. Una strada magari semplicistica è di chiederti, quando accedi al sistema, se vuoi accedere ad esempio come docente o come genitore.
    Vuoi che l'utente abbia un solo account, ma poi chiedi a lui con che tipo di account accedere.
    Mi pare di 'leggere' una contraddizione in tutto questo.

    Naturalmente, il tutto dipende dalle differenze nella modalità di gestione nei diversi ruoli, cosa di cui noi non sappiamo assolutamente nulla. E senza queste informazioni è molto difficile poter dare dei suggerimenti mirati.
  • Re: Riprogettazione tabella utenti

    gibra ha scritto:


    Vuoi che l'utente abbia un solo account, ma poi chiedi a lui con che tipo di account accedere.
    Mi pare di 'leggere' una contraddizione in tutto questo.
    Non direi, ho scritto che l'utente per forza di cosa può rivestire più ruoli anche contemporaneamente (magari docente e genitore) e questo fa parte della realtà quindi non è un concetto opinabile (l'ho sottovalutato all'inizio purtroppo).

    Dopo di che pur impersonando più ruoli, la persona è sempre la stessa, ha un CF una mail ed un numero di telefono, non penso mi potresti suggerire di dargli tre account diversi.
    Per evitare di presentargli un'interfaccia che sia un mixone incomprensibile, non mi pare astrusa l'idea di consentire all'utente uno switch di ruoli.

    gibra ha scritto:


    Naturalmente, il tutto dipende dalle differenze nella modalità di gestione nei diversi ruoli, cosa di cui noi non sappiamo assolutamente nulla. E senza queste informazioni è molto difficile poter dare dei suggerimenti mirati.
    Eh i ruoli possono avere funzioni ben diverse, è quasi improponibile una visione unificata.

    Detto tutto ciò, la struttura attuale del database è il grosso ostacolo per una unificazione vera delle utenze.
  • Re: Riprogettazione tabella utenti

    mikele78 ha scritto:


    Detto tutto ciò, la struttura attuale del database è il grosso ostacolo per una unificazione vera delle utenze.
    Bhè dai... stimo lavoro di un pomeriggio
Devi accedere o registrarti per scrivere nel forum
10 risposte