Dati di configurazione: tabella a riga singola e tabella coppia valore nome

58

Supponiamo che tu scriva un'applicazione che può essere configurata dall'utente. Per memorizzare questi "dati di configurazione" in un database, vengono comunemente utilizzati due modelli.

  1. La tabella a riga singola

      CompanyName  |  StartFullScreen  |  RefreshSeconds  |  ...
    ---------------+-------------------+------------------+--------
      ACME Inc.    |        true       |       20         |  ...
    
  2. La tabella nome-valore-coppia

      ConfigOption   |   Value
    -----------------+-------------
     CompanyName     | ACME Inc.
     StartFullScreen | true (or 1, or Y, ...)
     RefreshSeconds  | 20
     ...             | ...
    

Ho visto entrambe le opzioni in natura, ed entrambe hanno evidenti vantaggi e svantaggi, ad esempio:

  • Le tabelle a riga singola limitano il numero di opzioni di configurazione che è possibile avere (poiché il numero di colonne di una riga è generalmente limitato). Ogni opzione di configurazione aggiuntiva richiede una modifica dello schema del DB.
  • In una tabella nome-valore-coppia tutto è "tipicamente stringa" (devi codificare / decodificare i parametri booleano / data / etc).
  • (molti altri)

C'è qualche consenso all'interno della comunità di sviluppo su quale opzione sia preferibile?

    
posta Heinzi 04.09.2012 - 16:48
fonte

7 risposte

14

Personalmente preferisco le tabelle a riga singola per la maggior parte delle cose. Anche se è vero che è meno flessibile, a meno che non ti aspetti un comportamento dinamico, è perfettamente accettabile aggiungere colonne aggiuntive in seguito, se necessario. In un certo senso, è l'equivalente dell'uso di un dizionario / mappa per contenere le coppie nome-valore rispetto ai membri della classe durante la programmazione. Certo, non è una metafora perfetta, ma molti dei vantaggi e degli svantaggi sono paralleli quando ci pensi.

Quindi useresti un dizionario / mappa sui membri della classe? Probabilmente no, a meno che non abbiate motivo di pensare che la quantità di dati da rappresentare sia del tutto adattabile, proprio come avere una tabella di coppie nome-valore.

    
risposta data 04.09.2012 - 16:58
fonte
12

In genere vado con l'opzione 2, ma avrei più colonne per applicare il tipo di dati

ConfigOption   |   textValue    |   DateValue   |   NumericValue

Opzione 1 Ha il vantaggio aggiuntivo che puoi facilmente "Scambiare" intere Configurazioni aggiungendo una colonna Active .

    
risposta data 04.09.2012 - 16:55
fonte
8

Per me, che tu vada su una singola riga o su EAV dipende da come vuoi consumarli.

Il potere di EAV è che i nuovi dati possono essere aggiunti senza modifiche alla struttura. Ciò significa che se si desidera un nuovo valore di configurazione, è sufficiente aggiungerlo alla tabella ed estrarlo dove desiderato nel codice e non è necessario aggiungere un nuovo campo al dominio, schema, mapping, query DAL , ecc.

Il suo difetto è che ha solo la struttura più sottile, che richiede di trattare i dati in modo pessimistico. Ogni utilizzo di qualsiasi valore di configurazione deve aspettarsi che il valore non sia presente o non nel formato corretto e si comporti di conseguenza quando non lo è. Un valore di configurazione potrebbe non essere analizzabile a un doppio, a un int o a un carattere. Potrebbe essere nullo. potrebbe non esserci nessuna riga per il valore. Le modalità attorno a questo richiedono solitamente un unico valore "predefinito" valido per tutti i valori di configurazione di un particolare tipo in-code ( estremamente raro, più spesso il valore predefinito è altrettanto problematico per il consumo del codice come niente affatto), o per mantenere un dizionario hardcoded di valori predefiniti (che deve cambiare ogni volta che viene aggiunta una nuova colonna, rendendo il vantaggio principale dello storage EAV piuttosto moot).

