Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    Un consiglio su tabella mysql prima che faccio danni :)

    Ragazzuoli, dunque... mi scuso in anticipo per la prolissità di questo post.
    nel progetto di php che sto portando avanti, volevo realizzare una gestione dei movimenti (costi/ricavi) ma non voglio usare cose già pronte, mi dà più soddisfazione scrivermi il codice da solo (così imparo pure qualcosa)...
    ovviamente prima di iniziare a scrivere codice, devo studiare bene come strutturare la tabella nel database in base alle informazioni che vorrei che contenesse (e poi di conseguenza poterle visualizzare senza fare query assurde)..
    io l'ho pensata più o meno come dovrei farla, ma 3 punti mi sono oscuri.. quindi sono ben accetti suggerimenti o critiche visto che siete più esperti di me.
    cercherò di spiegarmi a "pezzi" così magari rispondete x punti e non mi perdo

    PUNTO 1
    intanto macro-suddivisione nella tabella della tipologia di movimento in due tipi

    ENTRATE e USCITE (vabbè, questa era facile )

    primo quesito che mi pongo è: li metto nella stessa tabella o ne creo due diverse?
    lì per lì la prima cosa che mi è venuta in mente è un campo "tipologia", con appunto i due valori dentro, così da poter già limitare un'eventuale select a solo quel tipo di movimento, anzichè usare una tabella x le entrate e una x le uscite.
    suggerimenti? faccio bene? sbaglio?

    PUNTO 2
    ovviamente il "mittente/destinatario" del movimento
    e qui dubbio atroce (in funzione del punto successivo che vi spiego dopo):
    campo varchar libero o campo legato ad altre tabelle che già ho?
    cioè, se ad esempio so che pago il mutuo ogni mese, vale la pena che scrivo sempre "rata mutuo"? non è meglio se questo campo lo lego, per esempio, alla tabella dove ho le banche?
    (ma il ragionamento sarebbe lo stesso anche se fosse un fornitore)
    è anche vero però che posso avere 'n-mila' destinatari di pagamenti o incassi...
    suggerimenti in merito? voi che fareste?

    PUNTO 3
    data/ricorrenza del movimento
    e qui mi lego al punto precedente.. tornando all'esempio della rata del mutuo, sapendo appunto che la pago ogni mese e volendo fare una funzione di "ripetizione" della spesa, come mi conviene gestire questa cosa, se uso un campo varchar nel campo del "mittente/destinatario"?
    cioè, provo a spiegarlo meglio...
    Immaginate il form, dove io sto inserendo i miei bei dati..

    tipo movimento: da un menu a discesa scelgo se è un'entrata o un'uscita.
    e fin qui niente di complicato

    mittente/destinatario: eh... e qui come spiegavo sopra.. che ci metto?
    un menù dinamico che si pesca tutti i possibili clienti/fornitori (e quindi dovrei anche inventarmi qualcosa x farlo inserire se non è presente!) oppure un campo testo libero?
    perchè se ad esempio mi prendo i dati dalla tabella "fornitori", sceglierò tipo "BANCA XXX"...
    e arrivo al punto successivo:

    data movimento: inserisco la data e magari ho anche un altro menù a discesa che mi permette di ripetere la spesa nei mesi a venire, ovvero prima metto tipo che so
    "RATA MUTUO" che so che la pago ogni mese, stesso giorno, stesso importo.
    poi seleziono la ripetizione dall'altro menu a discesa tipo "1mese, 2mesi, 3mesi... 1anno" eccetera...
    ecco, come la gestisco sta cosa se non so come legarla al db in quanto il campo del destinatario non so come farlo? voi che consigliate?

    insomma.. se avete voglia di confrontarvi su questa cosa magari perchè ci siete già passati, mi farebbe piacere, almeno ci arricchiamo tutti con condivisione di conoscenza/esperienza

    Buonanotte!
    Fabrizio

  2. #2
    Ciao Fabrizio.


    La tua richiesta è abbastanza corposa.
    Cercherò di risponderti per punti.

    Innanzitutto una cosa deve esserti chiara: prima di pensare al db pensa a quello che vuoi fare e come.
    So che lo hai fatto (l'hai scritto), ma non credere che per una data interfaccia/funzione esista sempre una sola implementazione. Mi spiegherò meglio più avanti portando alcuni esempi ai tuoi punti oscuri.

    Punto 1: Entrate/Uscite.
    Più che la tipologia, la cosa che distingue davvero un'entrata da un'uscita è il segno del valore!
    Se ci pensi le entrate sono sempre positive, mentre le uscite sempre negative!
    Ti suggerirei di non utilizzare alcun campo "tipologia" ma di inserire i valori con segno, questo per 2 motivi:
    [list=1][*]Non perdi la funzione che richiedevi. Se hai scelto di usare MySql e ne sei sicuro, sappi che MySql (come tutti i DBMS) offre funzioni anche complesse da usare nelle query. Per esemprio, immaginando che la tua tabella "movimenti" abbia un campo "valore", per distinguere entrate da uscite basterebbe "SELECT valore, IF(valore>=0,'entrata','uscita') FROM movimenti". Se usi le VIEW poi una query del genere la puoi anche memorizzare in una vista appunto [*]Ottieni un'informazione in più in modo veloce: il SALDO. Essendo tutto nella stessa colonna valore (es. prima) una semplice "SELECT SUM(valore) AS saldo FROM movimenti" automaticamente di darebbe la somma algebrica dei valori, aggiungendo e sottraendo in funzione del segno. Pensa che questa query, con un where su altri campi, potrebbe darti il saldo dei movimenti di un dato periodo oppure il conto legato ad un cliente/fornitore[/list=1]

    Punto 2: Mittente/Destinatario.
    Qui la cosa è un po' complessa.
    Prima di tutto devi distinguere 2 cose: il destinatario/mittente del movimento non implica la causale dello stesso, cioè un uscita per la banca (purtroppo) non è detto sia sempre per il mutuo.
    Io direi di prevedere i campi "soggetto" (mittente/destinatario deriva dal segno del valore) e "causale" (descrizione del movimento).
    La causale è ovviamente varchar o text (se scrivi tanto) mentre il soggetto potrebbe essere di 2 tipi:
    [list=1][*]Riferimento (id) a tabella anagrafica esterna: è sicuramente la cosa più giusta in quanto crei una relazione tra le tabelle e separi per responsabilità. In anagrafica ci saranno dati (tel, email, ecc..) che non sono legati ai movimenti, ma di implementazione più complessa[*]Varchar dove inserire solo il nome del soggetto. Semplice da realizzare, ma scarsamente utile soprattutto se vorrai corredare di altre info il soggetto (e già lo fai)[/list=1]

    Tutte le 2 soluzioni, cmq, permetterebbero di creare nel form il menù a tendina di selezione del soggetto: la prima con una select sulla tabella anagrafica, la seconda con una select distinct(soggett) sulla tabella movimento.
    La cosa complessa però è che, a volte, dovrai gestire una doppia operazione in un solo form: l'inserimento del movimento e l'inserimento del soggetto (un nuovo fornitore, un nuovo cliente, ecc...)
    Per tale motivo ti suggerirei di utilizzare una select per lo storico + un campo testo per il nuovo soggetto e lato server gestire il caso in cui, se il dato "soggetto" è inviato dal campo testo (es campi "soggettotxt" e "soggettoselect") allora, prima di inserire il movimento, inserirà il soggetto nell'anagrafica.
    Questo flusso vale solo per il caso di tabella referenziata, in quanto con la soluzione distinct ti basterà inserire il nuovo movimento associato al nuovo soggetto e automanticamente troverai il nominativo nella select dei soggetti (mi sa che non sono stato molto chiaro qui)
    Cmq io sono per la tabella referenziata

    Punto 3: Data/Ricorrenza movimento
    Ti stai infilando in una cosa molto complessa!!!!
    Sicuramente il movimento deve avere una data, non ci piove, se non 2 addirittura: data dell'evento che genera il movimento e data della reale movimentazione di cassa (es: compro oggi un televisore (data evento) che pagherò tra 30 giorni (data uscita di cassa), oppure pagamento rata del finanziamento (data uscita di cassa) per l'acquisto dell'auto (data evento)), ma sto veramente esagerando!
    Lasciamo solo la data di movimentazione cassa.

    Per quanto riguarda la ricorrenza del movimento mi sa che devi un attimo ragionarci un po'.
    Dal punto di vista analitico la tabella dei movimenti è un'entità statica (i movimenti non hanno una vita ma quando sono generati muoiono anche) e consuntiva (tracci il movimento quando è avvenuto, o poco prima).
    Quello di cui parli tu è uno scadenziario, che ti aiuti a seguire i tuoi pagamenti.
    Fino a qui niente di strano, stiamo solo dicendo che il modulo ha un altro nome.
    Ancora non è il movimento che è ripetuto nel tempo, ma l'evento scatenante (rata mutuo) genera più movimenti nel tempo.
    Sarebbe semplice dire che ogni movimento è un evento, ma nella realtà le cose sono un po' più difficili.
    Un esempio veloce: immagina di essere riuscito a creare tanti movimenti in automatico ciclati sul tempo, ok? Ora pensa di dover cancellare un movimento, potrebbe capitare no? Ok, ne cancelli solo uno? Cancelli tutti quelli che seguono? Cancelli tutti i movimenti dello stesso evento? Ok, ma come distingui poi tutti i movimenti dello stesso evento se non gestisci l'evento in modo differente?

    Per semplicità stabiliamo che il primo movimento di una catena è anche l'evento.
    Un movimento singolo sarà una catena con un solo elemento!
    Io farei così:
    [list=1][*]La tabella ha un campo evento e per ogni movimento tale colonna assume il valore dell'id movimento padre della catena. In generale id ed evento saranno uguali se non nei casi di movimenti ciclici, dove i movimenti derivanti farebbero riferimento al movimento padre[*]Nel form di inserimento movimento aggiungere dei campi per gestirne la ciclicistà: data inizio ciclo (data primo movimento immagino), data fine ciclo, nuomero ricorrenze e tipo ricorrenza (per gestire da "ogni giorno" a "12 anni" - tipo ricorrenza potrebbe essere un menù a tendina con "giorno","mese","anno")[*]Quando invio i dati dal form, il modulo si accorge che se ho programmato un evento ciclico e, in quel caso, sfruttando un ciclo da data inizio a data fine a passi di ricorrenza, inserisce tanti eventi quanti ne risulteranno necessari, facendo attenzione di valorizzare la colonna "evento" con l'id del primo movimento della catena.[/list=1]

    Se tutto funziona dovresti ritrovarti automaticamente tutti i movimenti inseriti nel database.
    A quel punto potrai facilmente distinguere movimenti della stessa catena attraverso il valore della colonna evento e casi di operazioni con effetto a cascata (come la cancellazione o la modifica del valore della rata) potranno essere gestiti.

    Lo so, non credo di essere stato limpidissimo, ma è un po' difficile dare una soluzione ad un quesito un po' complesso solo attraverso un forum.

    Spero cmq di esserti stato utile


  3. #3
    grazie x la risposta, piena di spunti interessanti... ora vediamo che ne verrà fuori!
    grazie ancora,
    Fabri

  4. #4
    Posso chiederti qualche delucidazione?

    Originariamente inviato da eumene

    Punto 1: Entrate/Uscite.
    Più che la tipologia, la cosa che distingue davvero un'entrata da un'uscita è il segno del valore!
    Se ci pensi le entrate sono sempre positive, mentre le uscite sempre negative!
    Ti suggerirei di non utilizzare alcun campo "tipologia" ma di inserire i valori con segno, questo per 2 motivi:
    [list=1][*]Non perdi la funzione che richiedevi. Se hai scelto di usare MySql e ne sei sicuro, sappi che MySql (come tutti i DBMS) offre funzioni anche complesse da usare nelle query. Per esemprio, immaginando che la tua tabella "movimenti" abbia un campo "valore", per distinguere entrate da uscite basterebbe "SELECT valore, IF(valore>=0,'entrata','uscita') FROM movimenti". Se usi le VIEW poi una query del genere la puoi anche memorizzare in una vista appunto [*]Ottieni un'informazione in più in modo veloce: il SALDO. Essendo tutto nella stessa colonna valore (es. prima) una semplice "SELECT SUM(valore) AS saldo FROM movimenti" automaticamente di darebbe la somma algebrica dei valori, aggiungendo e sottraendo in funzione del segno. Pensa che questa query, con un where su altri campi, potrebbe darti il saldo dei movimenti di un dato periodo oppure il conto legato ad un cliente/fornitore[/list=1]
    questa è un'ottima cosa, non sapevo di poter ottenere il saldo così facilmente, quindi sicuro farò così.

    Punto 2: Mittente/Destinatario.
    Qui la cosa è un po' complessa.
    Prima di tutto devi distinguere 2 cose: il destinatario/mittente del movimento non implica la causale dello stesso, cioè un uscita per la banca (purtroppo) non è detto sia sempre per il mutuo.
    Io direi di prevedere i campi "soggetto" (mittente/destinatario deriva dal segno del valore) e "causale" (descrizione del movimento).
    La causale è ovviamente varchar o text (se scrivi tanto) mentre il soggetto potrebbe essere di 2 tipi:
    [list=1][*]Riferimento (id) a tabella anagrafica esterna: è sicuramente la cosa più giusta in quanto crei una relazione tra le tabelle e separi per responsabilità. In anagrafica ci saranno dati (tel, email, ecc..) che non sono legati ai movimenti, ma di implementazione più complessa[*]Varchar dove inserire solo il nome del soggetto. Semplice da realizzare, ma scarsamente utile soprattutto se vorrai corredare di altre info il soggetto (e già lo fai)[/list=1]

    Tutte le 2 soluzioni, cmq, permetterebbero di creare nel form il menù a tendina di selezione del soggetto: la prima con una select sulla tabella anagrafica, la seconda con una select distinct(soggett) sulla tabella movimento.
    La cosa complessa però è che, a volte, dovrai gestire una doppia operazione in un solo form: l'inserimento del movimento e l'inserimento del soggetto (un nuovo fornitore, un nuovo cliente, ecc...)
    Per tale motivo ti suggerirei di utilizzare una select per lo storico + un campo testo per il nuovo soggetto e lato server gestire il caso in cui, se il dato "soggetto" è inviato dal campo testo (es campi "soggettotxt" e "soggettoselect") allora, prima di inserire il movimento, inserirà il soggetto nell'anagrafica.
    Questo flusso vale solo per il caso di tabella referenziata, in quanto con la soluzione distinct ti basterà inserire il nuovo movimento associato al nuovo soggetto e automanticamente troverai il nominativo nella select dei soggetti (mi sa che non sono stato molto chiaro qui)
    Cmq io sono per la tabella referenziata
    Dunque, considera che io una cosa simile la faccio già coi clienti nella parte di inserimento dei preventivi, ovvero:
    Menu a discesa con elenco clienti usando l'id_cli, se poi non è presente, link al form di inserimento anagrafica.
    Non è sicuramente ottimale perchè faccio fare il doppio passaggio in due pagine diverse (difatti pensavo di studiare un sistema che mi permettesse di aprire in un pop-up la lista clienti, magari divisa x pagine per poi una volta selezionato in questo pop-up, mi riportasse il valore alla pagina di prima), però questo mi consente di avere le anagrafiche complete di tutti i dati ed evitare di avere inserimenti "sporchi", tipo solo il nome ma niente numeri di tel, o p.iva eccetera.
    Ecco, la stessa cosa vorrei farla per la gestione dei mittenti/destinatari, quindi credo che debba solamente ottimizzarne la gestione, che al momento è molto "semplicistica", con quell'ipotesi di pop-up che ti dicevo prima.

    Punto 3: Data/Ricorrenza movimento
    Ti stai infilando in una cosa molto complessa!!!!
    e questa è l'unica cosa che sapevo di sicuro

    Sicuramente il movimento deve avere una data, non ci piove, se non 2 addirittura: data dell'evento che genera il movimento e data della reale movimentazione di cassa (es: compro oggi un televisore (data evento) che pagherò tra 30 giorni (data uscita di cassa), oppure pagamento rata del finanziamento (data uscita di cassa) per l'acquisto dell'auto (data evento)), ma sto veramente esagerando!
    Lasciamo solo la data di movimentazione cassa.
    Questo l'avevo pensato, difatti volevo creare due campi data, di cui uno nascosto e con l'opzione "on update current timestamp", proprio per distinguere la data di inserimento (cioè quando premo il bottone inserisci prende la data e l'ora corrente) dalla data del movimento.
    Come la vedi?

    Per quanto riguarda la ricorrenza del movimento mi sa che devi un attimo ragionarci un po'.
    Dal punto di vista analitico la tabella dei movimenti è un'entità statica (i movimenti non hanno una vita ma quando sono generati muoiono anche) e consuntiva (tracci il movimento quando è avvenuto, o poco prima).
    Quello di cui parli tu è uno scadenziario, che ti aiuti a seguire i tuoi pagamenti.
    Fino a qui niente di strano, stiamo solo dicendo che il modulo ha un altro nome.
    Ancora non è il movimento che è ripetuto nel tempo, ma l'evento scatenante (rata mutuo) genera più movimenti nel tempo.
    Sarebbe semplice dire che ogni movimento è un evento, ma nella realtà le cose sono un po' più difficili.
    Un esempio veloce: immagina di essere riuscito a creare tanti movimenti in automatico ciclati sul tempo, ok? Ora pensa di dover cancellare un movimento, potrebbe capitare no? Ok, ne cancelli solo uno? Cancelli tutti quelli che seguono? Cancelli tutti i movimenti dello stesso evento? Ok, ma come distingui poi tutti i movimenti dello stesso evento se non gestisci l'evento in modo differente?

    Per semplicità stabiliamo che il primo movimento di una catena è anche l'evento.
    Un movimento singolo sarà una catena con un solo elemento!
    Io farei così:
    [list=1][*]La tabella ha un campo evento e per ogni movimento tale colonna assume il valore dell'id movimento padre della catena. In generale id ed evento saranno uguali se non nei casi di movimenti ciclici, dove i movimenti derivanti farebbero riferimento al movimento padre[*]Nel form di inserimento movimento aggiungere dei campi per gestirne la ciclicistà: data inizio ciclo (data primo movimento immagino), data fine ciclo, nuomero ricorrenze e tipo ricorrenza (per gestire da "ogni giorno" a "12 anni" - tipo ricorrenza potrebbe essere un menù a tendina con "giorno","mese","anno")[*]Quando invio i dati dal form, il modulo si accorge che se ho programmato un evento ciclico e, in quel caso, sfruttando un ciclo da data inizio a data fine a passi di ricorrenza, inserisce tanti eventi quanti ne risulteranno necessari, facendo attenzione di valorizzare la colonna "evento" con l'id del primo movimento della catena.[/list=1]

    Se tutto funziona dovresti ritrovarti automaticamente tutti i movimenti inseriti nel database.
    A quel punto potrai facilmente distinguere movimenti della stessa catena attraverso il valore della colonna evento e casi di operazioni con effetto a cascata (come la cancellazione o la modifica del valore della rata) potranno essere gestiti.
    Dunque, se ho capito cosa vuoi dire...anche qui è già quello che faccio con gli articoli dei preventivi, ovvero... ad un id_preventivo, c'è associato un id_dettaglio_preventivo, proprio perchè posso avere N articoli presenti.
    difatti l'idea che avevo era di riportare questa cosa anche nelle scadenze, per avere appunto un evento "padre" e le varie ricorrenze gestirle come "figli" di quell'evento.
    E' questo che intendevi?

    Lo so, non credo di essere stato limpidissimo, ma è un po' difficile dare una soluzione ad un quesito un po' complesso solo attraverso un forum.

    Spero cmq di esserti stato utile

    Meglio di così non potevi fare, grazie ancora

    Fabri

  5. #5
    Posso chiederti qualche delucidazione?
    Certo!

    Ecco, la stessa cosa vorrei farla per la gestione dei mittenti/destinatari, quindi credo che debba solamente ottimizzarne la gestione, che al momento è molto "semplicistica", con quell'ipotesi di pop-up che ti dicevo prima.
    Credo possa essere una buon punto d'incontro.

    Questo l'avevo pensato, difatti volevo creare due campi data, di cui uno nascosto e con l'opzione "on update current timestamp", proprio per distinguere la data di inserimento (cioè quando premo il bottone inserisci prende la data e l'ora corrente) dalla data del movimento.
    Come la vedi?
    La data in cui esegui l'operazione di registrazione (campo data nascosto on update) è una buona cosa da utilizzare come log delle operazioni eseguite da un utente.
    Io mi riferifo di più ad un concetto di maturazione del costo.
    Pensa ad una fattura di fornitura pagabile a 30gg. Il costo sorge appena ti è consegnata la merce e la fattura (che infatti sarà registrata con la data di emissione) mentre l'uscita di cassa avverrà dopo 30gg! Come pensi di registrare questo caso?
    Da questa analisi ho evidenziato la necessità di inserire 2 date nel form da valorizzare e non da settare automaticamente alla data corrente

    Dunque, se ho capito cosa vuoi dire...anche qui è già quello che faccio con gli articoli dei preventivi, ovvero... ad un id_preventivo, c'è associato un id_dettaglio_preventivo, proprio perchè posso avere N articoli presenti.
    difatti l'idea che avevo era di riportare questa cosa anche nelle scadenze, per avere appunto un evento "padre" e le varie ricorrenze gestirle come "figli" di quell'evento.
    E' questo che intendevi?
    Esatto, è proprio questo, ma per evitare di creare un'altra anagrafica per gli eventi ho suggerito di semplificare il tutto con una referenza interna alla stessa tabella movimenti.
    Avrai così il concetto di movimento_padre che è cmq un movimento!

    Meglio di così non potevi fare, grazie ancora
    Grazie! Grazie!
    Si fa quel che si può

  6. #6
    Originariamente inviato da eumene

    La data in cui esegui l'operazione di registrazione (campo data nascosto on update) è una buona cosa da utilizzare come log delle operazioni eseguite da un utente.
    Io mi riferifo di più ad un concetto di maturazione del costo.
    Pensa ad una fattura di fornitura pagabile a 30gg. Il costo sorge appena ti è consegnata la merce e la fattura (che infatti sarà registrata con la data di emissione) mentre l'uscita di cassa avverrà dopo 30gg! Come pensi di registrare questo caso?
    Da questa analisi ho evidenziato la necessità di inserire 2 date nel form da valorizzare e non da settare automaticamente alla data corrente
    dunque, ho parlato direttamente col contabile (sarà lui lo sventurato che userà questa parte della webapp )
    ed in effetti è come avevi supposto tu...
    quindi, oltre al campo data nascosto (che lo tengo cmq x log operazioni appunto) dovrò appunto avere 2 campi data: quello a data fattura e quello di scadenza pagamento.
    Uhm... ok, ora vediamo che esce fuori.. grazie ancora x la disponibilità!

    Fabrizio

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.