Una tarea típica de un programador (o “arquitecto” como se llaman los especialistas en esta tarea) es crear las tablas en una base de datos relacional. En este artículo no quiero hablar de los comandos SQL necesarios para crearlas, sino de las características de las tablas que aparecen a la hora de crear el modelo de datos en la base de datos. En este artículo asumo que el lector ya sabe relacionar objetos del programa con tablas en una base de datos.

En una base de datos nos encontramos típicamente con tablas de las funcionalidades siguientes:

  • Tablas de estado actual. Estas guardan datos parecidos a las variables en un lenguaje de programación.
  • Tablas de entrada y salida. Son tablas que guardan mensajes o trazas y se parecen a ficheros o flujos de datos en un lenguaje de programación.
  • Tablas de historial. En estas tablas guardamos los datos viejos de las tablas de estado o de entrada y salida.
  • Tablas de configuración. Son tablas en que guardamos constantes de enumeración, parámetros de configuración y otros datos, que se suelen cambiar poco o nunca.

Casi todas las tablas en un esquema se dejan clasificar por una de estas categorías y vamos a verlas ahora una en una.

Las tablas de estado actual y las tablas de entrada y salida suelen ser las tablas de “trabajo” ya que contienen la información del procesamiento.

Las tablas del estado actual

Lo que se guarda en una tabla de estado es lo que se guardaría en un objeto variable en un programa. Por eso representan un estado. (Como se puede hacer una correspondencia entre variables y tablas es el tema del artículo “Relación entre objetos y tablas en una base de datos“.)

Igual como las variables en un programa, estas tablas reciben muchas peticiones de lectura y escritura. Por lo tanto importa un acceso rápido. Esto se consigue utilizando una clave primaria numérica y eliminando datos obsoletos que se pueden transferir a tablas de historial.

Las tablas de entrada/salida

Las tablas de entrada y salida son aquellas que de alguna forma guardan mensajes. Se puede utilizar una tabla en la base de datos para enviar mensajes entre varios procesos. Un proceso escribe sus notificaciones y otro los lee y procesa.

A menudo el método que el proceso que lee emplea es un “polling”: comprueba regularmente si ha llegado algún mensaje nuevo con un estado de “no tratado”. Típicamente hay una columna de estado de mensaje en este tipo de tablas. El proceso que escribe pone este estado a “mensaje nuevo” y el que lee les asigna un estado de “tratado”. Por supuesto, se puede evitar este campo de estado si el proceso que lee elimina los mensajes tras tratarlos.

Sin embargo, muchas veces es preferible no borrar datos de una base de datos para facilitar la depuración de errores. Si los mensajes procesados se quedan, todavía se puede averiguar qué información enviaron los procesos entre sí. Si guardo un número de secuencia con cada mensaje, puedo saber en qué orden se han introducido los mensajes. Este número de secuencia puede ser la clave primaria de esta tabla. Se puede omitir el número de secuencia si se guarda la fecha (mejor el timestamp) de creación del mensaje en su lugar. De hecho puede ser recomendable, ya que el timestamp es más informativo e internamente se guarda también como un número. Se puede guardar también la fecha de procesado del mensaje en otra columna para tener la información completa.

Para simplificar el uso de la base de datos, no debería más que un proceso que lee los mensajes de una tabla. Puede haber varios que escriben, pero es recomendable que haya sólo un proceso que escribe y uno que lee. No es costoso crear muchas tablas en un esquema, pero puede ser costoso sacar los mensajes y depurar un fallo cuando sólo hay una tabla de mensajería que actúa como la central nacional de correos.

Es recomendable que los mensaje no estén sobrecargados de información. Si un proceso cambia una tabla de estado basta con notificar con algo como “he hecho algo en la tabla tal” y añadir como mucho la clave primaria en esta tabla. No envíes más datos. El proceso que lee puede hacer su propia consulta a las tablas de estado y obtener toda la información que necesita.

Las trazas de un programa también se pueden guardar en una tabla. En este caso sólo hay un proceso que escribe pero ninguno que lee.

Igual como las tablas de estado, las tablas de entrada y salida suelen tener muchas peticiones de lectura y escritura. Por lo tanto, vale todo lo que ya he mencionado más arriba sobre asuntos de velocidad.

Las tablas de historial

