View Full Version : [progettazione] applicazione desktop+db
Salve gente, ho una domanda da porvi su una questione puramente progettuale.
Mettiamo che dovete fare una applicazione che permette di gestire articoli e ordini di articoli; ipotizzando che create due tabelle, articolo e ordine, dove ordine contiene l'id dell'articolo, come vi comportate in relazione all'eventualità che un articolo può venire rimosso?
Non permettete che un articolo venga rimosso
Invece di rimuovere l'articolo cambiate un flag (ATTIVO) nella tabella
Avverto l'utente di cosa sta per fare, me ne fotto, e cancello sia l''articolo che tutti gli ordini ad esso collegati
Invece di creare un vincolo tra le tabelle inserendo un id_articolo, inserisco i dati dell'articolo come testo(nome, descrizione ecc ecc)
Altro...
Credo sia una questione ricorrente, ho sempre usato la 2a ipotesi, ma alla lunga le cose si complicano perchè quando si scrivono le query bisogna sempre tenere in considerazione cosa è attivo e cosa no.
Ora l'esempio che ho fatto è banale, ma quando le entità che hanno il flag "stato" sono molte diventa facilissimo perdersi qualche stato per strada.
Mi interessa la vostra opinione al riguardo.
kevinpirola
02-10-2010, 13:10
Tralasciando vari parametri io farei una cosa così:
quando io vado a cancellare un articolo faccio in modo intanto da avere una schermatina con "sei sicuro che vuoi cancellare blabla" sotto questo, prima dei pulsanti si o no metterei una sezione con scritto: "Attenzione tale articolo è presente negli ordini x, y, z" leggendo dalla tabella degli ordini 'where articolo=id" x, y e z sarebbero dei link che mi aprono una piccola finestrella in javascript con i dati dell'ordine, nome cognome indirizzo dell'ordiinante, se è già stato ricevuto il pagamento, gli altri articoli in ordine ecc ecc.
Per ogni ordine poi metterei dei pulsanti del tipo "cancella ordine - operazione che invierà una mail al cliente di avvenuta cancellazione" nel caso non sia stato ricevuto il pagamento.
Invia email standardizzate "invia email prodotto non più disponibile" che manda l'email al cliente e mi inserisce l'ordine e tutte le risposte in una tabella a parte del database dove posso gestire singolarmente ogni caso.
ecc ecc
potrei andare avanti fino a domani... dipende quanta voglia di perderci tempo hai...sicuramente però non puoi cancellare e basta, non sarebbe rispettoso per il cliente che ha fatto l'ordine e che magari nell'ordine non ha solo quell'articolo, magari ha già pagato blablabla.....
/<.
Tralasciando vari parametri io farei una cosa così:
quando io vado a cancellare un articolo faccio in modo intanto da avere una schermatina con "sei sicuro che vuoi cancellare blabla" sotto questo, prima dei pulsanti si o no metterei una sezione con scritto: "Attenzione tale articolo è presente negli ordini x, y, z" leggendo dalla tabella degli ordini 'where articolo=id" x, y e z sarebbero dei link che mi aprono una piccola finestrella in javascript con i dati dell'ordine, nome cognome indirizzo dell'ordiinante, se è già stato ricevuto il pagamento, gli altri articoli in ordine ecc ecc.
Per ogni ordine poi metterei dei pulsanti del tipo "cancella ordine - operazione che invierà una mail al cliente di avvenuta cancellazione" nel caso non sia stato ricevuto il pagamento.
Invia email standardizzate "invia email prodotto non più disponibile" che manda l'email al cliente e mi inserisce l'ordine e tutte le risposte in una tabella a parte del database dove posso gestire singolarmente ogni caso.
ecc ecc
potrei andare avanti fino a domani... dipende quanta voglia di perderci tempo hai...sicuramente però non puoi cancellare e basta, non sarebbe rispettoso per il cliente che ha fatto l'ordine e che magari nell'ordine non ha solo quell'articolo, magari ha già pagato blablabla.....
/<.
Ti ringrazio per l'interessamento, quello che hai detto è giustissimo, ma forse ho scelto un esempio un pò sbagliato per quello che voglio sapere.
Mettiamo invece che si hanno ACQUISTO e RICEVUTA.
ACQUISTO contiene l'id dell'articolo acquistato, la quantità ordinata e l'id della ricevuta alla quale è associato, mentre RICEVUTA contiene il cliente che ha effettuato l'acquisto e la data.
Un articolo può capitare di non trattarlo più quindi potrebbe essere necessario eliminarlo, di conseguenza però non si avrebbero più informazioni sugli ACQUISTI fatti di quell'articolo.
Stessa cosa per le RICEVUTE, se voglio eliminare un cliente dal db, dovrei eliminare anche tutte le sue ricevute...
In un programma usato per scopi commerciali non puoi eliminare una referenza tout-court (a meno che non siano trascorsi 10 anni dall'ultima volta che è stata contabilizzata).
Se non vuoi usare un contrassegno che divida i prodotti attivi da quelli non più attivi, usa tabelle diverse.
In un programma usato per scopi commerciali non puoi eliminare una referenza tout-court (a meno che non siano trascorsi 10 anni dall'ultima volta che è stata contabilizzata).
Se non vuoi usare un contrassegno che divida i prodotti attivi da quelli non più attivi, usa tabelle diverse.
Quindi ad esempio metter su un trigger che quando si cancella sposta tutto in una tabella "storico" ?
Sembra la soluzione migliore, così ad occhio pure facile da mantenere.
In un programma usato per scopi commerciali non puoi eliminare una referenza tout-court (a meno che non siano trascorsi 10 anni dall'ultima volta che è stata contabilizzata).
Se non vuoi usare un contrassegno che divida i prodotti attivi da quelli non più attivi, usa tabelle diverse.
Esatto.
E' un problema che mi ero posto pure io.
Gli articoli possono essere toccati, gli ordini no.
Ho pensato a tre soluzioni anche io:
a) NON do la possibilità di cancellare (come hai pensato tu).
b) creo un FLAG su attivo/non attivo sul prodotto (cosa più semplice).
c) creo una seconda tabella che nasconda gli articoli 'rimossi', in modo che gli ordini funzionino ancora :)
Quindi ad esempio metter su un trigger che quando si cancella sposta tutto in una tabella "storico" ?
Sembra la soluzione migliore, così ad occhio pure facile da mantenere.
Si, secondo me è la via migliore.
In quanto il tuo 'cliente' può comunque cambiare il codice di un prodotto (che ne so, viene aggiornato e tengono lo stesso codice, non accade quasi mai, ma... lo sappiamo tutti... c'è sempre il fenomeno che lo fà la prima volta) quindi meglio arginare il problema; crei un trigger, seconda tabella, prodotti non piu in vendita/cancellati e gli ordini pescano da entrambi le tabelle :P
(se no ti fai una tabella copia-prodotto) dove metti dentro tutti e solo i prodotti venduti ;) cosi leggi solo da quella tabella :)
Esatto.
E' un problema che mi ero posto pure io.
Gli articoli possono essere toccati, gli ordini no.
Ho pensato a tre soluzioni anche io:
a) NON do la possibilità di cancellare (come hai pensato tu).
b) creo un FLAG su attivo/non attivo sul prodotto (cosa più semplice).
c) creo una seconda tabella che nasconda gli articoli 'rimossi', in modo che gli ordini funzionino ancora :)
Ok, vada per la solzuione della seconda tabella ( o magari altro db con medesime tabelle) vedo che ci salta fuori.
Mantenere un flag per lo stato diventa troppo oneroso ed error-prone secondo me.
(se no ti fai una tabella copia-prodotto) dove metti dentro tutti e solo i prodotti venduti ;) cosi leggi solo da quella tabella :)
Però, anche questa non è mica male, è da valutare, una tabella-copia di tutte le entità che potrebbero essere cancellate ma devono rimanere.
kevinpirola
02-10-2010, 13:45
io sono d'accordo anche con la flag però. è molto molto difficile fare errori, o è attivo o non è attivo. quindi o si vede o non si vede, però tu comunque leggendo le ricevute hai il riferimento anche se la flag è negativa. mi spiego
sei nella pagina di visualizzazione dei prodotti quella fa una chiamata del tipo
select * from 'prodotti' where disponibile='yes'
mentre quando vai a vedere un ordine fai il richiamo di
select * from 'prodotti' where id = 'numero'
così ti seleziona quel prodotto, abbia esso flag attiva o no.
io sono d'accordo anche con la flag però. è molto molto difficile fare errori, o è attivo o non è attivo. quindi o si vede o non si vede, però tu comunque leggendo le ricevute hai il riferimento anche se la flag è negativa. mi spiego
sei nella pagina di visualizzazione dei prodotti quella fa una chiamata del tipo
select * from 'prodotti' where disponibile='yes'
mentre quando vai a vedere un ordine fai il richiamo di
select * from 'prodotti' where id = 'numero'
così ti seleziona quel prodotto, abbia esso flag attiva o no.
Si ma quando non sono solo entità "articoli" ad avere il flag per lo stato, e quando le query diventano complesse, join di qual join di llà, sub-query, stare dietro ai vari flag delle varie entità interessate è un casino.
Te lo dico per esperienza visto che ho sempre utilizzato quel modo fino ad ora, e va benissimo per cose semplici ma poi diventa deleterio.
Però, anche questa non è mica male, è da valutare, una tabella-copia di tutte le entità che potrebbero essere cancellate ma devono rimanere.
kevinpirola ha ragione: il doppio stato/controllo è essenziale, insieme sono una coppia vincente; ho sviluppato diversi gestionali + ecommerce ed utilizzo anche io la tecnica dello 'stato' attivo e non (campo binary).
La seconda tabella ci infilo TUTTI i prodotti acquistati dall'utente (che andranno a comporre ordine, fattura e storico ordini); cosi non stai a toccare la tabella principale quando vai a prendere ordini e fatture.
L'ideale sarebbero due DB... ma sappiamo che non è il massimo in termini di 'prestazioni'.
Si ma quando non sono solo entità "articoli" ad avere il flag per lo stato, e quando le query diventano complesse, join di qual join di llà, sub-query, stare dietro ai vari flag delle varie entità interessate è un casino.
Te lo dico per esperienza visto che ho sempre utilizzato quel modo fino ad ora, e va benissimo per cose semplici ma poi diventa deleterio.
In una App ci deve essere sempre qualcosa di deleterio no? :D
In una App ci deve essere sempre qualcosa di deleterio no? :D
heheh si hai ragione, ma in quella che sto facendo c'è già troppo di deleterio non vorrei poi mica esagerare :p
heheh si hai ragione, ma in quella che sto facendo c'è già troppo di deleterio non vorrei poi mica esagerare :p
Java? (Non mi ricordo mai se tu sei spasimante di questo linguaggio ;)).
Comunque vai di second table con trigger, è la soluzione che sto adottando pure io per la nuova piattaforma ecomm che sto scrivendo nel tempo libero :P
Java? (Non mi ricordo mai se tu sei spasimante di questo linguaggio ;)).
Comunque vai di second table con trigger, è la soluzione che sto adottando pure io per la nuova piattaforma ecomm che sto scrivendo nel tempo libero :P
Si esatto! Sto usando java + hibernate e sto facendo una app desktop che tra le varie cose deve gestire anche un magazzino e la relativa vendita/noleggio di articoli.
E' la prima volta che utilizzo hibernate e già quello è stato abbastanza deleterio :asd:
Anche se devo ammettere che ora che ci sto prendendo la mano utilizzare le JPA è tutto un altro mondo, addio query :D
Si esatto! Sto usando java + hibernate e sto facendo una app desktop che tra le varie cose deve gestire anche un magazzino e la relativa vendita/noleggio di articoli.
E' la prima volta che utilizzo hibernate e già quello è stato abbastanza deleterio :asd:
Anche se devo ammettere che ora che ci sto prendendo la mano utilizzare le JPA è tutto un altro mondo, addio query :D
Beh... direi di si. Le JPA non le ho MAI usate ma so cosa sono; ho avuto modo di usare qualcosa di simile in PHP (CodeIgniter) e Python (DJango); diciamo che il mondo cambia e non poco anche se io, purista come sono, amo scriverle a manina... (su MySQL); ovvio su altri RDBMS uso le Stored e ... ci siamo capiti ;)
Bleah Java :P (ripudio personale ovviamente).
Fammi sapere come ti trovi con la seconda tabella, può essere interessante farci un articolo per il blog.
RaouL_BennetH
02-10-2010, 21:21
Si esatto! Sto usando java + hibernate e sto facendo una app desktop che tra le varie cose deve gestire anche un magazzino e la relativa vendita/noleggio di articoli.
E' la prima volta che utilizzo hibernate e già quello è stato abbastanza deleterio :asd:
Anche se devo ammettere che ora che ci sto prendendo la mano utilizzare le JPA è tutto un altro mondo, addio query :D
E' la stessa cosa che è capitata a me su due passaggi:
1) dalle varie query a .net + nhibernate
2) .net Entity Framework (addio xml :Prrr: )
Ad ogni modo, per tornare alla tua domanda spero di poterti dare uno spunto anche io:
In azienda facciamo molte operazioni verso sistemi IBM ISeries, sia verso DB400 che DB2.
In tutti e due i casi NON esiste proprio la cancellazione "fisica" di un record anche in assenza di relazioni. Ci sono tabelle separate che conservano lo storico di qualsiasi cosa (nel caso più semplice). Nel più complesso invece, vengono fatte vere e proprie repliche dei dati.
In tutti e due i casi NON esiste proprio la cancellazione "fisica" di un record anche in assenza di relazioni. Ci sono tabelle separate che conservano lo storico di qualsiasi cosa (nel caso più semplice). Nel più complesso invece, vengono fatte vere e proprie repliche dei dati.
Pensa che dove lavoravo qualche tempo fa il 'DELETE' era BANDITO.
:D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.