Normalizzazione necessaria come fare

di il
22 risposte

Normalizzazione necessaria come fare

Ciao a tutti
avevo aperto una discussione in un'altra sezione e mi hanno consigliato di
riportarla qui....ho ben chiaro quello che vorrei ottenere (che a quanto pare con access non è poco... )
ma un problema con un pulsante mi/ci ha reso evidente il fatto che il mio database abbia un problema di
progettazione sbagliata .quindi provo ad esporvi il problema qui nella speranza che qualcuno possa consigliarmi
un modo per avvicinarmi alla soluzione...basterebbe anche una dritta....forse devo integrare con una query?...o
concentrarmi sul tipo di relazione fra le tabelle?....insomma ...mi mi sono bloccato qui...
questo è lo scenario :

Il database riguarda la gestione di clienti , immobili richiesti , immobili offerti e relazione intrattenute con i primi da un agente immobiliare.
Le tabelle ed i rispettivi campi sono:
CLIENTE -ID(Chiave primaria)-Nome-Cognome
IMMOBILIOFFERTI -ID(Chiave primaria)-Tipologia-Comune-Richiesta-IdCliente(chiave esterna)
IMMOBILIRICHIESTI -ID(Chiave primaria)-Tipologia-Città-IdCliente(chiave esterna)
RELAZIONI -Data-Contenuto-IdCliente(chiave esterna)

La relazioni tra le tabelle sono tre e sono tutte uno a molti tra la chiave primaria della tabella CLIENTE e le chiavi esterne delle altre tre tabelle.

Le maschere sono :
PANNELLO (con le tre sottomaschere SOTTOMASCHERARELAZIONI-SOTTOMASCHERAIMMOBILIOFFERTI-SOTTOMASCHERAIMMOBILIRI
CHIESTI)
..qui nella maschera PANNELLO ho inserito i dati della tabella CLIENTE

INGESTIONE
..qui l'origine record è la tabella IMMOBILIOFFERTI
SOTTOMASCHERARELAZIONI
....qui ho inserito i dati della tabella RELAZIONI
SOTTOMASCHERAIMMOBILIRICHIESTI
..i record li prendo dalla tabella IMMOBILIRICHIESTI
SOTTOMASCHERAIMMOBILIOFFERTI
...qui ho inserito i dati della tabella IMMOBILIOFFERTI ed ho anche inserito un pulsante con macro che fa aprire la maschera INGESTIONE...
Quello che vorrei ottenere è questo: nella maschera pannello - sottomaschera immobili offerti...quando clicco sul pulsante apro la maschera INGESTIONE e da li inserisco un nuovo record alla tabella IMMOBILIOFFERTI..il cui contenuto a sua volta va a finire poi nella SOTTOMASCHERAIMMOBILIOFFERTI visto che questa prende i dati dalla stessa tabella...


praticamente succede che lo stesso cliente potrebbe richiedere un immobile in acquisto....quindi che so...mi dice...vorrei un appartamento a Milano.....ma anche darmi mandato a vendere un altro immobile...e di questo acquisisco tutte le informazioni e le specifiche ....riguardo lo stesso cliente mi serve di prendere un appunto su quando ci siamo sentiti e cosa ci siamo detti.....
e questo lo vorrei visualizzare tutto in una schermata...ma non ci entrerebbe...quindi ho pensato di fare una maschera "PANNELLO" dove ho giusto le cose importanti che mi servono a colpo d'occhio e da qui posso inserire l'appunto di una relazione intrattenuta,la richiesta di un immobile...ma....se mi da incarico per un immobile da vendere allora le cose cambiano...
in questo caso devo andare ad inserire nel DB un sacco di dati......mtq...piano...garage si garage no ...riscaldamenti ...etc....
e da qui l'esigenza che ...se devo inserire un "IMMOBILEOFFERTO" devo farlo tramite un'altra maschera che fa riferimento ad una tabella dedicata solo agli immobili in vendita...