Una singola riga larga è praticamente l'opposto. Si esegue il mapping su una singola istanza di un oggetto Configuration con un campo / una proprietà per ogni valore di configurazione esistente. Sai esattamente di che tipo dovrebbero essere quei valori in fase di compilazione, e "fallisci velocemente" nel DAL se una colonna di configurazione non esiste o non ha un valore del tipo corretto, dandoti un posto dove catturare le eccezioni basate sui problemi di recupero / idratazione della configurazione.

Il principale svantaggio è che è necessario un cambiamento strutturale per ogni nuovo valore; nuova colonna DB, nuova colonna nel DAL (il mapping o le query SQL / SP), nuova colonna di dominio, tutto il necessario per testare correttamente l'utilizzo.

La situazione corretta in cui utilizzare una di queste è la situazione in cui gli svantaggi vengono mitigati. Per me, la maggior parte delle situazioni per la codifica di configurazione ha richiesto un'implementazione a riga singola. Questo è principalmente dovuto al fatto che se stai introducendo un valore di configurazione completamente nuovo che regola il comportamento di una parte del tuo programma, devi già cambiare il codice in usare il nuovo valore di configurazione; perché non passare all'oggetto config e aggiungere il valore da utilizzare?

In breve, uno schema EAV per archiviare la configurazione in realtà non risolve il problema che si propone di risolvere, e la maggior parte delle soluzioni alternative ai problemi che presenta violano DRY.

    
risposta data 04.09.2012 - 22:33
fonte
4

Specificamente per i valori di configurazione, direi - vai con la singola riga. A meno che tu non stia passando per lo sviluppo, quante volte cambieranno comunque quelle colonne?

Probabilmente è meglio proteggere il tipo di dati dei valori , piuttosto che il codice per l'estensibilità che probabilmente non avrai nei tempi di fermo tra grandi (r) versioni. Inoltre, aggiungere o rimuovere una singola colonna è solo la migrazione più semplice che esista. Non prevedo un mal di testa durante la creazione di una nuova opzione di configurazione.

Inoltre, hai detto che "utenti" possono configurare queste opzioni, senza fornire un limite. Sono configurazioni per utente? In tal caso, sosterrò ancora più strongmente che le opzioni di configurazione dovrebbero essere nelle colonne: una singola riga per utente. In seguito risparmierai molti mal di testa di manutenzione.

    
risposta data 04.09.2012 - 23:13
fonte
1

Singola riga Pro: ben definito. Contro: cambiare la configurazione può essere un problema. Migrazioni DB ecc.

Entità-Valore Pro: Super flessibile, supporta l'evoluzione della tua configurazione. Contro: integrità referenziale? Più controlli nel codice per vedere se la proprietà esiste prima di poter fare qualsiasi cosa su di essa.

Prenderò l'approccio 2 supportato da un db non relazionale come Mongo. Se c'è qualcosa di cui puoi essere sicuro, il suo cambiamento.

    
risposta data 04.09.2012 - 21:32
fonte
1

Usa entrambi!

Ordina quali opzioni possono avere più istanze e quali opzioni sono generiche.

La tabella a riga singola (configurazioni)

  id  |  company_name  |  start_fullscreen  |  refresh_seconds  |  ...
------+----------------+--------------------+-------------------+-------
  4   |  ACME Inc.     |  true              |  20               |  ...

La tabella nome-valore-coppia (opzioni)

  name             |  value          | update_time  
-------------------+-----------------+--------------
  generic_option_1 |  Option 1 Value | timestamp    
  generic_option_2 |  Option 2 Value | timestamp    
  generic_option_3 |  Option 3 Value | timestamp    
  configuration    |  4              | timestamp    
  ...              |  ...            | ...          

Penso che sia più flessibile.

    
risposta data 24.11.2016 - 10:10
fonte
1

Se i tuoi client possono elaborare frammenti JSON (che non sono solo matrici e dizionari, ma anche semplici stringhe, numeri, booleani, valori nulli), puoi avere una tabella a più righe con il nome dell'opzione e un valore stringa contenente JSON. Ciò consente anche di memorizzare valori strutturati e il codice per elaborarli dovrebbe già essere lì.

Se i tuoi clienti non possono elaborare frammenti JSON, ottieni nuovi clienti.

    
risposta data 24.11.2016 - 10:30
fonte

Leggi altre domande sui tag