Buongiorno.
Sicuramente è una violazione della normalizzazione.
Però in questo caso secondo me è una delle rare eccezioni, dove violare la normalizzazione evita inutili complicazioni nella scrittura del codice e nella gestione delle query e dei report e dove è necessaria per andare a coprire le eccezioni.
Infatti, immaginiamo il caso di un azienda commerciale che venda migliaia di prodotti con centinaia di clienti ai quali deve inviare dei preventivi.
Naturalmente la prima cosa da fare è avere una tabella con i relativi prodotti e prezzi.
Ma in questo caso, ben sappiamo che i prezzi del singolo prodotto possono variare sia dalle zone di vendita, che per tipologia di cliente.
Quindi si andrà a creare una tabella con i prodotti ed un'altra tabella dove verranno archiviati i prezzi raggruppati per listini di vendita.
Quindi ad ogni prodotto, si avranno listini diversi, magari divisi per anno.
E fin qui tutto nella norma.
In fase di elaborazione del preventivo, basterà scegliere il relativo listino di vendita.
Il problema sorge quando, bisogna fare dei preventivi una tantum, personalizzati per il singolo prodotto o cliente.
In questo caso, per avere anche uno storico , la via più logica sarebbe creare un nuovo listino per il singolo preventivo, ma sicuramente non è la più performante, sia per l'operatore che deve creare un nuovo listino, andando a modificare il prezzo di un solo prodotto e per il singolo cliente, sia per la quantità di listini da creare se bisogna applicare modifiche a molti clienti.
Inoltre se un listino già presente dovesse subire delle modifiche ai prezzi, ma si sono fatti già dei preventivi approvati, in fase di esecuzione dell'ordine, si avrebbero i nuovi prezzi e non quelli vecchi con il quale è stato perfezionato il contratto di vendita.
Questo per dire che, secondo me, anche se viola la normalizzazione e si tratta di avere un valore doppio, la via più veloce, pratica e gestibile è quella di archiviare anche il prezzo nella tabella dei preventivi, scelto da un determinato listino, ma modificabile in fase di immissione.
Questo permette di avere uno storico, un preventivo personalizzato e che rimarrà invariato, anche in caso di modifiche ai prezzi del listino di origine, senza il bisogno di creare decine di listini personalizzati per ogni singolo cliente o singolo prodotto che potrebbe generare confusione, il classico latte alle ginocchia per l'operatore finale e che sicuramente andrebbe a cercare delle scorciatoie “per fare prima” che inevitabilmente generebbe degli errori a cascata.
Perchè si sa ogni volta che si dice “facciamo così che si fa prima” è il momento che si generano errori che poi generano altri errori, facendo perdere molto più tempo se si fosse seguita la via ufficiale, anche se macchinosa.
Inoltre, anche a livello tecnico, si eviterebbero query lunghe e piene di join, visto che verrebbe eseguita solo una query sulla tabella preventivi ed eventualmente solo sulla tabella dei prodotti per recuperare il nome e descrizione del prodotto, facilitando non di poco anche le somme.
Quindi è meglio attenersi alle regole, per poi gestire in modo più macchinoso le eccezioni, oppure violare le regole?