Caso d'uso eCommerce: rimozione di un prodotto

4

Sto iniziando a progettare lo schema del database per l'elemento eCommerce di un servizio Web che sto creando.

La cosa che sto cercando di capire è come gestire il caso d'uso di un venditore (utente del mio servizio web) che cancella un prodotto.

Il problema che ho è che questo prodotto può essere referenziato in un paniere di clienti, per essere pagato ordini, ordini in sospeso, consegne, ordini passati ecc ...

Questo problema è sicuramente uno che tutti coloro che stanno sviluppando un simile sistema si sono imbattuti. Mi sto solo chiedendo se esiste un modo migliore per affrontarlo?

Può essere indirizzato a livello di schema del database? O forse richiede solo alcuni controlli di convalida sui dati del database prima di consentire l'eliminazione di un prodotto o di interrompere un errore se un cliente sta tentando di pagare un ordine che ha un riferimento a un prodotto, ma tale riferimento è stato eliminato (es. prodotto è stato eliminato).

    
posta Gaz_Edge 20.12.2013 - 18:22
fonte

4 risposte

3

L'approccio standard consiste nel contrassegnare il prodotto come inattivo, fuori produzione o altrimenti non visibile. L'eliminazione di una voce dal database ha un'intera cascata di eventi che possono essere problematici.

Questo potrebbe essere qualcosa di semplice come un enumerico booleano, o un enum di MySQL, o la sua tabella da unirsi (se si vuole distinguere la differenza tra inattivo (non ancora disponibile e non visibile) e interrotto (precedentemente disponibile e non visibile).

Considera uno schema simile a questo:

 +---------------+     +----------------+
 | Product       |     | Product_state  |
 |---------------|     |----------------|
 | id (PK)       |  +--+ id (PK)        |
 | status (FK)   +--+  | visibile       |
 | sku           |     | desc           |
 | vendor (FK)   |     +----------------+
 | desc          |
 | ...           |
 +---------------+

Assicurati di avere tutti gli indici appropriati sulle tabelle (vedi Bitmap vs B-tree in Oracle e indice bitmap su wikipedia ). Questo, combinato con la vista corretta, ti consentirà di semplificare la logica della query.

Raramente i prodotti esistono da soli. Come hai detto:

The issue I have is that this product could be referenced in a customers basket, to be paid orders, pending orders, deliveries, past orders etc...

Rimuovere il prodotto dal database lascerebbe riferimenti ciondolanti a cose che non esistono. Ancora più "divertente" è se il database è stato costruito con chiavi esterne a cascata, che cascata di eventi diventa ancora più "divertente" con una cascata di eliminazioni che cancella i dati o imposta i valori su null (a seconda di come è configurata la cascata - vedi Chiave esterna su Wikipedia ). Nota che puoi usare questo approccio in alcuni RDBM per impedire a che gli utenti rovinino la tabella principale usando l'opzione restrict sulle chiavi esterne.

Non lo useresti solo per "in un carrello" come una cosa, ma come hai detto, ordini pagati, in sospeso, consegne, garanzie, ecc ... Limitazione della chiave esterna cancella sarà darti un errore nel database se cerchi di cancellare dove non dovrebbe essere e verrà applicato dal database stesso, invece di provare a implementare i controlli nel codice.

L'utilizzo dei vincoli di chiave esterna assicurerà inoltre che il database mantenga l'integrità referenziale, impedendo alle persone di collegare accidentalmente un ordine a qualcosa che non esiste (il che è altrettanto grave dell'eliminazione). Può anche migliorare le prestazioni delle letture (vedi La chiave esterna migliora le prestazioni delle query? )

Per oracle, puoi leggere i vincoli sulle chiavi esterne: 13.1.17.2 Utilizzo dei vincoli di chiave esterna

Per mysql, puoi leggere su 14.2.7.6 InnoDB e straniero vincoli chiave

    
risposta data 26.12.2013 - 17:14
fonte
5

Lo gestiamo tramite un campo di stato. I prodotti possono essere attivi, inattivi, in ordine arretrato, advance_sale, superati o interrotti. Solo i prodotti attivi, advance_sale e backorder vengono visualizzati all'utente.

Cosa fare se lo stato cambia durante una transazione è un requisito aziendale. Alcuni venditori potrebbero desiderare che il cliente venga informato e che l'articolo sia rimosso dal carrello. Alcuni potrebbero consentire ai clienti con l'articolo nel carrello di controllare, ma l'articolo non può apparire sui nuovi ordini. Abbiamo un verificatore di idoneità del prodotto per negozio che controlla i prodotti nel carrello di un cliente ogni volta che si verifica un'attività del carrello (aggiungi / rimuovi articolo, modifica quantità, avvia cassa). Se supporti liste di desideri o ordini ricorrenti, assicurati che la tua soluzione tenga conto anche di quelli.

    
risposta data 20.12.2013 - 21:11
fonte
2

Non cancellare; segnalo interrotto o non disponibile, come Mike ha sottolineato nei commenti. Se il prodotto viene interrotto, non lo si mostra più nelle pagine di vendita, ma i riferimenti del database vengono lasciati intatti. Se c'è un ordine in sospeso per quel prodotto, allora il lato business (non il database) deve capire come gestirlo: lo spediamo ancora (supponendo che c'è in magazzino) o emettiamo un rimborso?

Detto questo, se l'articolo non è usato in nessun carrello della spesa, ordini, ecc. - per esempio, è solo usato per addestrare qualcuno o è stato in qualche modo creato inavvertitamente - quindi, certo , cancella. Ma è necessario eseguire molti controlli di integrità anche in questo scenario per assicurarsi che la cancellazione sia sicura; probabilmente stai ancora meglio tagliandolo fuori produzione.

    
risposta data 20.12.2013 - 19:51
fonte
2

Non permetteremo al nostro sistema di eliminare fisicamente il prodotto. Abbiamo semplicemente impostato il flag Attivo su "No". Ciò ha permesso alle fatture archiviate di produrre correttamente.

Aggiornato il 12-26-2013: C'è un problema più grande in gioco qui

Dopo aver riletto la domanda dell'OP, sembra che questo servizio web sarà utilizzato da più di un venditore. In tal caso, esiste una relazione molti a molti tra venditore e prodotto. Quindi, non solo la tabella Product deve contenere un flag booleano attivo la tabella Product richiede un ForeingKey che identifica il SellerId .

    
risposta data 20.12.2013 - 20:07
fonte