Muchas aplicaciones requieren registros en sus tablas para tener un estado, como 'completo', 'borrador', 'cancelado'. ¿Cuál es la mejor manera de almacenar estos estados? Para ilustrar lo que estoy llegando aquí es un * muy breve) ejemplo.
Tengo una aplicación de blog simple y cada publicación tiene un estado de: publicado, borrador o pendiente.
A mi modo de ver, hay 2 formas de modelar esto en la base de datos.
- La tabla Publicar tiene un campo de texto que incluye el texto de estado.
- La tabla Post tiene un campo de estado que contiene el ID de un registro en la tabla PostStatus
El ejemplo del blog aquí es un ejemplo muy simple. Donde una enumeración (si es compatible) podría ser suficiente. Sin embargo, me gustaría que las respuestas a la pregunta tengan en cuenta que la lista de estados podría cambiar en cualquier momento, por lo que se podrían agregar o eliminar más.
¿Alguien puede explicar las ventajas / desventajas de cada uno?
¡Salud!
Mi opinión inicial sobre esto es que es mejor usar otra tabla y buscar el estado, ya que es mejor para la normalización y siempre me han enseñado que la normalización es buena para las bases de datos.
fuente
Respuestas:
Almacenar el estado como un índice en otra tabla es una complicación innecesaria. Almacene el estado directamente en la tabla de forma legible. En el código de la aplicación, use constantes o un tipo de enumeración. Esto dará como resultado un código de aplicación más simple y facilitará la depuración de la capa de datos.
Esto no desnormaliza los datos, simplemente cambia la representación. Si la base de datos admite enumeraciones directamente, úsela. De lo contrario, use una restricción para restringir los valores de columna. Va a tener una restricción de cualquier manera: ya sea una restricción directa en los valores de columna o una restricción de clave externa.
Sí, es posible que deba presentar el estado de manera diferente a los diferentes usuarios. Ese es un problema de presentación, que se resolverá en la capa de presentación, no en la capa de persistencia.
fuente
Almacenar el texto de estado es IMO, no es una buena idea, ya que alguien podría decidir que "completo" debería llamarse "terminado" y luego debe actualizar su base de datos, mirar a través del programa si alguien codificó el texto, etc.
Lo que he visto en muchos programas es un código numérico (1 = nuevo, 2 = borrador, 3 = en validación, 4 = completo, 99 = cancelado) o un código alfanumérico corto ("NUEVO", "DRA", "INV "," COM "," CAN "). El último hace que el código (en el programa o en la base de datos) sea más legible para los humanos, lo que generalmente es algo bueno. Por otro lado, los códigos numéricos facilitan hacer comparaciones "mayores que" o "menores que", por ejemplo
fuente
status.draft=Draught
Las tres reglas de las bases de datos relacionales:
Entonces su pregunta se responde sola. Mantenga el estado dentro de su propia tabla y use GUID / UUID como su ID . Los GUID indexados son muy rápidos y solucionan los problemas intrínsecos al incremento de números. Con una identificación, puede hacer cosas interesantes como pedirle a la base de datos todas las publicaciones completadas utilizando la identificación, y debido a que está trabajando dentro del paradigma relacional de db, es muy rápido. Si solo tiene un campo, la base de datos debe recorrer cada fila y hacer una comparación de texto, tal vez con munging, y eso es muy lento.
Los nombres de estado de las publicaciones pueden cambiar, puede encontrar más información sobre el estado de las publicaciones, todo funciona si se normaliza .
Por ejemplo, puede agregar niveles de estado como información adicional, lo que permitiría las menciones de comparación de ammoQ. Pero no dependen de la clave para el posicionamiento, lo que permite reorganizar el nivel de estado sin dañar la integridad de la base de datos. También puede insertar niveles adicionales, lo cual es un buen truco si tiene el nivel asociado a la clave de aumento automático.
fuente
Sí, debe ir con la opción 2, que tiene una tabla PostStatus.
Aparte de todas las ventajas mencionadas en otras respuestas.
Teniendo en cuenta que los estados deben agregarse o eliminarse, puede tener una columna "habilitada" en la tabla PostStatus, por lo que si se elimina el estado marque la columna "habilitada" como "N", de esa manera podrá agregar o eliminar estados y también los registros existentes permanecerán sin problemas.
fuente
Me gustaría agregar a las respuestas perspicaces que para una normalización completa, un cambio en el estado de una entidad se modela en una entidad separada, por ejemplo, llamado 'statusChange'.
Necesitaría una unión adicional con la entidad statusChange, pero tiene la posibilidad de agregar información adicional, como el actor que realiza el cambio, posibles comentarios sobre por qué ocurrió el cambio y una fecha en la que se realiza el statusChange y posiblemente incluso cuando Se vuelve efectivo.
fuente
El uso de texto para el estado en la tabla de registro probablemente no sería una buena idea, ya que esto puede cambiar y sería difícil realizar cualquier verificación de integridad de datos en la inserción / actualización. Si está utilizando un DBMS con un tipo de datos enum, puede usar esto en su lugar (el rendimiento probablemente no se verá comprometido ... dependiendo).
Si su estado necesita algún metadato (descripción, creado por, nombre descriptivo, ...), deberá almacenar los estados en una tabla separada y tener una clave de estado en su tabla de registro (asegúrese de usar una clave externa). La identificación no necesariamente debe ser un número, solo el PK de la tabla de estado. Además, si los estados están en su propia tabla, puede compartirlos entre tipos de registros (tablas) si corresponde. No me preocuparía por problemas de rendimiento con JOIN a la tabla de estado.
Hagas lo que hagas, asegúrate de evitar los estados mágicos (1 para activo, 2 para eliminado, ...). Esto se basa en la documentación y la tradición, que siempre tienden a perderse en una línea de tiempo lo suficientemente grande. Si está utilizando identificadores numéricos, asegúrese de que haya una asociación textual en algún lugar de su base de datos.
fuente
Depende del propósito del diseño de la base de datos.
Si diseña la base de datos simplemente para admitir la aplicación (es decir, los objetos (código) son maestros de todo), entonces usar una enumeración (o una enumeración psuedo para clases que no las admiten) y almacenar el nombre de la enumeración es un buena idea porque aún controla los valores permitidos a través de la enumeración y también hace que la tabla sea un poco más fácil de leer cuando se ve obligado a ver los datos sin procesar (que no es tan frecuente si el código realmente lo gobierna todo). Pero si la enumeración está marcada. Luego, generalmente almaceno el valor de enumeración (entero).
fuente
El estado es muy importante, cada vez que reciba información de la publicación, deberá obtener su estado, o querrá filtrar las publicaciones por estado. Si tiene el estado en otra tabla, deberá hacer uniones para obtener esta información y así el rendimiento se verá comprometido. Definitivamente deberías tener estado en la misma tabla. ¡Y ponle un índice! Todavía puede usar enteros como estado, o tal vez enum field.
fuente
La solución correcta es usar una tienda / fuente de eventos con CQRS o una cadena de bloques. El problema con la captura de eventos en un RDB es que RDB almacena una instantánea de un solo evento en el tiempo, y cosas como "Estados / Estados" son secuencias de mutaciones que evolucionan con el tiempo
fuente