Database
 sql >> Database >  >> RDS >> Database

Modellazione di un database per la registrazione delle vendite. Parte 1

Archiviare correttamente i dati di vendita e combinarli successivamente può portare alla creazione di un modello predittivo con un alto tasso di accuratezza. In questo e nei prossimi articoli analizzeremo la progettazione di un database per la registrazione delle vendite.

Tutti vivono vendendo qualcosa.

Robert Louis Stevenson

Nel mondo di oggi, vendita di prodotti è onnipresente. E i venditori che hanno accesso a strumenti solidi che sfruttano i dati storici per analizzare le tendenze e consentire a un'azienda di adattare le strategie di business di conseguenza hanno un vantaggio rispetto ai loro concorrenti. Ci sono molti parametri che possono influenzare i risultati dell'azienda:l'attuale situazione economica globale, l'ubicazione dei clienti, l'età, lo stato materiale e civile e la cronologia dei contatti precedenti o delle vendite ai clienti.

Inizieremo con un esempio molto semplice:un modello di database per le vendite in un caffetteria . Negli articoli successivi estenderemo il modello alla vendita di prodotti in altri rami.

Modello di vendita

In questo articolo analizzeremo solo una parte del modello che contiene dati di vendita con altre parti mancanti.

Abbiamo ancora collegamenti a tabelle mancanti e considereremo il modello come una scatola nera presupponendo che quanto segue sia corretto per la tabella sale :

  • user_has_role_id fare riferimento all'id in user_has_role (come presentato nel mio precedente articolo nella sezione "Componente temporale aggiunto") e memorizza le informazioni sull'utente che ha creato il record di vendita



Questo modello ci consente di creare record di vendita con più articoli. Ogni articolo è correlato a un prodotto del nostro catalogo. Il momento in cui generiamo una vendita può essere diverso dal momento in cui la vendita viene pagata. Ad esempio, per una tazza di caffè questi momenti differiranno nel giro di pochi minuti o ore. Se il nostro negozio vendeva dispositivi di telecomunicazione, la differenza può essere di pochi giorni, forse anche di mesi.

Tabelle

Diamo un'occhiata alla definizione della tabella e spieghiamo lo scopo e l'utilizzo degli attributi.

La tabella più importante nel modello è product . Viene utilizzato per memorizzare i dettagli sui prodotti che offriremo ai nostri clienti. I prodotti vengono solitamente consegnati a un cliente e pagati una volta, di solito al momento della consegna. Inoltre, i prodotti sono generalmente oggetti fisici come automobili, telefoni, pacchetti di zucchero o tazze di caffè.

Parleremo della vendita di cose non fisiche (servizi) nei prossimi articoli.

Attributi nel product tabella sono:

  • name – il nome del prodotto nel sistema
  • price_per_unit – costo del prodotto per unità (es. 1 tazza di caffè costa 1,8 Euro, 1 macchina costa 17.500 Euro, 1 kg di riso costa 2 Euro)
  • basic_unit – unità base quando vendiamo un prodotto (es. pezzo, kg, litro)
  • tax_percentage – percentuale del prezzo_per_unità da addebitare come imposta. Dobbiamo presumere che la percentuale di imposta non sarebbe la stessa per tutti i prodotti
  • limited – questo campo è impostato su Vero se abbiamo una quantità limitata in magazzino e su Falso in caso contrario (ad esempio, possiamo ordinare qualsiasi quantità di cui abbiamo bisogno per il nostro negozio da un distributore)
  • in_stock – if limited=True questo attributo mostra quanti ne abbiamo a disposizione per vendere
  • active_for_sale – se questo attributo è False allora non stiamo offrendo quel prodotto in vendita, altrimenti possiamo offrirlo ai clienti

Possiamo ottenere un elenco di prodotti che possiamo offrire ai clienti con la seguente query:

SELECT product.id, product.price_per_unit, 
       product.basic_unit, product.limited, product.in_stock
FROM product
WHERE product.active_for_sale = True
AND (product.limited = False OR
      (product.limited = True and product.in_stock > 0))

La tabella sale_status è solo un semplice dizionario che contiene tutti gli stati che una vendita può avere nel sistema (es. "scontrino emesso", "scontrino pagato").

