Quando si codificano i valori dei dati effettivi nel codice invece di utilizzare un DB?


17

Una domanda di lunga data per me è stata: quando immagazzino i dati (valori effettivi) in una tabella del database e quando li conservo nel codice?

Il consenso indicibile è stato in genere tale (*):

Se si tratta di una singola variabile o di una struttura semplice o di una matrice di pochi valori, inserire i dati nel codice.

[* Il consenso è stato discusso in commenti e risposte, ma fondamentalmente volevo una sorta di premessa per far ripartire la domanda, quindi sentiti libero di sfidare e migliorare su di essa ]

Esempio:

$number = 44;
$colors = array("blue", "yellow", ... "mauve");

Se ha centinaia + di righe di dati dello stesso tipo, utilizzare un database.

Ma sembra esserci un'area grigia; che dire di casi che non sono così chiari? A quali considerazioni e fattori è necessario prestare attenzione per prendere una decisione?

Esempio:
supponiamo che la tua azienda utilizzi 10-15 diversi tipi di telai di motori che possono essere rappresentati come "412T". Ne hai circa 30 e cambiano raramente. È possibile creare una tabella DB per quelli o codificarli in un database. In questo caso, i motori sono cose statiche e fisiche che non cambiano spesso.

La loro conservazione nel codice li sottopone al controllo del codice sorgente, dove in un database le modifiche del DB non vengono generalmente monitorate. Ma tenerli in un database libera (separa) il codice dai dati.

Un altro esempio (effettivo) che posso usare è questa mia domanda: /programming/26169751/how-to-best-get-the-data-out-of-a-lookup-table (attualmente 48 righe di dati opzione).


3
Il consenso indicibile in genere NON è stato tale: se si tratta di una singola variabile o di una struttura semplice o di una matrice di pochi valori, inserire i dati nel codice.
Pieter B,

C'è una via di mezzo: i dati sono archiviati in un database. Quindi viene estratto per scrivere il codice sorgente (ad esempio, in un global_constants.hfile).
mouviciel,

@mouviciel ma ciò che costituisce i dati ... hai bisogno di alcuni dati per accedere al database, quindi non puoi archiviare tutti i dati lì dentro.
jwenting

Risposte:


33

Non penso che queste due affermazioni rappresentino davvero un consenso su quando codificare i dati:

Se si tratta di una singola variabile o di una struttura semplice o di una matrice di pochi valori, inserire i dati nel codice

Se ha centinaia + di righe di dati dello stesso tipo, utilizzare un database

Semplice contro-esempio (sono sicuro che ce ne sono di migliori): le tabelle di sintassi del linguaggio di programmazione sono grandi strutture complesse che sono spesso codificate. Dai un'occhiata a un esempio del codice sorgente Perl .

Invece mi concentrerei prima di chiedere:

  • Con quale frequenza cambiano i dati?

  • Chi potrebbe aver bisogno di cambiarlo?

Se la risposta a "con quale frequenza" è "più spesso di quanto io voglia distribuire una nuova versione della mia app", non dovresti codificare i dati.

Se la risposta a "chi lo cambia" è "qualcuno oltre al programmatore", allora non dovresti codificare i dati.

In un piccolo negozio, è possibile che la distinzione tra il programmatore e l'utente sia scomparsa, e anche l'idea di "implementazione" è scomparsa. In questo caso sei il re del tuo dominio e puoi fare quello che vuoi.

Ma anche in quella situazione, può sorgere la necessità di collaborare, e ciò può essere difficile se un'applicazione personalizzata non segue una convenzione seguita in genere dai programmatori.


6
Simile alla frequenza con cui una domanda, un'altra domanda è "Con che velocità deve cambiare?" Il fattore di gating può essere il tempo impiegato per implementare la tua base di utenti. Per il software server centralizzato, la risposta potrebbe essere minuti, ma per le app mobili sul campo, potrebbero essere necessarie settimane.
CuriousRabbit

Nell'esempio Perl, lo direi come an array with a few values, pochi sono file 377-ish di tipo di dati fondamentali. Forse più di "pochi" per alcuni, ma è ancora piuttosto piccolo. Ho strutture simili ma leggermente meno piatte codificate. Se fossero più di mille righe, probabilmente sarei più riluttante a codificarlo in questo modo.
Dennis,

14

Andrei con la terza opzione: un file di configurazione!

Per le applicazioni su cui lavoro (in Java, quindi tutti i miei esempi usano Java + Spring), tali valori sono generalmente memorizzati in file di configurazione e iniettati (tramite Spring) nel codice che ne ha bisogno all'avvio dell'applicazione. In un file delle proprietà:

