¿Cuándo se codifican los valores de datos reales en el código en lugar de usar un DB?

17

Una pregunta de larga data para mí ha sido: ¿cuándo almaceno datos (valores reales) en una tabla de base de datos y cuándo los guardo directamente en el código?

El consenso no contado ha sido típicamente como tal (*):

Si es una variable única o una estructura simple, o una matriz de unos pocos valores, coloque los datos directamente en el código.

[* el consenso ha sido debatido en comentarios y respuestas, pero básicamente quería una especie de premisa para impulsar la pregunta, así que siéntete libre de desafiarla y mejorarla ]

Ejemplo:

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

Si tiene cientos de filas de datos del mismo tipo, use una base de datos.

Pero parece haber un área gris; ¿Qué pasa con los casos que no son tan claros? ¿A qué consideraciones y factores hay que prestarle atención para tomar una decisión?

Ejemplo:
supongamos que su empresa utiliza entre 10 y 15 tipos diferentes de bastidores de motores que se pueden representar como "412T". Tienes alrededor de 30 de ellos y cambian raramente. Puede crear una tabla de base de datos para esos o codificarlos en una base de datos. En este caso, los motores son cosas físicas estáticas que no es probable que cambien con frecuencia.

Mantenerlos en código los somete al control de origen, donde en una base de datos, los cambios en la base de datos generalmente no se rastrean. Pero mantenerlos en una base de datos libera (separa) el código de los datos.

Otro ejemplo (real) que puedo usar es esta pregunta mía: /programming/26169751/how-to-best-get-the-data-out-of-a-lookup-table (actualmente 48 filas de datos de opciones).

Dennis
fuente
3
El consenso no contado normalmente NO ha sido como tal: si se trata de una sola variable o una estructura simple, o una matriz de algunos valores, coloque los datos en el código.
Pieter B
Hay una vía intermedia: los datos se almacenan en una base de datos. Luego se extrae para escribir el código fuente (por ejemplo, en un global_constants.harchivo).
mouviciel
@mouviciel, pero lo que constituye datos ... necesita algunos datos para acceder a la base de datos, por lo que no puede almacenar todos los datos allí.
Jwenting

Respuestas:

33

No creo que estas dos declaraciones realmente representen un consenso sobre cuándo codificar los datos:

Si es una variable única o una estructura simple, o una matriz de algunos valores, coloque los datos directamente en el código

Si tiene cientos de filas de datos del mismo tipo, use una base de datos

Contraejemplo simple (estoy seguro de que hay mejores): las tablas de sintaxis del lenguaje de programación son estructuras grandes y complejas que a menudo están codificadas. Eche un vistazo a un ejemplo del código fuente de Perl .

En cambio, me centraría primero en preguntar:

  • ¿Con qué frecuencia cambian los datos?

  • ¿Quién podría necesitar cambiarlo?

Si la respuesta a "con qué frecuencia" es "con más frecuencia de la que quiero implementar una nueva versión de mi aplicación", entonces no debe codificar los datos.

Si la respuesta a "quién lo cambia" es "alguien además del programador", entonces no debe codificar los datos.

En una tienda pequeña, es posible que la distinción entre el codificador y el usuario haya desaparecido, y la idea de "despliegue" también ha desaparecido. En este caso, eres el rey de tu propio dominio y puedes hacer lo que quieras.

Pero incluso en esa situación, puede surgir la necesidad de colaborar, y eso puede ser difícil si una aplicación personalizada no sigue una convención que los programadores suelen seguir.

código x
fuente
66
Similar a la pregunta con qué frecuencia, otra pregunta es, "¿Qué tan rápido necesita cambiar?" El factor de activación puede ser cuánto tiempo lleva desplegarse en su base de usuarios. Para el software de servidor centralizado, la respuesta puede ser minutos, pero para las aplicaciones móviles en el campo, podría llevar semanas.
CuriousRabbit
En el ejemplo de Perl, lo pondría como an array with a few values, pocas son filas de 377 ish de tipo de datos fundamentales. Tal vez más que "unos pocos" para algunos, pero aún es bastante pequeño. Tengo estructuras similares pero un poco menos planas codificadas. Si fuera más de mil filas, probablemente sería más reacio a codificarlo de esta manera.
Dennis
14

