Gestire le enumerazioni (tabelle di ricerca)

2

Sto cercando di progettare lo schema DB del mio nuovo progetto e ho bisogno di alcuni suggerimenti. Ho deciso di creare una tabella di ricerca per salvare i valori di enumerazione. Quindi ho una tabella Status con queste colonne idstatus , statusName , statusCode . La mia domanda è, pensi che sia una buona pratica seguire questa strada? Immagina uno scenario per cui vuoi aggiornare lo stato di un ordine. Quindi l'app front-end deve inviare statusCode e quindi deve ottenere il idstatus di questo codice e infine aggiornare la tabella Order .

Che ne pensi? C'è un approccio migliore?

    
posta pik4 23.05.2018 - 15:17
fonte

3 risposte

2

Le tabelle di ricerca sono molto utili e una buona pratica, poiché il database rimane la fonte dei dati e non lo si diffonde tra database e applicazione.

Il database dovrebbe essere la fonte di dati canonica. Il salvataggio dei valori di enumerazione nelle tabelle di ricerca fornisce l'integrità referenziale a causa delle relazioni di chiavi esterne tra le tabelle di ricerca e le altre tabelle che utilizzano queste enumerazioni. Il database diventa l'unica fonte di verità su quali elementi si trovano in queste enumerazioni.

I linguaggi di programmazione come C # consentono di salvare una stringa in una colonna nel database e quindi mapparla facilmente a enum , ma il codice C # diventa l'unica fonte di verità per quei dati, ma non il resto . Il codice di programmazione dovrebbe essere l'unica fonte di verità per il comportamento: gli algoritmi. Il database dovrebbe essere sui dati. L'utilizzo delle tabelle di ricerca consente di completare questa separazione.

Immagina un caso in cui hai due stati per gli ordini:

  1. In attesa
  2. Fullfilled

Quindi crei un enum in un linguaggio di programmazione per rappresentarlo:

public enum OrderStatus
{
    Pending = 0,
    Fullfilled = 1
}

Quindi aggiungi un altro stato: Cancelled = 2 ma non hai ancora salvato un ordine "annullato" nel database. Durante la navigazione intorno alle tabelle del database, vengono visualizzati solo gli stati "In sospeso" e "Completato" per gli ordini. Senza il codice di programmazione disponibile non puoi dire quali sono tutti i valori possibili.

In relazione a questo, ti consiglio di utilizzare una colonna "codice" per la chiave primaria - una stringa, in sostanza. Qualcosa di corto. Quando si guardano le tabelle nel database, non è necessario tenere traccia dei numeri e delle loro rappresentazioni corrispondenti. Non è necessario ricordare che un ID stato di 1 è In attesa e 2 è Pieno, e 3 è Annullato. Se la tua tabella di stato ha questi tre stati, e le loro chiavi primarie sono letteralmente "In sospeso", "Completato" e "Annullato", allora le altre tabelle che utilizzano quegli stati avranno chiavi estranee che hanno senso per un umano, senza la necessità per ricordare il numero della traduzione del nome dello stato.

    
risposta data 23.06.2018 - 02:56
fonte
1

Il tuo scenario è molto tipico e ricorrente. L'adozione di un idstatus ha alcune implicazioni benefiche per la progettazione di DB e alcune complessità da gestire nella progettazione del livello di dominio.

TL; DR : se le tue enumerazioni dipendono dalla logica del dominio (non è un requisito non funzionale) vai al sicuro per idstatus e preparati a gestire un piccolo sforzo in più sulla progettazione di DomainLayer.

Progettazione DB

  • Prestazioni : un FK su un tipo più compatto (tipicamente INT) è migliore (osservazione davvero ingenua) e potrebbe velocizzare il filtraggio sulla tabella master nel caso in cui statusCode s tendesse a essere troppo ampio o il master tabella ha molte di queste enumerazioni
  • Evolvibilità : puoi essere davvero sicuro che il statusCode s stesso (o più statusName ) non cambierà in futuro? ... I codici dovrebbero trasmettere informazioni sul modello di dominio e il vocabolario del tuo modello potrebbe evolversi : avere un modo semplice per adattarsi ad esso non sarebbe così male

Progettazione livello dominio

  • Codici di stato : sono semanticamente Valori oggetto e non Entità : non esporre il loro idstatus a Application Layer mai quindi ...
    • Modelli di entità : le tue entità dovrebbero evitare di esporre qualsiasi idstatus in favore di statusCode s.
    • Repository : modella l'interfaccia dei repository esponendo statusCode s. La gestione di una query con una ricerca aggiuntiva non è così complessa. Tieni in considerazione che potresti anche evitare un ulteriore JOIN se memorizzi nella cache la tabella di ricerca a questo livello ... nel caso in cui sei esasperato dal guadagno di prestazioni
risposta data 23.06.2018 - 00:31
fonte
0

Il design del database dovrebbe essere basato su come lo si utilizzerà. Ovviamente se hai davvero bisogno di iniziare dalla progettazione del database (come puoi anche partire da casi aziendali). La stessa regola si applica alle tabelle di ricerca. Se tu :

  • hanno un gruppo di proprietà che difficilmente vengono cambiate per entità
  • ha una proprietà comune per tutte le righe della tabella (ad esempio, lo stato in la maggior parte dei casi è comune per gli ordini)
  • desidera recuperare la proprietà comune senza estrarla da tutti righe (ad esempio, elenca tutti gli stati possibili per nome senza controllarli in tutte le righe)
  • ...
  • ...

tu potresti pensare a una tabella aggiuntiva, tabella di ricerca. Ma tu non devi. Identifica i casi principali: controlla quale soluzione è migliore. Non indovinare!

Se decidi di farlo nella maggior parte dei casi, utilizzerai alcuni ID / i univoci in un'unica entità e gli stessi ID di indici nella parte comune (la tua tabella di ricerca). Quindi chiederai al frontend la lista di tutti gli stati e riceverai oggetti con id, nome e codice (se non è univoco e devi visualizzarlo). L'utente sceglie per nome nell'interfaccia utente e passa l'id di stato corrispondente al back-end (+ dell'ID ordine del corso) per aggiornare l'ordine specifico.

    
risposta data 23.05.2018 - 15:49
fonte

Leggi altre domande sui tag