• User Attivo

    @html5today said:

    Io farei tre tabelle: una con i campi "condivisi" (immagino "username", "password", "email", etc.) e una per ogni tipologia di utente con le colonne specifiche.

    Si chiama "normalizzazione": prova a cercare su papà Goooogle "First Normal Form SQL" 😉
    Ciao html5today,
    Una tabella unica con persone fisiche e giuridiche sarebbe già 1NF, perché nessuna tupla contiene duplicati e i dati rappresentano tutti un'entità univoca (l'utente). Sarebbe già anche 2NF... 😉
    La normalizzazione spesso dipende dall'utilizzo che si fa dei dati e nello specifico, trattandosi di una relazione 1 a 1, è auspicabile ridurre ad una sola tabella.
    Inoltre, in fase di interrogazione del db (ad esempio per mostrare l'anagrafica, dato l'id), dato che non si sa se l'utente è persona fisica o giuridica, sarebbe necessario richiamare sempre entrambe le tabelle, riducendo le prestazioni rispetto all'interrogazione su tabella unica.

    @rambco said:

    Si i gradi sono uguali, nel senso sono sempre utenti solo che a seconda della loro tipologia richiedo dati diversi per l'iscrizione e l'attivazione di vari function nella loro area personale.
    Se i dati diversi sono molti allora meglio separarli in due tabelle, se invece, come immagino, hai nome, cognome, indirizzo, telefono, ecc (e magari il codice fiscale), potresti risolvere aggiungendo un campo ragione sociale e facendo diventare il C.F. un campo C.F/P.I. (e se proprio vuoi un flag persona fisica/giuridica).

    Nome utente e password li terrei comunque a parte (perché non sempre sarà necessario portarsi dietro tutti i dati anagrafici) e ricorda di salvare le password in maniera sicura (ad esempio crittografate con md5).

    Ciao,
    Luca Bartoli


  • User Attivo

    @lucabartoli said:

    Una tabella unica con persone fisiche e giuridiche sarebbe già 1NF, perché nessuna tupla contiene duplicati e i dati rappresentano tutti un'entità univoca (l'utente). Sarebbe già anche 2NF... 😉
    Ciao Luca
    uhm, direi di no - ogni riga avrebbe delle colonne "nullable" (cioè di fatto che in alcuni casi possono essere NULL per design perchè usate solo per alcune "categorie" di record) e quindi sarebbe violata la condizione numero 4 della First Normal Form: h t t p : //en.wikipedia.org/wiki/First_normal_form

    Sebbene, effettivamente, la "dottrina" sia un po' divisa su questo punto... 😉 Infatti, a dire il vero, la normalizzazione per me non è una regola da seguire a prescindere e in maniera cieca ma piuttosto un suggerimento - che in questo caso mi sembra un buon suggerimento, dal momento che avere una singola tabella per due tipologie diverse di dati mi "suona" sbagliato.

    @rambco said:

    Si questa era uno soluzione che pensavo.
    Ma poi per mettere in relazione le tabelle, nelle tabelle contenenti i dati dei form indichirei l'id dell'utente, penso di si...
    Certamente, tu avrai un campo "id_utente" nella tabella degli utenti che usi come chiave per creare le relazioni con le tabelle "dettagli_privato" e "dettagli_persona_giuridica"


  • User Attivo

    Beh, se così fosse vorrebbe dire che ogni parametro opzionale dovrebbe essere su una tabella a parte, ovvero uno per tabella (altrimenti conterrebbe degli elementi che possono essere nulli). E' chiaro che un database così fatto diverrebbe praticamente inutilizzabile, no? 😉
    Non ho mai preso in considerazione questa regola per dire che una tabella è 1NF, esattamente come non prendo in considerazione le forme 4NF e 5NF, che degradano drasticamente le prestazioni di un db. Ritengo che siano importanti la qualità e la scalabilità di un database, nella misura in cui non si ottiene un degrado complessivo delle prestazioni, per un utilizzo stabilito.

    Credo che le forme normali siano finezze in questo caso più che superflue e sarebbe meglio orientarsi sul "simple is better", specialmente se lo sviluppatore non ha molta dimestichezza con i mezzi a disposizione.

    Comunque, hai un'ottima cultura e ti ringrazio per essere qui a dare una mano.

    Buona serata,
    Luca Bartoli


  • User Attivo

    @lucabartoli said:

    Beh, se così fosse [...]
    In realtà è così, (purtroppo :2: non sono stato io a scrivere le regole della normalizzazione dei DB, ma la quarta regola dice proprio questo.

    Che poi questa regola vada "interpretata" è giusto, ma...
    @lucabartoli said:

    [...] vorrebbe dire che ogni parametro opzionale dovrebbe essere su una tabella a parte[...]
    No, è qui l'errore: non stiamo parlando di "parametri opzionali" ma di "informazioni non pertinenti".

    Le informazioni opzionali possono benissimo, a mio modo di vedere, restare in un unica tabella (quindi violando la 1NF dal momento che per definizione sono nullable) purchè siano pertinenti e omogenei tra loro.

    Facciamo un esempio, partendo dalla richiesta dell'OP.

    Prendiamo una tabella generica "utenti" in cui inserire tutti gli utenti, a prescindere dalla loro tipologia (la soluzione che suggerivi tu). In questa tabella avremo per forza di cose un campo "Partita IVA" per le persone giuridiche. Ora, questo campo, per una categoria di record (le persone fisiche) non è "opzionale" ma è non pertinente, nel senso che nessuna persona fisica avrà mai una partita IVA.

    Ecco dove si applica, a mio modo di vedere, la quarta regola della 1NF: avere tutti i campi di una tabella omogenei, ovvero con una relazione "logica" con il record di riferimento.

    Ed ecco perchè secondo me è meglio avere tre tabelle:

    • utenti - con i campi comuni quali possono essere username, password, email, ...
    • persone_fisiche - con i campi specifici (anche se opzionali) delle persone fisiche, tipo "data di nascita"
    • persone_giuridiche - idem ma per le persone giuridiche, tipo "partita iva" o "data di fondazione"

    @lucabartoli said:

    Comunque, hai un'ottima cultura e ti ringrazio per essere qui a dare una mano.
    Ti ringrazio - a dire il vero il mio SQL e uso di database è un po' arrugginito e sto sfruttando questa discussione per rinfrescarmi un po' la memoria...

    @lucabartoli said:

    Buona serata
    Buona serata a te! 🙂


  • User

    wow, grazie a tutti sta diventando una discussione interessante...non sono un guru di sql ma dalla discussione ho preso un paio di spunti molto interessanti, cmq sto studiando bene come organizzare le tabelle, minimo 2 poi vediamo se suddividere il tutto in 3 come detto da html5today


  • User

    domanda !!

    ponendo il caso di 3 tabelle !

    utenti
    utnPFisica
    utnPGiuridica

    Volendo fare un join tra la tabella utenti e la tabella associata all'utente inche modo mi comporto ?

    devo fare un join a 3 tabelle ? es...

    select * from utenti inner join utnPFisica on utenti.id = utnPFisica.utente_id inner join utnPGiuridica on utenti.id=utnPGiuridica.utente_id where utenti.id = 10

    giusto ?


  • User Attivo

    Direi proprio di no 😉

    Il vantaggio di questo approccio è dividere "logicamente" i dati relativi ad una categoria rispetto i dati relativi all'altra quindi la JOIN la devi fare solo con la tabella corrispondente al "tipo utente" specifico.

    Inoltre la tua query non funzionerebbe perchè delle tue due JOIN una sarebbe sempre "falsa" dal momento che ad ogni utente può essere associato solo un record di una delle due tabelle (cioè un utente può essere solo persona fisica o persona giuridica e non entrambi, giusto?)

    Ovviamente nel tuo PHP devi avere la "logica" per decidere quale tabella interrogare - oppure usare due query, interrogando prima la tabella "utenti" (dove avrai un campo "tipo") e poi la tabella "giusta" in base al "tipo" utente.

    Una considerazione: tutta la discussione avuta sino ad ora è un po' "di scuola" quindi può darsi che in alcune applicazioni pratiche sia più conveniente violare le regole di normalizzazione a vantaggio di una maggior efficienza o manutenibilità del codice. Se ad esempio tu mostri spesso gli utenti in liste indifferentemente dalla loro tipologia oppure non sai a priori (per es. avendolo nella sessione o passandolo come parametro) la tipologia di utente da mostrare potrebbe essere più conveniente avere tutto in un'unica tabella. La scelta dipende dall'implementazione, da considerazioni di efficienza e, in ultima e più importante istanza, dalle tue preferenze.


  • User

    ok, grazie !


  • User

    eccomi ritorno ehehe

    allora altro dubbio.... il software deve gestire dei pagamenti.. ovvero gli utenti devono eseguire un tesseramento per poi poter richiedere delle autoriazioni....

    io avevo in mente di fare un'unica tabella pagamenti da agganciare poi con due tabelle, alle tabella Tesseramenti e Autorizzazioni

    Tabelle : Tesseramenti, Autorizzazioni, Pagamenti
    Tabella di collegamento :

    • Associazione_Tesseramenti : che collega l'id della tessera al pagamento sulla tabella pagamenti

    • Associazione_Autorizzazioni : che collega l'id dell'autorizzazione al pagamento sulla tabella pagamenti

    Un approccio del genere è giusto ? Suggerimenti ?


  • User

    @rambco said:

    eccomi ritorno ehehe

    allora altro dubbio.... il software deve gestire dei pagamenti.. ovvero gli utenti devono eseguire un tesseramento per poi poter richiedere delle autoriazioni....

    io avevo in mente di fare un'unica tabella pagamenti da agganciare poi con due tabelle, alle tabella Tesseramenti e Autorizzazioni

    Tabelle : Tesseramenti, Autorizzazioni, Pagamenti
    Tabella di collegamento :

    • Associazione_Tesseramenti : che collega l'id della tessera al pagamento sulla tabella pagamenti

    • Associazione_Autorizzazioni : che collega l'id dell'autorizzazione al pagamento sulla tabella pagamenti

    Un approccio del genere è giusto ? Suggerimenti ?

    Ciao, l'approccio è ideologicamente corretto, tuttavia è ridondante fare 2 tabelle per gestire gli abbinamenti, ne basta una strutturata ipoteticamente così come segue.

    **id | tipo | id_assoc | pagamento**
    ```Dove:
    
    - **id **è l'identificativo univoco della riga;
    - **tipo **identifica la tipologia di abbinazione (tesseramento/autorizzazione);
    - **id_assoc **è l'id da abbinare del tesseramento/autorizzazione in questione;
    - **pagamento **è l'id associato al pagamento in questione.
    
    
    Spero sia abbastanza chiaro ;-)

  • User

    mmm anche potrebbe essere un'ottima soluzione per risparmiare tabelle


  • User

    Chiaro che tutto dipende dall'applicazione che si intende sviluppare.
    A seconda del contesto alcune logiche ridondanti possono essere più performanti su numeri sconfinati mentre in medio-piccole applicazioni non conviene in quanto il numero "esiguo" di record non comporta problemi prestazionali risultando spesso invece il metodo più rapido per gestire la cosa.

    Sta all'abilità di chi struttura il database prevedere in base alla vastità dell'applicazione, e al numero di record che si aspetta di immagazzinare, di creare una determinata logica di archiviazione relazionale, al posto di un altra, al fine di poterne ottimizzare al meglio le operazioni sui dati ivi archiviati.


  • User

    Hai ragione, comunque rapportarsi con gli altri serve anche a capire le varie metodologie con cui affrontare il problema no 😉


  • User

    @rambco said:

    hai ragione, cmq rapportarsi con gli altri serve anche a capire le varie metodologie con cui affrontare il problema no 😉

    Motivo per cui è stata mia premura esprimere il precedente concetto, magari arriva qualcuno che mi smentisce/corregge e mi apre un mondo nuovo.

    Se mi sono posto lasciando intender male, ti chiedo scusa 🙂


  • User

    No figurati anzi. 😉