Iría con la tercera opción: ¡un archivo de configuración!

Para las aplicaciones en las que trabajo (en Java, por lo que todos mis ejemplos usan Java + Spring), dichos valores generalmente se almacenan en archivos de configuración y se inyectan (a través de Spring) en el código que los necesita cuando se inicia la aplicación. En un archivo de propiedades:

motorFramesString=412T, 413T, ...

En la configuración de primavera:

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

La ventaja de esto es que puede cambiar o agregar más de estos valores mayoritariamente estáticos con la suficiente facilidad, sin recompilar, y no tiene que preocuparse por llenar su base de datos (relacional) con datos de referencia (ya que parece ser un preocupación, y tal vez no todo tiene que estar en la base de datos de todos modos).

En cuanto a por qué estos valores deberían ir a un archivo de configuración en lugar de una tabla de referencia: ¿planea usar estos valores principalmente en el código o principalmente en la base de datos? Si tiene muchas consultas, vistas y procedimientos existentes que dependen de estos valores, puede ser mejor colocarlos en la base de datos como datos de referencia, ya que es más fácil que cargarlos desde archivos de configuración y enviarlos como parámetros a cada consulta posible / vista / procedimiento que los hace referencia. Si los valores se usan principalmente en el código de la aplicación, entonces el archivo de configuración es probablemente una mejor opción.


También podría hacerse un ejemplo más complicado, como lo que vincula, con o sin propiedades.

En productos.propiedades:

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

En su archivo de configuración de 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>

Lo bueno de esto es que si sus datos de origen son una hoja de cálculo (como en la pregunta a la que se vinculó) puede usar macros en Excel para generar automáticamente las propiedades y los fragmentos de resorte.

FrustratedWithFormsDesigner
fuente
mientras está en el ejemplo del marco, es bastante simple (solo un valor de cadena). ¿Su enfoque será básicamente el mismo para la tabla de opciones que tiene n-tuplas de variables mixtas (vinculadas al final de mi pregunta)?
Dennis
@ Dennis: Se agregó un ejemplo más complejo.
FrustratedWithFormsDesigner
8
Un archivo de configuración es solo una forma de db.
DougM
3
@DougM, estoy de acuerdo, pero hay una gran diferencia entre configurar una serie de tablas de configuración en Oracle y tener un archivo de configuración XML simple. El archivo de configuración también tiene la virtud de ser controlado por el control de versiones. El archivo de configuración es un término medio y uno que anima a los codificadores a separar más datos de configuración. Me cuesta pensar en escenarios realistas en los que el tiempo no sea algo bueno
mcottle
2
@gbjbaanb: Para la mayoría de las aplicaciones, un RDBMS es una exageración WAAAAAY, incluso para sistemas bastante extensos. Sin mencionar que son lentos y requieren un esfuerzo considerable para mantenerse e integrarse. Los archivos "ini" no proporcionan ningún tipo de seguridad, debe escribir el analizador usted mismo y debe escribir su propia verificación de tipo. Los archivos de configuración XML, al menos en .Net, obtienen todos los beneficios proporcionados por cualquiera de sus opciones preferidas esencialmente GRATIS. Por lo tanto, su afirmación de que un archivo de configuración XML siempre es una elección peor no podría estar más equivocada.
Dunk
10

Creo que la premisa de la pregunta no es del todo correcta. El factor de división no es la cantidad de registros que necesitan cambiar, sino la frecuencia de los cambios y quién los cambia.

Frecuencia

Cuando los datos son volátiles , en el sentido de que cambian con frecuencia y fuera del ciclo de lanzamiento del software, deben poder configurarse fuera de los valores codificados o incluso de los archivos de configuración. Una base de datos tiene sentido aquí, especialmente si la aplicación en sí es capaz de mantenerla.

Quien

Cuando un cliente necesita poder cambiar datos, debe ser modificable de una manera fácil de usar y fuera de un ciclo de lanzamiento.

Hilo común