motorFramesString=412T, 413T, ...

Nella configurazione di primavera:

<bean="motorFrameManager" class="myCompany.MotorFrameManager" >
    <property name="motorFrames" value="${motorFrames}"/>
</bean>

Il vantaggio di questo è che puoi modificare o aggiungere più di questi valori prevalentemente statici abbastanza facilmente, senza ricompilare, e non devi preoccuparti di riempire il tuo database (relazionale) con dati di riferimento (dal momento che sembra essere un preoccupazione, e forse non tutto deve essere nel database comunque).

Per quanto riguarda il motivo per cui questi valori dovrebbero andare in un file di configurazione anziché in una tabella di riferimento: prevedi di utilizzare questi valori principalmente nel codice o principalmente nel database? Se hai molte query e viste e procedure che dipendono da questi valori, potrebbe essere meglio inserirli nel database come dati di riferimento, poiché è più semplice caricarli da file di configurazione e inviarli come parametri a ogni possibile query / visualizza / procedura che li fa riferimento. Se i valori vengono utilizzati principalmente nel codice dell'applicazione, il file di configurazione è probabilmente una scelta migliore.


Un esempio più complicato come quello che colleghi potrebbe essere fatto anche con o senza proprietà.

In products.properties:

productA.name=Product A 123
productA.hasMotor=true
productA.numFeet=1
productA.hasOutlet=true
productA.needsManual=true

productB.name=Product B 456
productB.hasMotor=false
productB.numFeet=1
productB.hasOutlet=true
productB.needsManual=true

Nel tuo file di configurazione di primavera:

<bean name="productA" class="com.mycompany.Product">
   <property name="name" value="${productA.name}"/>
   <property name="hasMotor" value="${productA.hasMotor}"/>
   <!-- rest omitted for brevity -->
</bean>
<bean name="productB" class="com.mycompany.Product">
   <property name="name" value="${productB.name}"/>
   <property name="hasMotor" value="${productB.hasMotor}"/>
   <!-- rest omitted for brevity -->
</bean>
<!-- configure as many beans as needed -->
<bean="motorFrameManager" class="myCompany.MotorFrameManager" >
    <property name="motorFrames"> <!-- assumes that MotorFrameManager has a property motorFrames which is a List<Product> -->
        <list>
            <ref bean="productA"/>
            <ref bean="productB"/>
        </list>
    </property>
</bean>

La cosa bella di questo è che se i tuoi dati di origine sono un foglio di calcolo (come nella domanda a cui ti sei collegato) puoi usare le macro in Excel per generare automaticamente le proprietà e i frammenti di primavera.


mentre sei nell'esempio di frame, è abbastanza semplice (solo un valore di stringa). Il tuo approccio sarà sostanzialmente lo stesso per la tabella delle opzioni che ha n-tuple di variabili miste (collegate in fondo alla mia domanda)?
Dennis

@Dennis: aggiunto un esempio più complesso.
FrustratedWithFormsDesigner

8
Un file di configurazione è solo una forma di db.
DougM,

3
@DougM, sono d'accordo, ma c'è una differenza tra impostare una serie di tabelle di configurazione in Oracle e avere un semplice file di configurazione XML. Il file di configurazione ha anche la virtù di essere controllato dal controllo della versione. Il file di configurazione è una via di mezzo e uno che incoraggia i programmatori a separare più dati di configurazione. Sto lottando per pensare a scenari realistici in cui il tempo non è una buona cosa
McCottle

2
@gbjbaanb: per la maggior parte delle applicazioni un RDBMS è eccessivo WAAAAAY, anche per sistemi altrimenti piuttosto estesi. Per non parlare del fatto che sono lenti e richiedono un notevole sforzo per mantenersi e integrarsi. I file "ini" non offrono alcun tipo di sicurezza, devi scrivere tu stesso il parser e devi scrivere il tuo controllo del tipo. I file di configurazione XML, almeno in .Net, ottengono essenzialmente GRATUITAMENTE tutti i vantaggi offerti da una delle opzioni preferite. Quindi la tua affermazione che un file di configurazione XML è sempre una scelta peggiore non potrebbe essere più sbagliata.
Dunk,

10

Penso che la premessa della domanda non sia del tutto corretta. Il fattore di divisione non è la quantità di record che devono essere modificati, ma la frequenza dei cambiamenti e anche chi li modifica.

Frequenza

