Mantener una enumeración y una tabla sincronizadas

11

Estoy haciendo un programa que publicará datos en una base de datos, y me he encontrado con un patrón que estoy seguro es familiar: una breve tabla de valores fijos más probables (muy probables) que sirven como enumeración. Supongamos que la siguiente tabla se llama Status:

  Estado
  ID Descripción
  --------------
   0 sin procesar
   1 pendiente
   2 procesados
   3 error

En mi programa, necesito determinar un Id. De estado para otra tabla, o posiblemente actualizar un registro con un nuevo Id. De estado.

Podría codificar los identificadores de estado en una enumeración y espero que nadie cambie la base de datos. O podría buscar previamente los valores en función de la descripción (por lo tanto, codificar eso ).

¿Cuál sería el enfoque correcto para mantener estos dos, enum y table, sincronizados?

MPelletier
fuente
¿Por qué mantienes las cosas sincronizadas y no sincronizadas? ¡Synch (dilo) es raro!
MrFox
1
@suslik Ambos se pronuncian igual. Sincronizar y sincronizar .
MPelletier
1
Tener una enumeración y la tabla de la base de datos es duplicación. A menos que la tabla de la base de datos sea utilizada por otras aplicaciones, renunciaré a la tabla y solo usaré la enumeración. Si la tabla se usará en varias aplicaciones, cargue los estados de la base de datos en tiempo de ejecución.
Peter Smith el
Depende del contexto. En este caso, al tratarse de valores de flujo de trabajo o de estado de la tarea, preferiría mantenerlos más dinámicos que estáticos, ya que los procesos suelen cambiar; y tienden a cambiar fuera de banda por programas de lanzamiento de software. Por otro lado, si se trata de un servicio estable que es poco probable que se introduzcan nuevos estados o que se eliminen los estados existentes, podría estar más obligado a codificar el enum / desnormalizarlos (dependiendo de cómo se usen los registros más adelante).
JustinC
@PeterSmith La base de datos no puede imponer restricciones si solo están en su enumeración de Java y no en una tabla. Vas a restringir los valores en tu base de datos, ¿no?
David Conrad

Respuestas:

5

Codificaría la enumeración dentro de su programa, ya que sospecho que estos diferentes estados afectan la lógica de sus programas. Si tiene un nuevo estado, ¿cómo se supone que su programa reaccionará a este nuevo estado?

Debido a que la base de datos es parte de su aplicación, no creo que tenga sentido afectar una sin consultar a otra, más o menos.

Mateo
fuente
No se trata tanto de nuevos estados (que definitivamente garantizarían una modificación de la base de datos y del programa), sino de los valores de Id.
MPelletier
2
No veo por qué cambiarías el valor de ID sin cambiar su significado. Este tipo de enumeraciones no se incrementaría automáticamente, y en realidad son solo para facilitar la lectura de las personas que depuran la base de datos, ya que generalmente su aplicación realizará consultas y ya sabría cuál pendingsería la ID . Por supuesto, tener una Statusmesa te da integridad referencial, pero eso es lo que quiero decir.
Mateo
Pues sí, esa es la idea. Pero si configuro los ID en un lugar y en otros, estoy trabajando bajo la suposición de que ambos tienen razón. Es un enlace suelto, ¿no?
MPelletier
3
Hacemos estos supuestos todo el tiempo, si piensa en una definición de tabla, nuestro programa asume que la definición es como tal al escribir una consulta. La Statustabla no debe considerarse dinámica durante el tiempo de ejecución de la aplicación y, por lo tanto, no creo que deba leerla como tal.
Mateo
8

Normalmente cargaría estos datos en un caché estático (generalmente en un HashMap o algo así) cuando se inicia la aplicación. Evita tener que volver a compilar solo porque la enumeración se ha modificado de alguna manera.

FrustratedWithFormsDesigner
fuente
2

Debido a que esos son estados, deben estar codificados en la aplicación para garantizar que ningún cambio en la base de datos corromperá su programa (al menos no fácilmente). Esto es importante porque cada estado que debe agregarse debe codificarse primero y no simplemente agregarse a la base de datos.

Aún debe tener esos valores de estado escritos en la base de datos con sus descripciones correctas en caso de que necesite extraer un informe, por ejemplo.

Por lo general, tengo un pequeño fragmento de código que se conectará a la base de datos y verificará que los estados enumerados en una tabla específica tengan todos los mismos valores de identificación / nombre que he codificado en la memoria. Si no coinciden, abortaré la ejecución del software.

Dependiendo de sus necesidades, es posible que desee implementar comportamientos ligeramente diferentes, pero en general es una buena idea tener esos estados codificados de todos modos.

Alex
fuente
2

Tenemos problemas similares en mi proyecto (código heredado, ¡hurra!) El problema principal es que "las tablas de enumeración nunca cambian" hasta que lo hacen y el código se rompe. Tengo dos estrategias para mitigar hacia las que he estado migrando lentamente.

Primero, y lo mejor, es eliminar las referencias directas a estos valores siempre que sea posible. Siempre pregunte, "¿por qué necesito usar directamente el valor enum?" En muchos casos, esto es una señal de que el código tiene demasiados supuestos codificados o está tratando de manipular demasiado los datos. Vea si no puede establecer mejores relaciones en la base de datos o un código más flexible para manejar lo que se está manipulando.

Cuando eso no funciona, voy al plan B: generación de código. Dado que las tablas cambian con poca frecuencia y publicamos nuevas compilaciones regularmente, un generador de código puede leer las tablas de enumeración y escribir el código de enumeración. Esta biblioteca generada dinámicamente se utiliza en el proyecto. Si la base de datos cambia, la próxima compilación no se compilará, lo cual es mucho mejor que obtener misteriosos errores de tiempo de ejecución.

CodexArcanum
fuente
¿Cómo eliminarías las referencias a una enumeración? Por ejemplo, está ordenando o buscando por un estado en este caso. Tener algún valor mágico en el DB tampoco me sienta bien. Para eso están las tablas de búsqueda.
nportelli
En el pasado, he hecho lo contrario. Siempre que hay un cambio de código en Enum, en el arranque de la aplicación, sincroniza esos valores con la Base de datos. Aquí el código es la fuente de la verdad. La base de datos es una representación de ella. Por lo general, ignoro los valores en DB que el código no puede comprender, pero de esta manera, obtengo un mecanismo para limpiar DB automáticamente si es necesario.
Anshul