El hilo conductor aquí es que cuando los datos necesitan cambiar fuera de una versión de software, deben almacenarse en una base de datos. Las bases de datos pueden actualizarse durante un lanzamiento, pero los datos perduran sin restablecerse ni modificarse demasiado. Cuando un cliente necesita poder modificar datos (o configurar la funcionalidad), debe almacenarse en una base de datos con un buen front end que sea a prueba de idiotas.

Pruebas

Asegúrese de escribir pruebas unitarias que validen su software en una variedad de configuraciones. Tal vez su cliente active un aviso opcional o redefina un metro para igualar doce pies. Independientemente de cuán razonable sea el cambio, si su software lo permite, es mejor validar que el cambio funcione como se espera, sin importar cuán estúpido sea.


fuente
4

No es la frecuencia de los cambios ni la cantidad de datos lo que decide dónde almacenar los datos.

Si se requieren los datos para ejecutar el programa, es parte del código del programa, por lo tanto, guárdelo como una constante. Todos los demás datos van en la base de datos.

Por supuesto, los archivos de configuración, imágenes, sonidos, etc. generalmente se almacenan mejor en el sistema de archivos.

winkbrace
fuente
Hice un programa de asistencia de centro de llamadas que estaba completamente basado en db; los datos fueron necesarios para "ejecutar el código", pero hubiera sido absurdo compilarlo.
DougM
1
Fui desarrollador de Oracle durante 8 años, pero todavía no me gustan las aplicaciones que tienen un acoplamiento tan estrecho con la base de datos subyacente.
winkbrace
2

Si existe la más mínima posibilidad de que reciba una llamada telefónica que le obligue a reconstruir una aplicación porque ha cambiado algo codificado, entonces no lo codifique. Como mínimo, guárdelo en un archivo de configuración o en una tabla db. No tiene que proporcionar ninguna interfaz de usuario para mantenerla necesariamente, pero marcar y cambiar un archivo de configuración o ejecutar una ACTUALIZACIÓN de SQL en una tabla seguramente es preferible a reconstruir toda la coincidencia de disparo.

Alan B
fuente
1

La distinción es, de hecho, un área un tanto gris, pero mi enfoque para este tipo de problemas es: ¿cambian los datos en la producción "? Cualquier cosa que cambie después del despliegue en un entorno de producción debería ir a la base de datos, incluso para cosas que rara vez cambian.

Entonces, la pregunta que debe hacerse no es "¿con qué frecuencia cambiará?", Sino "¿puede cambiar?". Si el valor de una propiedad puede variar dentro de la misma iteración de código (sin tocar nada más en el código) en el entorno de producción, entra en la base de datos.

Thyamarkos
fuente
0

Lo que también le falta es información de tipo "control de programa" que dice el tamaño máximo del búfer, el número de elementos en voz alta en un orden, el tamaño máximo de página para una pantalla siempre es mejor codificado en el programa o en un archivo de configuración.

Si mantiene este tipo de datos en una base de datos, siempre existe la posibilidad de que alguien lo cambie sobre la marcha y cambie por completo el comportamiento de un sistema.

El otro problema es que no hay una manera fácil de obtener entradas de la base de datos a través del control de origen / gestión de cambios / sistemas de compilación automática que debería estar utilizando.

James Anderson
fuente
0

Una cosa que nunca debe guardar en la base de datos son los detalles necesarios para acceder a la base de datos.
Después de todo, tiene un poco de catch-22 si necesita acceder a la base de datos para recuperar las cadenas de conexión, el nombre de usuario y la contraseña para esa misma base de datos.

¿Codificarlo? hmm, podría funcionar si está utilizando algún tipo de base de datos que se instala y se envía con la aplicación.
¿Archivo de configuración? Más prometedor, pero ¿qué pasa con la seguridad de la cuenta?

Por supuesto, podría almacenar la información de la base de datos en ese archivo de configuración en forma cifrada, pero luego necesitaría tener las claves de descifrado almacenadas en algún lugar, y eso sería codificado casi con toda seguridad.

Aparte de eso, hay cosas que nunca cambian. Cosas como las constantes naturales (G, pi, e, lo que sea), cosas como ciertas expresiones regulares, como la validación de correo electrónico.

jwenting
fuente