Cómo almacenar los estados de los registros (como pendiente, completo, borrador, cancelado ...)

14

Muchas aplicaciones requieren que los registros de sus tablas tengan un estado, como 'completar', 'borrador', 'cancelado'. ¿Cuál es la mejor manera de almacenar estos estados? Para ilustrar a lo que me refiero aquí es un * muy corto) ejemplo.

Tengo una aplicación de blog simple y cada publicación tiene el estado uno de: publicado, borrador o pendiente.

La forma en que lo veo hay 2 formas de modelar esto en la base de datos.

  1. La tabla de publicaciones tiene un campo de texto que incluye el texto de estado.
  2. La tabla de publicación tiene un campo de estado que contiene el ID de un registro en la tabla de estado de seguimiento

El ejemplo de 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 tuvieran en cuenta que la lista de estados podría cambiar en cualquier momento, por lo que se podrían agregar o eliminar más.

¿Puede alguien explicar las ventajas / desventajas de cada uno?

¡Salud!

Mi opción inicial es que es mejor usar otra tabla y buscar el estado como mejor para la normalización y siempre me han enseñado que la normalización es buena para las bases de datos

    
pregunta veganista 14.02.2012 - 15:10

9 respuestas

13

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 utilice constantes o un tipo de enumeración. Esto resultará en 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, entonces use eso. De lo contrario, utilice una restricción para restringir los valores de columna. Tendrá 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 tenga que presentar el estado de forma diferente a diferentes usuarios. Ese es un problema de presentación, que debe resolverse en la capa de presentación, no en la capa de persistencia.

    
respondido por el kevin cline 14.02.2012 - 19:40
7

Almacenar el texto de estado es IMO, no es una buena idea, ya que alguien podría decidir que "completo" debería llamarse "finalizado" en su lugar y luego tienes que actualizar tu base de datos, revisar el 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 bueno. Por otro lado, los códigos numéricos facilitan las comparaciones "mayor que" o "menor que", por ejemplo

select * from myrecords where status < Status.Complete;
    
respondido por el user281377 14.02.2012 - 15:19
4

Las tres reglas de las bases de datos relacionales:

  1. Normalize
  2. Normalize
  3. Normalize

Así que tu pregunta se responde sola. Mantenga el estado dentro de su propia tabla y use GUID / UUIDs como su ID . Los GUIDES indexados son muy rápidos, y solucionan los problemas intrínsecos al incremento de números. Con un ID, puedes hacer cosas geniales, como pedirle a la base de datos todas las publicaciones completadas con el ID, y debido a que estás trabajando dentro del paradigma de db relacional, es muy rápido. Si solo tiene un campo, la base de datos tiene que recorrer cada fila y hacer una comparación de texto, tal vez con munging, y eso es muy lento.

Los nombres de estado de publicación pueden cambiar, más información sobre el estado de publicación puede ir a la tabla, todo funciona si se normaliza .

Por ejemplo, puede agregar niveles de estado como información adicional, lo que permitiría la comparación de municiones menciones. Pero no dependen de la clave para el posicionamiento, lo que permite reorganizar el nivel de estado sin dañar la integridad de DB. También puedes insertar niveles adicionales, lo cual es un gran truco si tienes el nivel asociado a la clave de autoincremento.

    
respondido por el Spencer Rathbun 14.02.2012 - 16:37
2

Sí, debes ir con la opción 2, tener 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 poder agregar o eliminar estados y también los registros existentes permanecerán sin problemas.

    
respondido por el Mr Spark 15.02.2012 - 09:34
1

Me gustaría agregar a las respuestas de otro modo perspicaces que para la normalización completa, un cambio en el estado de una entidad en realidad se modela en una entidad separada, por ejemplo. llamado 'statusChange'.

Necesitaría una unión adicional con la entidad statusChange, pero gana la posibilidad de agregar información adicional, como el actor que realiza el cambio, los posibles comentarios sobre por qué ocurrió el cambio y una fecha en la que se realiza el cambio de status y posiblemente incluso cuando sea efectivo.

    
respondido por el Dibbeke 14.02.2012 - 18:42
0

El uso de texto para el estado en la tabla de registro probablemente no sea una buena idea ya que esto puede cambiar y sería difícil realizar cualquier verificación de integridad de los datos en la inserción / actualización. Si está utilizando un DBMS con un tipo de datos enum, puede usar este en su lugar (el rendimiento probablemente no se verá comprometido ... dependiendo).

Si su estado necesita metadatos (descripción, creados por, nombre descriptivo, ...), deberá almacenar los estados en una tabla separada y tener una clave de estado en su tabla de registros (asegúrese de usar una clave externa) . La identificación no necesariamente tiene que 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 en todos los tipos de registros (tablas), si corresponde. No me preocuparía por los problemas de rendimiento con un 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 tienen una tendencia 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 db.

    
respondido por el smp7d 14.02.2012 - 16:03
0

Depende del propósito del diseño de la base de datos.

Si diseña la base de datos simplemente para que sea compatible con la aplicación (es decir, los objetos (código) son maestros de todos), entonces use una enumeración (o una enumeración de psuedo para las clases que no los admiten) y almacene el nombre del La enumeración es una 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 le obliga a ver los datos sin procesar (que no es tan frecuente si el código realmente gobierna todo). Pero si la enumeración está marcada. Luego, por lo general, almaceno fuera del valor de enumeración (entero).

    
respondido por el ElGringoGrande 14.02.2012 - 20:44
-1

El estado es muy importante, cada vez que obtengas información de publicación, necesitarás obtener su estado o querrás filtrar las publicaciones por estado. Si tiene el estado en otra tabla, deberá hacer uniones para obtener esta información, por lo que el rendimiento se verá comprometido. Definitivamente deberías tener estado en la misma tabla. ¡Y ponerle un índice! Aún puedes usar los enteros como estado, o tal vez enumerar campo.

    
respondido por el dxvargas 14.02.2012 - 15:27
-2

La solución correcta es utilizar un Almacén / 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 una secuencia de mutaciones que evolucionan con el tiempo

    
respondido por el LastTribunal 06.04.2018 - 20:45

Lea otras preguntas en las etiquetas