He visto una serie de preguntas, como esta , pidiendo consejos sobre cómo almacenar enumeraciones en DB. Pero me pregunto por qué harías eso. Entonces, digamos que tengo una entidad Person
con un gender
campo y una Gender
enumeración. Entonces, mi tabla de persona tiene una columna de género.
Además de la razón obvia de forzar la corrección, no veo por qué crearía una tabla adicional gender
para asignar lo que ya tengo en mi aplicación. Y realmente no me gusta tener esa duplicación.
Respuestas:
Tomemos otro ejemplo que esté menos cargado de concepciones y expectativas. Tengo una enumeración aquí, y es el conjunto de prioridades para un error.
¿Qué valor está almacenando en la base de datos?
Por lo tanto, podría estar almacenando
'C'
,'H'
,'M'
, y'L'
en la base de datos. O'HIGH'
y así sucesivamente. Esto tiene el problema de los datos de tipo cadena . Existe un conjunto conocido de valores válidos, y si no está almacenando ese conjunto en la base de datos, puede ser difícil trabajar con él.¿Por qué está almacenando los datos en el código?
Tienes
List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'};
o algo por el estilo en el código. Significa que tiene varias asignaciones de estos datos al formato adecuado (está insertando todas las mayúsculas en la base de datos, pero las está mostrando comoCritical
). Su código ahora también es difícil de localizar. Ha vinculado la representación de la base de datos de la idea a una cadena que se almacena en el código.En cualquier lugar donde necesite acceder a esta lista, debe tener duplicación de código o una clase con un montón de constantes. Ninguno de los cuales son buenas opciones. Tampoco se debe olvidar que hay otras aplicaciones que pueden usar estos datos (que pueden estar escritos en otros idiomas: la aplicación web Java tiene un sistema de informes Crystal Reports utilizado y un trabajo por lotes de Perl que introduce datos). El motor de informes necesitaría conocer la lista válida de datos (¿qué sucede si no hay nada marcado en
'LOW'
prioridad y necesita saber que esa es una prioridad válida para el informe?), Y el trabajo por lotes tendría la información sobre cuál es el valor válido los valores sonHipotéticamente, podría decir "somos una tienda de un solo idioma, todo está escrito en Java" y tenemos un único .jar que contiene esta información, pero ahora significa que sus aplicaciones están estrechamente unidas entre sí y que contiene .jar los datos. Deberá liberar la parte de informes y la parte de actualización por lotes junto con la aplicación web cada vez que haya un cambio, y esperar que esa versión se realice sin problemas para todas las partes.
¿Qué sucede cuando tu jefe quiere otra prioridad?
Tu jefe vino hoy. Hay una nueva prioridad -
CEO
. Ahora tiene que ir y cambiar todo el código y volver a compilar y volver a implementar.Con un enfoque de 'enumeración en la tabla', actualiza la lista de enumeraciones para tener una nueva prioridad. Todo el código que obtiene la lista la extrae de la base de datos.
Los datos rara vez están solos
Con las prioridades, las claves de datos en otras tablas que pueden contener información sobre los flujos de trabajo, o quién puede establecer esta prioridad o no.
Volviendo al género como se menciona en la pregunta por un momento: el género tiene un enlace a los pronombres en uso:
he/his/him
yshe/hers/her
... y desea evitar codificarlo en el propio código. Y luego aparece tu jefe y debes agregar que tienes el'OTHER'
género (para simplificarlo) y debes relacionar este género conthey/their/them
... y tu jefe ve lo que Facebook tiene y ... bueno, sí.Al restringirse a un bit de datos de tipo secuencial en lugar de una tabla de enumeración, ahora necesita replicar esa secuencia en un montón de otras tablas para mantener esta relación entre los datos y sus otros bits.
¿Qué pasa con otros almacenes de datos?
No importa dónde almacene esto, existe el mismo principio.
priorities.prop
que tenga la lista de prioridades. Usted lee esta lista desde un archivo de propiedades.Podría tener una base de datos del almacén de documentos (como CouchDB ) que tenga una entrada para
enums
(y luego escribir una función de validación en JavaScript ):Podría tener un archivo XML con un poco de esquema:
La idea central es la misma. El almacén de datos en sí es donde la lista de valores válidos debe almacenarse y aplicarse. Al colocarlo aquí, es más fácil razonar sobre el código y los datos. No tiene que preocuparse por verificar a la defensiva lo que tiene cada vez (¿en mayúsculas o minúsculas? ¿Por qué hay un
chritical
tipo en esta columna? Etc ...) porque sabe lo que está obteniendo del almacén de datos. exactamente lo que el almacén de datos espera que envíe de lo contrario, y puede consultar el almacén de datos para obtener una lista de valores válidos.La comida para llevar
El conjunto de valores válidos son datos , no códigos. Usted no tiene que luchar por la SECO código - pero la cuestión de la duplicación es que se está duplicando los datos en el código, en lugar de respetar su lugar como los datos y su almacenamiento en una base de datos.
Facilita la escritura de múltiples aplicaciones en el almacén de datos y evita tener instancias en las que necesitará implementar todo lo que esté estrechamente vinculado a los datos en sí, porque no ha acoplado su código a los datos.
Hace que las aplicaciones de prueba sean más fáciles porque no tiene que volver a probar toda la aplicación cuando
CEO
se agrega la prioridad, porque no tiene ningún código que se preocupe por el valor real de la prioridad.Ser capaz de razonar sobre el código y los datos independientemente uno del otro hace que sea más fácil encontrar y corregir errores al realizar tareas de mantenimiento.
fuente
¿Cuál de estos crees que es más probable que produzca errores al leer la consulta?
O
Las personas crean tablas de enumeración en SQL porque consideran que este último es más legible, lo que lleva a menos errores al escribir y mantener SQL.
Podrías hacer que el género sea una cadena directamente
Person
, pero luego tendrías que intentar forzar el caso. También puede aumentar el éxito de almacenamiento para la tabla y el tiempo de consulta debido a la diferencia entre cadenas e enteros, dependiendo de cuán impresionante sea su base de datos para optimizar las cosas.fuente
No puedo creer que la gente no haya mencionado esto todavía.
Llaves extranjeras
Al mantener la enumeración en su base de datos y al agregar una clave externa en la tabla que contiene un valor de enumeración, se asegura de que ningún código ingrese valores incorrectos para esa columna. Esto ayuda a la integridad de sus datos y es la razón más obvia por la que debería tener tablas para enumeraciones.
fuente
Estoy en el campamento que está de acuerdo contigo. Si mantiene una enumeración de género en su código y un tblGender en su base de datos, puede tener problemas en el momento del mantenimiento. Deberá documentar que estas dos entidades deben tener los mismos valores y, por lo tanto, cualquier cambio que realice en uno también debe realizarlo en el otro.
Luego deberá pasar los valores de enumeración a sus procedimientos almacenados de la siguiente manera:
Pero piense cómo haría esto si guardara estos valores en una tabla de base de datos:
Claro que las bases de datos relacionales se crean teniendo en cuenta las uniones, pero ¿qué consulta es más fácil de leer?
Aquí hay otra consulta de ejemplo:
Compare eso con esto:
Aquí hay otra consulta de ejemplo:
Tenga en cuenta que en este ejemplo, tendría que convertir la celda de género en sus resultados de int a enum. Sin embargo, estas conversiones son fáciles. Compare eso con esto:
Todas estas consultas son más pequeñas y más fáciles de mantener cuando se tiene la idea de mantener las definiciones de enumeración fuera de la base de datos.
fuente
Crearía una tabla de Genders por la razón de que puede usarse en el análisis de datos. Podría buscar todas las personas de sexo masculino o femenino en la base de datos para generar un informe. Cuantas más formas pueda ver sus datos, más fácil será descubrir la información de tendencias. Obviamente, esta es una enumeración muy simple, pero para enumeraciones complejas (como los países del mundo, o estados), facilita la generación de informes especializados.
fuente
Primero, debe decidir si la base de datos solo será utilizada por una aplicación o si existe la posibilidad de que varias aplicaciones la usen. En algunos casos, una base de datos no es más que un formato de archivo para una aplicación (las bases de datos SQLite a menudo se pueden usar a este respecto). En este caso, duplicar un poco la definición de enumeración como una tabla a menudo puede estar bien y puede tener más sentido.
Sin embargo, tan pronto como desee considerar la posibilidad de tener múltiples aplicaciones accediendo a la base de datos, entonces una tabla para la enumeración tiene mucho sentido (las otras respuestas explican por qué con más detalle). La otra cosa a considerar es que usted u otro desarrollador quiera ver los datos sin procesar de la base de datos. Si es así, esto puede considerarse otro uso de la aplicación (solo uno donde el medidor de laboratorio es SQL sin formato).
Si tiene la enumeración definida en el código (para un código más limpio y la comprobación del tiempo de compilación), así como una tabla en la base de datos, recomendaría agregar pruebas unitarias para verificar que las dos estén sincronizadas.
fuente
Cuando tiene una enumeración de código que se utiliza para impulsar la lógica de negocios en el código, aún debe crear una tabla para representar los datos en la base de datos por las muchas razones detalladas arriba / abajo. Aquí hay algunos consejos para asegurarse de que sus valores de DB permanezcan sincronizados con los valores del código:
No convierta el campo ID en la tabla en una columna Identidad. Incluir ID y descripción como campos.
Haga algo diferente en la tabla que ayude a los desarrolladores a saber que los valores son semiestáticos / vinculados a una enumeración de código. En todas las demás tablas de búsqueda (generalmente donde los usuarios pueden agregar valores), generalmente tengo un LastChangedDateTime y LastChangedBy, pero no tenerlos en las tablas relacionadas con la enumeración me ayuda a recordar que solo los desarrolladores pueden cambiarlos. Documente esto.
Cree un código de verificación que verifique que cada valor en la enumeración esté en la tabla correspondiente y que solo esos valores estén en la tabla correspondiente. Si tiene "pruebas de estado" automatizadas de aplicaciones que se ejecutan después de la compilación, allí. De lo contrario, haga que el código se ejecute automáticamente al iniciar la aplicación siempre que la aplicación se ejecute en el IDE.
Crear producción entrega scripts SQL que hacen lo mismo, pero desde dentro de la base de datos. Si se crean correctamente, también ayudarán con las migraciones del entorno.
fuente
Depende también de quién acceda a los datos. Si solo tiene una aplicación, puede estar bien. Si agrega en un almacén de datos o un sistema de informes. Tendrán que saber qué significa ese código, cuál es la versión humana del código.
Por lo general, la tabla de tipos no se duplicaría como una enumeración en el código. Puede cargar la tabla de tipos en una lista que se almacena en caché.
A menudo, escribe ir y venir. Necesitaría una fecha para cuando se agregó el nuevo tipo. Sepa cuándo se eliminó un tipo específico. Mostrarlo solo cuando sea necesario. ¿Qué pasa si un cliente quiere "transgénero" como género pero otros clientes no? Toda esta información se almacena mejor en la base de datos.
fuente