Quando i dati sono volatili , nel senso che cambiano spesso e al di fuori di un ciclo di rilascio del software, devono essere configurati al di fuori di valori hardcoded o persino di file di configurazione. Un database ha senso qui, soprattutto se l'applicazione stessa è in grado di gestirlo.

Chi

Quando un cliente deve essere in grado di modificare i dati, deve essere modificabile in modo intuitivo e al di fuori di un ciclo di rilascio.

Filo comune

Il thread comune qui è che quando i dati devono cambiare al di fuori di una versione del software, dovrebbero essere archiviati in un database. I database potrebbero essere aggiornati durante una versione, ma i dati sopravvivono senza essere ripristinati o fortemente modificati. Quando un cliente deve essere in grado di modificare i dati (o configurare la funzionalità), dovrebbe essere archiviato in un database con un bel front-end a prova di idiota.

analisi

Assicurati di scrivere unit test che convalidano il tuo software in una varietà di configurazioni. Forse il tuo cliente attiva un prompt opzionale o ridefinisce un metro per equivalere a dodici piedi. Indipendentemente da quanto sia ragionevole la modifica, se il tuo software lo consente, è ben meglio convalidare che la modifica funziona come previsto, non importa quanto sia insano.


4

Non è né la frequenza delle modifiche né la quantità di dati che decide dove archiviare i dati.

Se i dati sono necessari per eseguire il programma, fanno parte del codice del programma, quindi archiviarli come costante. Tutti gli altri dati vanno nel database.

Naturalmente, i file di configurazione, le immagini, i suoni, ecc. Di solito sono meglio memorizzati sul filesystem.


Ho realizzato un programma di assistenza al call center interamente guidato da db; i dati dovevano "eseguire il codice", ma sarebbe stato assurdo compilarlo.
DougM,

1
Sono stato uno sviluppatore Oracle per 8 anni, ma ancora non mi piacciono le applicazioni che hanno un così stretto accoppiamento con il database sottostante.
winkbrace,

2

Se c'è anche la minima possibilità che tu abbia mai ricevuto una telefonata che ti costringe a ricostruire un'applicazione perché qualcosa di hardcoded è cambiato, allora non codificarlo. Almeno tenerlo in un file di configurazione o tabella db. Non è necessario fornire alcuna interfaccia utente per mantenerlo necessariamente, ma è sicuramente preferibile comporre e modificare un file di configurazione o eseguire un SQL UPDATE su una tabella per ricostruire l'intera partita di tiro.


1

La distinzione è in effetti un'area piuttosto grigia, ma il mio approccio a questo tipo di problemi è: i dati cambiano in produzione "? Tutto ciò che cambia dopo la distribuzione in un ambiente di produzione dovrebbe andare nel database, anche per cose che raramente possono cambiare.

Quindi la domanda che dovresti porre non è "quanto spesso cambierà?", Ma "può cambiare?". Se un valore per una proprietà può variare all'interno della stessa iterazione di codice (senza toccare nient'altro nel codice) nell'ambiente di produzione, entra nel database.


0

Ciò che manca anche sono le informazioni sul tipo di "controllo del programma", ad esempio la dimensione massima del buffer, il numero di elementi ad alta voce in un ordine, la dimensione massima della pagina per uno schermo è sempre meglio codificata nel programma o in un file di configurazione.

Se conservi questo tipo di dati in un database, c'è sempre la possibilità che qualcuno li cambi al volo e cambi completamente il comportamento di un sistema.

L'altro problema è che non esiste un modo semplice per ottenere voci di database attraverso il controllo del codice sorgente / gestione delle modifiche / sistemi di compilazione automatica che dovresti usare.


0

Una cosa che non dovresti mai tenere nel database sono i dettagli necessari per accedere al database.
Hai un po 'di catch-22 se devi accedere al database per recuperare le stringhe di connessione, il nome utente e la password per quello stesso database dopo tutto.

Hardcode vero? hmm, potrebbe funzionare se stai usando una specie di database che si installa e spedisce con l'applicazione.
File di configurazione? Più promettente, ma per quanto riguarda la sicurezza dell'account?

Ovviamente potresti archiviare le informazioni del database in quel file di configurazione in forma crittografata, ma allora avresti bisogno di avere le chiavi di decrittazione archiviate da qualche parte, e questo sarebbe quasi sicuramente codificato.

A parte questo, ci sono cose che non cambiano mai. Cose come le costanti naturali (G, pi, e, tu lo chiami), cose forse come certe espressioni regolari, come la convalida della posta elettronica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.