Conviene mantener las tablas de estado y de entrada/salida, es decir, las tablas de “trabajo” con un número de registros reducido, ya que el acceso a sus datos es más rápido cuando menos datos contengan. De otro lado muchas veces se desea guardar los datos antiguos. La solución traen las tablas de historial.

Todos los datos que ya no se necesitan en una tablas de trabajo se pasan a una tabla de historial. Esta tabla suele tener las mismas columnas con los mismos tipos ya que acoge a los mismos datos. Cuando se pasa un registro al historial, se puede borrar en la tabla de trabajo. Hay muchas aplicaciones que todavía permiten visualizar los datos históricos. Por ejemplo, si una tabla de estado contiene las ordenes de compra en curso, la tabla de historial correspondiente contiene las ordenes de compra ya cerradas y permite visualizar estadísticas sobre las ventas en los meses pasados.

No es necesarios pasar los datos de una tabla de trabajo a una tabla de historial justamente después de terminar el trabajo con un registro. Es una tarea que se puede programar una vez al día o una vez al mes en que se pasan todos los registros antiguos de golpe. Por eso las tablas de historial pueden tener pocas pero grandes modificaciones. Por no necesitar un acceso constante, la velocidad no es importante. Algunas bases de datos como Oracle, permiten guardar estas tablas un tablespace diferente.

Las tablas de configuración

Las tablas de configuración contienen parámetros de sólo lectura – aunque una aplicación puede permitir actualizarlos de forma esporádica. Puede ser factible cachear estos datos de configuración en un programa – sobre todo si son muchos y se cambian poco.

Tablas de configuración sustituyen lo que se podría guardar en un fichero “ini”. La ventaja de las tablas es que se guardan todos los datos en un mismo sitio: la base de datos.

A menudo se usan para enlazar identificadores numéricos con un texto descriptivo. Por ejemplo, la tabla de ordenes de trabajo tiene una columna con el estado de la orden. Por ser una tabla de trabajo, la tabla de ordenes sólo guarda un número en el campo de estado, ya que es más rápido que un texto.  En una tabla de configuración se relaciona el número de estado con su significado. Por ejemplo, estado 10 equivale a “en preparación”, estado 20 a “listo para enviar”. Esta construcción permite mantener la velocidad de datos numéricos en las tablas de trabajo pero poder mostrar textos descriptivos al usuario.

Conclusión

Hemos visto diferentes conceptos de uso de tablas de base de datos. Aunque técnicamente la base de datos no distingue estos uso, un programador, sí, puede hacerlo. Puede diferenciarlo por asignar espacio de almacenamiento distinto, por optimizar consultas o por encapsular o cachear la información de forma distinta. Se pueden usar prefijos diferentes como “HIS_” para tablas de históricos para dejar claro de qué tipo de tabla se trata.

A base de las diferentes categorías, se pueden crear clases (abstractas) que se relacionan con uno u otro tipo de tabla. Por ejemplo, una estructura jerárquica como “orden de compra”, “envíos de la orden”, “contenido de los envíos” se parece a una estructura de “paleta”, “caja”, “contenido de caja”: un contenedor que contiene otro contenedor. Cada anidamiento necesita una columna adicional para la clave primaria. Una clase abstracta de “contenedor triple” que usa el nombre de las tablas como parámetro podría cargar la estructura de diferentes datos con el mismo código. Las clases derivadas se ocuparían de extraer los datos particulares de la tabla – dependiendo si es una orden de compra o una paleta de transporte con cajas. Una secuencia SQL modificable podría crear estas estructuras de datos. De esta forma se puede crear código reciclable para varios proyectos.

Y una última nota: Las bases de datos (al menos las de importancia) permiten guardar comentarios descriptivos junto con la definición de las tablas y columnas. Esto es una funcionalidad muy útil ya que permite explicar la utilidad de un campo donde se necesita. Y hay pocos campos que no necesitan una descripción explicativa. Desgraciadamente no se usa esta posibilidad en todos los sitios. Aunque puede ser una alternativa describir los campos en un documento tipo Word, no es tan práctico como guardar el significado directamente en la base de datos. Porque los documentos se pueden perder. Si, en cambio, uno consigue perder la base de datos, las descripciones de los campos van a ser lo de menos.

Referencias

Anuncios