La tabella sale è la seconda tabella più importante in questo modello. Finora, questa tabella non ha alcun collegamento con i clienti a cui abbiamo venduto i prodotti perché, nel nostro esempio di caffetteria, non abbiamo bisogno di conoscere tali informazioni. Nella parte 2, il modello sarà esteso a tali casi.

Gli attributi nella tabella e il loro significato sono:

  • time_created – ora in cui è stato generato un record di vendita nel sistema (ad es. ora automatica in cui il record è stato creato quando abbiamo generato una vendita di caffè nella nostra caffetteria o un tempo aggiunto manualmente se lo desideriamo)
  • time_paid – generalmente possiamo aspettarci che alcune vendite vengano pagate entro pochi giorni o addirittura un mese dopo la creazione (ad esempio, se consegniamo software e creiamo una ricevuta possiamo aspettare fino a 90 giorni per essere pagati in alcuni paesi, se tutto va bene la legge)
  • sale_amount – importo originario destinato ad essere addebitato al cliente
  • sale_amount_paid – importo effettivamente pagato dal cliente. Può essere nullo perché al momento della creazione di una ricevuta non sempre abbiamo queste informazioni
  • tax_amount – somma di tutti gli importi delle tasse per gli articoli su quella ricevuta
  • sale_status_id – riferimento a sale_status tabella
  • user_has_role_id – riferimento all'utente e al suo ruolo nel momento in cui ha inserito la ricevuta nel sistema

Possiamo ottenere l'importo emesso e pagato (in base a time_created) entro un periodo di tempo con una query come questa:

SELECT SUM(sale.sale_amount) AS amount_issued,
       SUM(sale.sale_amount_paid) AS amount_paid 
FROM sale
WHERE sale.time_created >= @start_time 
AND sale.time_created <= @end_time;

Per ottenere l'importo esatto pagato entro un periodo di tempo dobbiamo utilizzare una query come questa:

SELECT SUM(sale.sale_amount_paid) AS amount_paid 
FROM sale
WHERE sale.time_paid >= @start_time 
AND sale.time_paid <= @end_time;

La query seguente calcolerà l'importo emesso e pagato entro un periodo di tempo con la data di emissione e la data di pagamento verificate separatamente:

SELECT 
SUM(CASE WHEN sale.time_created >= @start_time 
    AND sale.time_created <= @end_time 
    THEN sale.sale_amount END) AS amount_issued,
SUM(CASE WHEN sale.time_paid >= @start_time 
    AND sale.time_paid <= @end_time 
    THEN sale.sale_amount_paid END) AS amount_paid 
FROM sale

In tutti gli esempi @start_time e @end_time sono variabili contenenti l'ora di inizio e l'ora di fine del periodo per il quale vogliamo controllare la SOMMA emessa e pagata.

La tabella sale_item collega prodotti e vendite. Ovviamente, dobbiamo presumere che avremo più articoli su una ricevuta, quindi abbiamo bisogno che questa tabella abbia una relazione molti-a-molti.

Gli attributi e il loro significato sono:

  • quantity_sold – quantità di prodotto che è stato venduto e che viene addebitato su quella vendita/scontrino (es. 3 caffè)
  • price_per_unit – stesso valore di product.price_per_unit nel momento in cui è stata creata la vendita. Dobbiamo salvarlo perché price_per_unit nel product la tabella può cambiare nel tempo
  • price – prodotto di quantity_sold e price_per_unit; una piccola ridondanza che ci aiuta a evitare questo calcolo nelle query. In genere, la somma di tutti i prezzi degli articoli appartenenti alla stessa vendita dovrebbe essere uguale a sale.sale_amount
  • tax_amount – importo dell'imposta per quell'articolo al momento della ricezione
  • sale_id – ID della vendita a cui appartiene questo articolo
  • product_id – ID prodotto relativo a questo articolo

Ora potremmo facilmente fare un semplice rapporto, quanti prodotti/servizi abbiamo venduto nel periodo ea quale prezzo.

SELECT product.name, SUM(sale_item.quantity_sold) AS quantity, 
       SUM(sale_item.price) AS price
FROM sale, sale_item, product
WHERE sale.id = sale_item.sale_id
AND sale_item.product_id = product.id
AND sale.time_created >= @start_time 
AND sale.time_created <= @end_time
GROUP BY product.id