in

UGISS Community

Il sito della community dello User Group Italiano di SQL Server

regole di normalizzazione e l'utilizzo dei null

Last post 07-06-2007 18.36 by dmauri. 4 replies.
Page 1 of 1 (5 items)
Sort Posts: Previous Next
  • 07-02-2007 10.47

    • Digi
    • Top 150 Contributor
    • Joined on 06-04-2007
    • Posts 2
    • Points 55

    regole di normalizzazione e l'utilizzo dei null

    sto approfondendo l'argomento "Design di database" e mi è venuto un dubbio riguardo le regole di normalizzazione e l'utilizzo dei null,
    tra l'altro ho letto e riletto l'articolo di Davide a riguardo... http://www.microsoft.com/italy/msdn/risorsemsdn/sql/sql2.mspx

    Però mi è venuto un dubbio e per spiegarlo partirei da un esempio che, in situazioni diverse, ho già realizzato nello stesso identico modo forse una 50 volte:

    per realizzare una semplice procedura di fatturazione vado a pescare i dati dalle tabelle "Vendite" e "Clienti"
    tabella Vendite : codVendita, codDettaglioVendita, codCliente, dataVendita, Totale
    tabella Clienti : ORA HO UN DUBBIO!!!!!
    supponiamo che i Clienti possono essere sia persone fisiche che aziende ,
    quindi per i primi i dati saranno qualcosa del tipo nome,cognome,codicefiscale.... etc etc
    mentre per le aziende avrò per esempio ragione sociale, tipo società, p.iva.... etc etc

    Fino ad oggi non mi sono mai posto nè dubbi nè problemi e senza nessuna remora andavo a realizzare un solo megatabellone
    che riuniva entrambe le tipologie di Cliente. Quindi se il cliente è una persona tutti i campi relativi all'azienda sono null, al contrario
    se il cliente è una azienda i campi realtivi alla persona sono null.

    Forse il megatabellone è la risposta giusta al problema ma ora ho un tarlo nella testa che mi dice che non è il modo corretto
    per rappresentare i Clienti, tuttavia non riesco a capire quale strada prendere come alternativa:
    se spacco i clienti in due realizzando quindi le tabelle ClientiPersone e ClientiAziende poi sulla tabella Vendite che ci metto?
    quale sarebbe il Design corretto?

    Ringrazio anticipatamente per la disponibilità.

    ciao ciao.

     

    • Post Points: 20
  • 07-02-2007 22.32 In reply to

    • dmauri
    • Top 10 Contributor
      Male
    • Joined on 05-14-2007
    • Novate Milanese
    • Posts 1.182
    • Points 15.485

    Re: regole di normalizzazione e l'utilizzo dei null

    Ciao Digi

    Bella domanda! Bella perché mi permette di introdurti il concetto dei SuperTypes e dei SubTypes.

    Nella tua situazione è possibile pensare di avere un'entità "astratta" chiamata Cliente, e due entità di tipo Cliente che "derivano" da  quest'ultima. Le due entità in questione sarebbero Persone e Aziende.

    Tra l'entita Cliente e l'entita Persona, così come tra Cliente e Azienda c'è una relazione 1:1 di tipo "is a" (è un):

     

    Persona IS A Cliente

    Azienda IS A Cliente

     

    Questo permette di disgnare il database in questo modo:


    create table dbo.Clienti

    (

        id_cliente int not null identity primary key,

        ragione_sociale varchar(100) not null,

        codice_fiscale char(11) not null

    )

    go


    create table dbo.Persone

    (

        id_cliente int not null primary key,

        nome varchar(20) not null,

        cognome varchar(20) not null,

        constraint FK_Persone_Clienti foreign key (id_cliente) references dbo.Clienti (id_cliente)

    )

    go


    create table dbo.Aziende

    (

        id_cliente int not null primary key,

        tipo_societa char(1) not null,

        partita_iva char(16) not null,

        constraint FK_Aziende_Clienti foreign key (id_cliente) references dbo.Clienti (id_cliente)

    )

    go


    in questo modo i campi comuni rimangono in "clienti", mentre i campi specifici di ogni SubType (Persone ed Aziende) sono nelle tabelle dedicate.

    Cosi facendo non hai da gestire i null, hai tabelle compatte con solamente le colonne necessarie, e, nel caso ti servisse, puoi vedere tutti i clienti come se fossere in una unica tabella creando una semplice vista:

    create view dbo.vw_Clienti

    as

    select

         c.id_cliente,

         c.ragione_sociale,

         c.codice_fiscale,

         p.nome,

         p.cognome,

         a.tipo_societa,

         a.partita_iva

    from

         dbo.Clienti c

    left outer join

         dbo.Aziende a on a.id_cliente = c.id_cliente

    left outer join

         dbo.Persone p on p.id_cliente = c.id_cliente

    go

    Spero di averti chiarito i dubbi :-)

    Davide Mauri
    Microsoft MVP - SQL Server, MCP, MCAD, MCDBA, MCT - http://www.davidemauri.it
    Socio Fondatore e Mentor di Solid Quality Learning Italy - http://www.solidq.com
    Presidente di UGISS: User Group Italiano Sql Server - http://www.ugiss.org
    • Post Points: 20
  • 07-03-2007 15.32 In reply to

    • Digi
    • Top 150 Contributor
    • Joined on 06-04-2007
    • Posts 2
    • Points 55

    Re: regole di normalizzazione e l'utilizzo dei null

    Grandissimo! certo che a te i null ti danno al voltastomaco Big Smile!!!

    Ora pongo un' altra domanda un po' più impegnativa... o meglio è l'argomento ad essere decisamente più impegnativo...

    la questione è la persistenza di una entità di business in un database relazionale, ho cercato su Forum, manuali, articoli e ne ho trovate di tutti i colori
    (comprese le tue battaglie con Jannky - Giancarlo Sudano ), la cosa non mi sorprende dato anche io mi sono reso conto che la persistenza dei dati è uno dei punti cruciali
    di tutte le applicazioni (forse ad esclusione di quelle di Business Intellingence).
    con molto rammarico mi spiace non aver partecipato ai meeting sull'argomento...Crying

    Comunque alla fine sono riuscito a farmi una mia idea: e penso che il punto di contatto tra RDBMS e OOP è "meglio" che siano viste/SProc
    ... però non nascondo le mie difficoltà quando incontro relazioni 1:n

    Un po' di conforto: il Data Access Layer è lo strato di software che si occupa della persistenza delle entità di Business? giusto??? Embarrassed

    Riprendendo sempre come esempio il tuo articolo sulla normalizzazione di una pseudobiblioteca
    facciamo finta che alla bibliotecaria, è anche una bella ragazzuola, arriva un nuovo libro
    la procedura "logica" di inserimento dovrà registrare solo l'entità libro
    ma dietro le quinte si tratterà di effettuare l'inserimento "contemporaneo" come minimo
    1)nella tabella Libri (ISBN,Titolo)
    2)nela tabella AutoriLibri (ISBN,idAutore)

    ora mi potresti spiegare qualè il modo corretto di passare a una SProc sia il libro che gli autori
    per poter finalmente riuscire a mettere all'interno della stessa SProc usp_LibroCreate tutta la gestione della transazione?

    Mi viene logico pensare che la transazione sia da gestire nella SProc usp_LibroCreate  poichè....

    In un database devono essere inseriti solo dati “reali” (e quindi veri) in quanto l’introduzione di un dato non corretto (e quindi falso) impedirebbe al motore del database (che è quindi un motore di inferenza logica) di dare risposte corrette. Appare quindi molto importante come durante la progettazione e la programmazione del database sia necessario definire anche tutta quella serie di meccanismi che impediscano a chiunque, indipendentemente dall’applicazione di accesso ai dati che verrà usata, di poter inserire dati non veri nel database.

    (Parola di Davide Mauri... rendiamo grazie a Davide Yes)

    ho sempre cercato di seguire questa regola (anche se io partivo non da megadefinizioni ma daI buonsenso) ma non sempre ci sono riuscito.

    In ogni caso tornando alle entità composte da una serie di altre identità correlate (Libri - AutoriLibri) ho utilizzato vari barbatrucchi :
    1)in SQL2000 per i casi più semplici,tipo il famoso "Libro", me la sono cavata mettendo nella usp_LibroCreate un parametro in input varchar(8000)
    contenente una lista di idAutore separati da un carattere tipo "," Idea

    mentre per i casi di entità più complesse era il DAL specializzato, nell' esempio quello sulla classe libro,
    che iniziava la transazione e all'interno di questa eseguivo n SProc usp_AutoreLibroCreate tante volte quanti sono gli autori .Devil

    2)in SQL2005 "migliorerei" le cose grazie alle variabili di tipo XML Surprise un po' più, passami il termine, "carine" dei varchar(8000) anche perchè con XML
    è possibile definire relazioni e sequenze... tuttavia anche con SQL2005 nei casi un po' più complessi la transazione mi viene quasi automatico farla comandare dalla fuzione "Create"
    del DAL dell'oggetto più corposo Angry... è sempre il  "Libro"

    Il fatto è che mi rendo conto di aver raggiunto un livello paradossale: per i casi semplici riesco a raggiungere il massimo delle (mie) potenzialità sia in termini di prestazioni che di coerenza con il database (inferenza logica!!!) ma per i casi più complessi mi riduco a ciclare liste e/o sottoliste e per ogni oggetto chiamare la rispettiva Create
    praticamente un qualcosa che se utilizzassi un ORM forse avrei delle prestazioni migliori.

    Ho detto castronate? Saper di aver capito la funzione del "DAL",  credo sia già qualcosa...Big Smile
    Ma ora mi chiedo... come dovrebbe "funzionare" un DAL che gestisce la persistenza sul database in modo "corretto" del libro?...coi i miei barbatrucchi Confused?

    Spero di non aver fatto troppa confusione nell'esporre il mio dubbio...

    già che cero mi sono divertito un po' con le faccine...Embarrassed

    ciao ciao.

     

    • Post Points: 35
  • 07-06-2007 18.08 In reply to

    • dmauri
    • Top 10 Contributor
      Male
    • Joined on 05-14-2007
    • Novate Milanese
    • Posts 1.182
    • Points 15.485

    Re: regole di normalizzazione e l'utilizzo dei null

    Scusa il ritardo nella risposta ma è stata una settimana intensa Smile 

    Digi:

    Grandissimo! certo che a te i null ti danno al voltastomaco Big Smile!!!

    Beh....se posso evitarli li evito, rendono la programmazione più complessa, raramente aggiungendo del valore aggiunto.

     

    Digi:

    Comunque alla fine sono riuscito a farmi una mia idea: e penso che il punto di contatto tra RDBMS e OOP è "meglio" che siano viste/SProc

    Scelta molto saggia IMHO.

     

    Digi:

    ... però non nascondo le mie difficoltà quando incontro relazioni 1:n

    Beh ma questo è un limite del software attuale, che come hai già sicuramente capito non deve e non può inficiare il disegno del modello dati, altrimenti "sporcheremmo" il nostro modello con necessità date dell'implementazione fisica che dipende unicamente dall'evoluzione del software e che, evidentemente , non deve essere un qualcosa che ci pone un limite alla modellazione della nostra realtà.

    Cmq non ti preoccupare che è possibile già oggi gestire senza problemi questa cosa (e la soluzione l'hai gia trovata), e dal 2008 con il supporto per i table-valued parameter di SQL Server 2008 il problema si risolverà alla radice. 

     

    Digi:

    Un po' di conforto: il Data Access Layer è lo strato di software che si occupa della persistenza delle entità di Business? giusto??? Embarrassed

     

    Correttissimo. 

     

    Digi:

    ora mi potresti spiegare qualè il modo corretto di passare a una SProc sia il libro che gli autori
    per poter finalmente riuscire a mettere all'interno della stessa SProc usp_LibroCreate tutta la gestione della transazione?

    Mi viene logico pensare che la transazione sia da gestire nella SProc usp_LibroCreate  poichè....

    Ri-Correttissimo. 

     

    Digi:

    ho sempre cercato di seguire questa regola (anche se io partivo non da megadefinizioni ma daI buonsenso) ma non sempre ci sono riuscito.

    Beh il buon senso è alla base di tutto :-) In effetti le regole di normalizzazione ed il modello relazionale è "buon senso" formalizzato matematicamente :-)

     

    Digi:
     

    In ogni caso tornando alle entità composte da una serie di altre identità correlate (Libri - AutoriLibri) ho utilizzato vari barbatrucchi :
    1)in SQL2000 per i casi più semplici,tipo il famoso "Libro", me la sono cavata mettendo nella usp_LibroCreate un parametro in input varchar(8000)
    contenente una lista di idAutore separati da un carattere tipo "," Idea

    Giusto, anche perchè in SQL 2000 non si poteva fare molto altro.... 

     

    Digi:

     
    mentre per i casi di entità più complesse era il DAL specializzato, nell' esempio quello sulla classe libro,
    che iniziava la transazione e all'interno di questa eseguivo n SProc usp_AutoreLibroCreate tante volte quanti sono gli autori .Devil

    Direi che non vedo nulla di male in questo. 

     

    Digi:

    2)in SQL2005 "migliorerei" le cose grazie alle variabili di tipo XML Surprise un po' più, passami il termine, "carine" dei varchar(8000) anche perchè con XML
    è possibile definire relazioni e sequenze... tuttavia anche con SQL2005 nei casi un po' più complessi la transazione mi viene quasi automatico farla comandare dalla fuzione "Create"
    del DAL dell'oggetto più corposo Angry... è sempre il  "Libro"

    Decisamente con SQL Server 2005 è molto meglio usare XML come strumento per passare i dati "complessi" tra DAL e database.

     

    Digi:

    Il fatto è che mi rendo conto di aver raggiunto un livello paradossale: per i casi semplici riesco a raggiungere il massimo delle (mie) potenzialità sia in termini di prestazioni che di coerenza con il database (inferenza logica!!!) ma per i casi più complessi mi riduco a ciclare liste e/o sottoliste e per ogni oggetto chiamare la rispettiva Create
    praticamente un qualcosa che se utilizzassi un ORM forse avrei delle prestazioni migliori.

    Beh ma in molti casi cosa credi che faccia un ORM? Smile

    Un consiglio che ti posso dare, in questi casi, è di mandare un unico batch a SQL Server e non tanti comandi singoli. Sicuramente avrai performance migliori. 

     

    Digi:

    Ho detto castronate? Saper di aver capito la funzione del "DAL",  credo sia già qualcosa...Big Smile

    Non direi! Smile Anzi, direi che sei sulla strada giusta.

     

    Digi:

    Ma ora mi chiedo... come dovrebbe "funzionare" un DAL che gestisce la persistenza sul database in modo "corretto" del libro?...coi i miei barbatrucchi Confused?

    Di trucchi sporchi non mi sembra di averne visti...continua pure su questa strada, cercando di preferire l'invio di un batch singolo piuttosto che l'invio di tanti singoli comandi. 

     

    Digi:
     

    già che cero mi sono divertito un po' con le faccine...Embarrassed

    eheheh Smile 

    A presto!

    Davide Mauri
    Microsoft MVP - SQL Server, MCP, MCAD, MCDBA, MCT - http://www.davidemauri.it
    Socio Fondatore e Mentor di Solid Quality Learning Italy - http://www.solidq.com
    Presidente di UGISS: User Group Italiano Sql Server - http://www.ugiss.org
    Filed under:
    • Post Points: 5
  • 07-06-2007 18.36 In reply to

    • dmauri
    • Top 10 Contributor
      Male
    • Joined on 05-14-2007
    • Novate Milanese
    • Posts 1.182
    • Points 15.485

    Re: regole di normalizzazione e l'utilizzo dei null

    A proposito di gestione dei Multiple-Valued paramters, ecco un bel post che fa chiarezza su qual'è il metodo migliore:

    http://sqlblog.com/blogs/peter_debetta/archive/2007/02/12/multiple-valued-parameters.aspx 

    Davide Mauri
    Microsoft MVP - SQL Server, MCP, MCAD, MCDBA, MCT - http://www.davidemauri.it
    Socio Fondatore e Mentor di Solid Quality Learning Italy - http://www.solidq.com
    Presidente di UGISS: User Group Italiano Sql Server - http://www.ugiss.org
    • Post Points: 5
Page 1 of 1 (5 items)
(C) 2007 User Group Italiano di SQL Server