Página principal
Artículos y trucos
Catálogo de productos
Ejemplos y descargas
Mis libros
Cursos de formación
Investigación y desarrollo
Libros recomendados
Mis páginas favoritas
Acerca del autor
 
En colaboración con Amazon
 
Intuitive Sight

El buen uso de las identidades

"En el Mundo Perfecto, Bach seguiría componiendo su Música"
Ian Marteens

Millones de veces he tronado contra el uso insensato de recursos como generadores (InterBase), secuencias (Oracle) y campos de identidad (SQL Server). Repito los motivos:

  • El BDE utiliza normalmente las claves primarias de los registros para identificar las copias que guarda en la caché del cliente con el registro correspondiente del servidor. Si la clave primaria se asigna en el lado del servidor, el BDE puede tener problemas para identificar un registro.

  • La principal ventaja, desde el punto de vista de la implementación del servidor, es que estos recursos no se bloquean durante una transacción, al contrario de lo que sucedería con una tabla de contadores. Pero esto se paga caro, pues matemáticamente es imposible evitar saltos en la secuencia de valores asignados. Por supuesto, existen trucos para que el servidor reasigne valores desperdiciados, especialmente si se trata de SQL Server y las identidades. Sin embargo, estas técnicas no garantizan la secuencialidad en cada instante.

MIRA GESTORUM...

Pero esto no quiere decir que debamos prohibir o desterrar a las identidades de nuestro repertorio de recursos. ¿Sabéis algo de música? El intervalo que existe entre el Fa y el Si natural se conocía en la Edad Media como diabolum, pues corresponde a un sonido aparentemente inarmónico. En el famoso canto gregoriano que da nombre a las notas musicales en Occidente gracias al monje Guido D'Arezzo, cada estrofa comienza con una nota más alta que la anterior, secuencialmente siguiendo la escala. La primera sílaba de la estrofa le da nombre. Y curiosamente, la escala asciende solamente hasta el La natural. Hubiera sido pecado incluir el Si y su disonancia.

Hay un curioso acorde, o conjunto de notas que se pulsan simultáneamente, denominado de séptima disminuida. Puede corresponder a la siguiente combinación: Do, Mi bemol, Fa sostenido, La, Do octava. La particularidad de este acorde es que permite enlazar temas musicales de los más diversos, y sirve de puente entre las más disímiles tonalidades. El gran genio musical de Johann Sebastian Bach fue el primero que aprovechó todas sus posibilidades. Y lo más interesante es que contiene dos intervalos diabólicos en su interior: del Do al Fa sostenido, y del Mi bemol al La natural. Si crees en la Luz, es gracias a la Oscuridad...

ESCALA ASCENDENTE, IDENTIDADES CAMBIANTES

La moraleja de la historia anterior es que no hay recurso de programación malo, sino mal aprovechado. Una buena aplicación de las identidades de SQL Server es con las tablas de apoyo que abundan en todo diseño de base de datos: las tablas de referencia. La estructura típica de estas tablas es la siguiente:


CampoTipo
CódigoINTEGER
DescripciónVARCHAR

El código es un valor interno, que sirve para implementar las claves externas (foreign key). Así que la verdadera clave de la tabla, en el sentido semántico, sería la Descripción. Es posible que, en casos puntuales, existan atributos adicionales en cada fila, pero da lo mismo para la explicación que sigue a continuación.

Supongamos que queremos definir una tabla para almacenar las diferentes formas de pago existentes. La siguiente definición nos serviría:

create table FormasDePago (
    Codigo       int not null identity(1,1),
    Descripcion  varchar(30) not null,

    primary key nonclustered (Codigo),
    unique clustered (Descripcion)
);

Observe que, aunque Código se crea como clave primaria, también se crea una clave única para la Descripción. La propiedad identity, que se asocia a la primera columna, puede utilizarse con tipos numéricos. Estamos indicando que sus valores se asignen a partir de uno, y que aumenten también de uno en uno.

La otra técnica que he aplicado es definir el índice sobre las descripciones mediante la cláusula clustered. Así crearemos un índice agrupado: las filas de las formas de pago se almacenarán de forma ordenada en la base de datos, en un formato similar al de las tablas de Paradox. Con esta técnica, por ejemplo, la ordenación por descripciones se ejecutará muy eficientemente. Como solamente puede haber un índice agrupado por tabla, explícitamente indicamos que la clave primaria no irá agrupada.

COMO HACER QUE TODO FUNCIONE

Para que un mantenimiento sobre este tipo de tablas funcione, hay que tener en cuenta las siguientes recomendaciones:

  • La definición de la tabla no puede contener especificaciones default, ni pueden existir triggers asociados a las operaciones de modificación. Si existen tales definiciones, el BDE intentará releer los registros recién insertados, y tendremos problemas cuando no pueda encontrarlos por culpa del cambio dinámico de la clave primaria. Es evidente que FormasDePago cumple este requisito.

  • En el lado de la aplicación, cuando abrimos un TTable o un TQuery, el conjunto resultado debe estar ordenado por alguna clave alternativa única o casi única. Y también estamos cumpliendo este requisito.

  • Por último, es sumamente conveniente, aunque no necesario, esconder el código de operación de la vista del usuario durante los mantenimientos. La causa es que, a pesar de las precauciones anteriores, cuando insertemos una nueva forma de pago el BDE no se quejará, pero no actualizará el código asignado. Hay programadores que refrescan entonces la tabla, pero esa técnica me parece un desperdicio de las capacidades de la red. Además, ¿no habíamos quedado en que el código era un valor interno? Pues seamos consecuentes.

Si se siguen las recomendaciones anteriores, la ventana de mantenimiento de la tabla de formas de pago contendrá una rejilla con una sola columna. Se pueden arreglar las cosas visualmente para que el usuario tenga la impresión de que está trabajando con una lista de cadenas en un cuadro de listas. Por ejemplo, podemos eliminar los títulos de la rejilla, la columna del indicador y las líneas de separación jugando un poco con la propiedad Options del DBGrid.