22 Risposte

  • Re: Normalizzazione necessaria come fare

    Io partirei dalla seguente organizzazione tabelle:

    La tabella ImmobiliOfferti parla degli Immobili in quanto tali. Potrebbe chiamarsi semplicemente Immobili.
    Ci sono alcuni campi ripetuti in Immobili e ImmobiliRichiesti: ciò è errato progettualmente.
    La tua struttura tabella ritengo debba essere così:

    Clienti
    IDCliente (PK)
    tutti i campi tipicamente anagrafici del Cliente

    Immobili
    IDImmobile (FK)
    tutti i campi che parlano di quell'Immobile
    …se hai troppi campi sulla stessa tabella che lo descrivono, sono sicuro che non li compili sempre tutti. Io lascerei quelli più essenziali/indispensabili, tipo Indirizzo, Città, poi ci vedrei una tabella DettagliImmobili e relazione Immobili.IDImmobile uno-a-molti DettagliImmobili.IDImmobile.
    Da togliere la relazione con il campo Clienti.IDCliente e eliminare il campo Immobili.IDCliente

    MovimentiImmobili (che sostituisce ImmobiliRichiesti)
    IDMI (PK)
    DataMovimento
    Descrizione
    …altri campi che tu ritieni utili…ovviamente cambiando il nome la tabella, cambiano anche LOGICHE denominazioni di campi
    IDImmobile (FK)
    IDCliente (FK)

    Relazioni
    IDRelazione (PK)
    TimeRelazione (con il formato Data/Ora completo)
    DescrizioneRelazione
    IDCliente (FK)

    Linee di join:
    Clienti.IDCliente uno-a-molti MovimentiImmobili.IDCliente
    Clienti.IDCliente uno-a-molti Relazioni.IDCliente
    Immobili.IDImmobile uno-a-molti MovimentiImmobili.IDImmobile
  • Re: Normalizzazione necessaria come fare

    Grazie per la risposta Osvaldo
    ho iniziato a normalizzare secondo i tuoi consigli ma mi sono subito reso conto che sotto l'aspetto della ridondanza
    le tue modifiche sicuramente snelliscono il DB e l'aggiunta della tabella DettagliImmobili sicuramente evita l'appesantimento..
    ma per il resto viene sconvolta la logica di quello che si vorrebbe ottenere.
    Ad esempio : la relazione TAB_Cliente.IDCliente(PK)-TAB_Immobili.IdCliente(FK) è fondamentale !!:
    quello che voglio ottenere non è di sapere chi sono i clienti o quali sono gli immobili....o meglio .... mi serve poter consultare
    questi dati ma la cosa più importante per me è :
    avere un pannello in cui visualizzo un cliente e che mi dica : quanti e quali immobili mi ha dato in gestione , quanti e quali immobili mi ha richiesto , quando e cosa ci siamo detti..
    per me un cliente può avere diversi immobili e farmi diverse richieste e ogni immobile deve avere un cliente(proprietario)...
    Lo so che può sembrarti strano ma per un agente il cliente non è solo chi compra ma anche chi vende e a volte lo stesso cliente fa l'una e l'altra cosa..
    Anche la sostituzione della tabella ImmobiliRichiesti per quello che voglio ottenere non credo abbia senso, al massimo la si potrebbe chiamare Richieste....perchè non ha nulla a che fare con gli immobili bensì è strettamente collegata al Cliente....ribadisco...un cliente POSSIEDE immobili ben precisi e FA RICHIESTE per immobili ipotetici...quindi la richiesta non è collegata ad un immobile ma ad un cliente...
  • Re: Normalizzazione necessaria come fare

    ario75 ha scritto:


    in cui visualizzo un cliente e che mi dica : quanti e quali immobili mi ha dato in gestione , quanti e quali immobili mi ha richiesto , quando e cosa ci siamo detti..
    per me un cliente può avere diversi immobili e farmi diverse richieste e ogni immobile deve avere un cliente(proprietario)...
    Lo so che può sembrarti strano ma per un agente il cliente non è solo chi compra ma anche chi vende e a volte lo stesso cliente fa l'una e l'altra cosa..
    Esattamente per questo motivo serve la tabella MovimentiImmobili. In essa aggiungi un campo che discrimina se si tratta di Offerta, Richiesta, Proposta...adesso non conosco i dettagli del tuo ambito professionale.
    Entriamo nel pratico: tu sostieni che l'Immobile X in Via Garibaldi 10 di 100 mq con caratteristiche A, B, C è in Vendita proposta dal Cliente Rossi Mario. Secondo te l'immobile X è "strettamente legato" a Rossi Mario...ma come fa ad esserlo se poi lo comprerà Bianchi Antonio? Allora l'Immobile X resta X nella propria tabella Immobili. La tabella MovimentiImmobili traccerà tutti gli spostamenti "storici"...ovviamente A PARTIRE DAlla data più antica. Sarà un'apposita query che ti screma tutte le Proposte per sapere i relativi "proprietari".
  • Re: Normalizzazione necessaria come fare

    Giustissimo hai perfettamente ragione...non stavo considerando un aspetto importantissimo di questo DB....
    ho anche riletto come vedresti tu la struttura e adesso mi è più chiara...
    ma non capisco ancora una cosa...se nella tabella Immobili elimino idCliente e non ho la relazione con la tabella Clienti...
    come faccio a sapere di chi è l'immobile in questo momento?
    cioè adesso il Cliente Rossi mi da mandato a vendere l'immobile x...tu lo vedresti solo nella tabella MovimentiImmobili?...
    io credo sia più comodo un collegamento uno-molti tra cliente e immobili ...visto che uno può affidarmente diversi..

    ...quindi la query di cui tu parli dovrebbe interrogare la sola tabella MovimentiImmobili...
  • Re: Normalizzazione necessaria come fare

    ario75 ha scritto:


    ma non capisco ancora una cosa...se nella tabella Immobili elimino idCliente e non ho la relazione con la tabella Clienti...
    come faccio a sapere di chi è l'immobile in questo momento?
    Sfrutti la Data più recente associata al campo TipoMovimento = "Vendita"

    ario75 ha scritto:


    cioè adesso il Cliente Rossi mi da mandato a vendere l'immobile x...tu lo vedresti solo nella tabella MovimentiImmobili?...
    Esatto.

    ario75 ha scritto:


    io credo sia più comodo un collegamento uno-molti tra cliente e immobili ...visto che uno può affidarmente diversi..
    Io continuo a indicarti DataPiùRecente + TipoMovimento= "Vendita" + IDImmobile=X + IDCliente per sapere di chi è l'Immobile X.
    Avrei un'altra idea che permetterebbe a te di scremare più facilmente questa combinazione di campi. Potresti aggiungere in tabella MovimentiImmobili un campo di tipo Sì/No (che chiamerei Proprietà) dove indichi se si sta parlando della Proprietà di Rossi Mario all'Immobile X. In questo modo, una query con filtro su Proprietà=Sì ti screma automaticamente tutti i Proprietari associati al singolo Immobile così come li avresti visti in Immobili con il campo IDCliente come avevi progettato prima. Devi fare attenzione a ricordarti che, qualora l'immobile passa ad altro Proprietario, devi aver cura di togliere la spunta dal Cliente precedente e metterla a quello nuovo. Ti sto proponendo una soluzione "poco normalizzante", ma più facile e intuitiva.
  • Re: Normalizzazione necessaria come fare

    Grazie Osvaldo per i tuoi suggerimenti scomodi ... ma importantissimi...
    ...ho rivisto tutto il progetto ..adesso ho più o meno lo scenario che mi dicevi di attuare..
    ..ma non so esattamente come fare la "scrematura"..
    mi spiego :
    TAB_Clienti--1-------M--TAB_RegistrazioneImmobili--M---------1--TAB_Immobili
    TAB_Clienti--1-------M--TAB_AcquisizioneImmobili--M---------1--TAB_Immobili

    In TAB_RegistrazioneImmobili ho
    ID (PK)
    IdImmobile
    IdCliente
    DataRegistrazione
    TipoRegistrazione

    In TAB_AcquisizioneImmobili Ho la stessa configurazione ma con altri campi in più....
    Questo perchè spesso mi capita di dover registrare degli immobili molto prima di aver ricevuto l'incarico a vendere e
    mi serve distinguere le due cose anche a livello di maschere ... vorrei anche in seguito predisporre una funzione che
    quando arriva l'incarico cancella il record in TAB_Reg...e lo inserisce in TAB_Acqu... ma questa è un'altra storia...
    comunque una domandina te la voglio fare...
    1)..pensi che sia meglio unire le due tabelle in una o ho fatto bene di separarle?

    Adesso vorrei creare una maschera dove inserire il nome di un Cliente in una casella di testo e che mi restituisca
    (penserei ad una sottomaschera) gli immobili di quel cliente (se ce ne sono) che siano stati registrati o acquisiti...

    o meglio ...non posso fare altrimenti perchè come suggerito da Osvaldo ho lasciato la TAB_Immobili senza IdCliente ..
    ma non riesco ad impostare la query....
    2)Che tipo di query devo fare?...di unione...a campi incrociati..
    3)E come impostare i criteri?..
  • Re: Normalizzazione necessaria come fare

    Mi rispondo da solo alla domanda banale....Che tipo di query......di selezione...
    ma ho comunque due problemi :
    funziona solo con le tre tabelle
    Clienti
    Immobili
    Registrazione

    1)...se aggiungo la tabella Acquisizione mi da un errore del genere..."...contiene outer-join ambigui..."
    2)...come impostare il criterio che restituisce gli immobili registrati con l'id del cliente in combobox?

    ho provato mettendo nel criterio di idCliente il percorso della combo come da generatore ma nopn funziona...
    da precisare che la query l'ho impostata come sottomaschera in una maschera che prende i dati dalla tab_Clienti
    in cui ho inserito la combo...
  • Re: Normalizzazione necessaria come fare

    Scusatemi ....se continuo arispondermi da solo..
    ho cercato spunti da Northwind....ho visto che li la query sulle transazioni effettuate praticamente interroga un'altra query..
    ...forse dovrei fare anch'io così?
  • Re: Normalizzazione necessaria come fare

    ario75 ha scritto:


    Grazie Osvaldo per i tuoi suggerimenti scomodi ... ma importantissimi...
    ...ho rivisto tutto il progetto ..adesso ho più o meno lo scenario che mi dicevi di attuare..
    ..ma non so esattamente come fare la "scrematura"..
    mi spiego :
    TAB_Clienti--1-------M--TAB_RegistrazioneImmobili--M---------1--TAB_Immobili
    TAB_Clienti--1-------M--TAB_AcquisizioneImmobili--M---------1--TAB_Immobili

    In TAB_RegistrazioneImmobili ho
    ID (PK)
    IdImmobile
    IdCliente
    DataRegistrazione
    TipoRegistrazione

    In TAB_AcquisizioneImmobili Ho la stessa configurazione ma con altri campi in più....
    Questo perchè spesso mi capita di dover registrare degli immobili molto prima di aver ricevuto l'incarico a vendere e
    mi serve distinguere le due cose anche a livello di maschere ... vorrei anche in seguito predisporre una funzione che
    quando arriva l'incarico cancella il record in TAB_Reg...e lo inserisce in TAB_Acqu... ma questa è un'altra storia...
    comunque una domandina te la voglio fare...
    1)..pensi che sia meglio unire le due tabelle in una o ho fatto bene di separarle?

    Adesso vorrei creare una maschera dove inserire il nome di un Cliente in una casella di testo e che mi restituisca
    (penserei ad una sottomaschera) gli immobili di quel cliente (se ce ne sono) che siano stati registrati o acquisiti...

    o meglio ...non posso fare altrimenti perchè come suggerito da Osvaldo ho lasciato la TAB_Immobili senza IdCliente ..
    ma non riesco ad impostare la query....
    2)Che tipo di query devo fare?...di unione...a campi incrociati..
    3)E come impostare i criteri?..
    Le tabelle RegistrazioniImmobili e AcquisizioniImmobili devono essere una tabella sola. Io l'ho chiamata MovimentiImmobili. Va bene l'aggiunta del campo TipoMovimento (tu lo avevi chiamato TipoRegistrazione).
    Mi raccomando la denominazione ESPLICITA dei campi ID. Chiamalo IDMovimento.
  • Re: Normalizzazione necessaria come fare

    ..Osvaldo grazie per la tua risposta ma nel frattempo avevo fatto dei tentativi ed avevo risolto...
    facendo due query di selezione
    Immobili---Registrazioni
    Immobili---Acquisizioni
    ed una di unione tra le due..
    e visto che funziona vorrei proseguire così , infatti rimango del parere che le due tabelle
    mi conviene lasciarle separate . Infatti una sola tabella conterrebbe campi eterogenei..
    (motivo registrazione in caso di registrazione.....tipo di mandato in caso di acquisizione...)
    ...doppi record..
    (oggi registrazione....dopo un mese acquisizione...)
    Adesso però devo chiederti una cosa....per caso uno dei motivi per cui mi consigli
    la tabella unica riguarda problemi di integrità referenziale?..
    Infatti facendo dei test mi succede che se elimino un cliente in TAB_Clienti
    nel record correlato in TAB_Immobili rimane con un id orfano pur avendo fleggato
    aggiorna ed elimina campi correlati a catena..
  • Re: Normalizzazione necessaria come fare

    Siamo nella sezione "Progettazione database" e qui si parla di NORMALIZZAZIONE. Il mio suggerimento si incanala nella direzione corretta della normalizzazione. Se tu vuoi tenere 2 tabelle separate...poi ti scontrerai volente o nolente con quelle problematiche che esponi poi. La normalizzazione tende a evitare dispersione di dati...cosa che tu vuoi contraddire a tutti i costi.
    L'impostazione corretta è avere una tabella MovimentiImmobili con i campi necessari DataMovimento e TipoMovimento. È quest'ultimo campo che ti fa capire di quale TipoMovimento stai parlando e da esso puoi evincere/estrapolare solo Acquisizioni, solo...altre voci che solo tu sai...
  • Re: Normalizzazione necessaria come fare

    Grazie Osvaldo
    sei stato chiaro...mi sono spiegato male io.
    ecco il motivo della mia ostinazione :

    in "tipoMovimento" potrei avere :
    Registrazione (data-tipoRegistrazione-fonteRegistrazione)
    Acquisizione (data-tipoIncarico-inizioIncarico-fineIncarico-fotoSi/No-tabelleSi/No-documentiSi/No-Allegati)
    Richieste (data-immobileRichiesto-richiedente-telefono-fonteRichiesta-tipologiaRichiesta-cittàRichiesta-etc..)
    Trattative (dataInizio-dataFine-clienteAcquirente-clienteProprietario-immobile-offerta-etc..-allegati)
    Vendite (data-Notaio-Indirizzo-Costi-etc..-Provvigioni-etc..)

    come vedi ognuno di questi "tipi" è una tabella a se stante...e sono sicuro che in questo sarai d'accordo con me.

    come fare?...
    forse la Movimenti dovrebbe essere intermedia...ma come dovrei gestire gli id?
  • Re: Normalizzazione necessaria come fare

    Perchè ti vuoi complicare la vita con più tabelle che non servono? Anzi, visto che

    ario75 ha scritto:


    in "tipoMovimento" potrei avere :
    Registrazione (data-tipoRegistrazione-fonteRegistrazione)
    Acquisizione (data-tipoIncarico-inizioIncarico-fineIncarico-fotoSi/No-tabelleSi/No-documentiSi/No-Allegati)
    Richieste (data-immobileRichiesto-richiedente-telefono-fonteRichiesta-tipologiaRichiesta-cittàRichiesta-etc..)
    Trattative (dataInizio-dataFine-clienteAcquirente-clienteProprietario-immobile-offerta-etc..-allegati)
    Vendite (data-Notaio-Indirizzo-Costi-etc..-Provvigioni-etc..)
    anche le Relazioni possono essere inglobate dentro la tabella MovimentiImmobili. Quando si tratta di un semplice Appuntamento che non riguarda alcun Immobile, puoi prevedere un record "immobile fantasma" da inserire in casi come questo. Per esempio l'immobile con IDImmobile=500 avrà tutti i campi vuoti. Tutti gli altri campi si compilano comodamente a seguire. I campi di MovimentiImmobili devono essere i seguenti:
    IDMovimento (PK)
    DataMovimento
    IDImmobile (FK) (se si tratta di un certo IDImmobile lo inserisci, se il movimento non contempla alcun immobile ci metti il valore 500)
    TipoMovimento (qui ci metti una casella combinata con tutti i TipoMovimento possibili)
    Descrizione
    IDCliente (FK)

    Quello che non so/capisco è se un Movimento prevede molti Dettagli. Se sì, potresti prevedere una tabella figlia DettagliMovimenti dove elenchi molti dettagli relativi ad un singolo Movimento.
  • Re: Normalizzazione necessaria come fare

    Quello che non so/capisco è se un Movimento prevede molti Dettagli. Se sì, potresti prevedere una tabella figlia DettagliMovimenti dove elenchi molti dettagli relativi ad un singolo Movimento.
    Si ogni tipo di movimento prevede molti dettagli....sono quelli che ho messo tra parentesi..
    e come puoi vedere ogni tipo ha dei dettagli che non hanno nulla a che vedere con i dettagli degli altri.

    Quando si tratta di un semplice Appuntamento che non riguarda alcun Immobile, puoi prevedere un record "immobile fantasma" da inserire in casi come questo. Per esempio l'immobile con IDImmobile=500 avrà tutti i campi vuoti. Tutti gli altri campi si compilano comodamente a seguire.
    Gli appuntamenti li voglio gestire con tutt'altre tabelle perchè costituiscono un blocco a se stante...molto corposo..
    L'immobile fantasma non rientra nella logica che voglio al progetto e che praticamente a livello maschere sarebbe questa :

    1)Giorno 1 mi chiamano..."vorrei vendere l'immobile x , in via y , mtq z , richiesta q . " ---Registro l'immobile e il cliente...
    --------------------------------"verrò da lei a visitare l'immobile in data 123"--registro una relazione intrattenuta e fisso un app...

    a) in data 123 faccio il sopralluogo , la richiesta a mio parere è eccessiva , il cliente mi sfancula ----resto calmo e mantengo
    l'immobile registrato senza formattare il cliente....aBis)lavora di fantasia.
    b) in data 123 faccio il sopralluogo , a mio parere l'immobile vale più di quanto richiede il cliente , il quale apprezza la mia
    professionalità e decide di darmi incarico in esclusiva-----resto calmo lo stesso e fisso un app per ricevere documentazione , fare foto , mettere tabelle e quant'altro-------in questo caso apro la maschera immobili e l'immobile da
    registrato diventa acquisito .

    2)Giorno 2 un altro cliente interessato all'immobile avvia una trattativa-----------in questo caso apro la maschera e l'immobile oltre ad essere acquisito passa anche in trattativa.
    a) la trattativa va a buon fine e si avvia la vendita-------apro la maschera e l'immobile resta acquisito ma non è più in trattativa e risulta in vendita.
    ............a1)la vendita va a buon fine-------l'immobile non è più acquisito , non in vendita ma viene di nuovo registrato come venduto.
    ...........a2)la vendita non va a buon fine-----l'immobile non è in vendita , non in trattativa , torna acquisito.
    b)la trattativa non va a buon fine----l'immobile non è più in trattativa ma torna acquisito.

    vero è che potrei di volta in volta cambiare l'attributo "tipo movimento"
    ma come tenere traccia dello storico dei vari movimenti ?
    e poi tenendo tutti i dettagli in un'unica tabella dettagli...i record vuoti si moltiplicherebbero...
Devi accedere o registrarti per scrivere nel forum
22 risposte