Sei sulla pagina 1di 28

ELIMINACIN DE LA NORMA

Una vez que hemos terminado de desarrollar el modelo de datos para el sistema y que
ste es correcto desde un punto de vista lgico, podemos comenzar con xito el
desarrollo fsico y crear aplicaciones. Sin embargo, no hay que decir que habr que
optimizar el diseo creado para llevar a buen puerto ste objetivo. Tampoco existir
ningn motivo para afirmar que el modelo de datos existente es inadecuado.
Nota: Normalmente, deber mantener su modelo fsico tan cerca como sea posible de su
modelo lgico.
En los ltimos aos de la dcada de los ochenta era muy comn desnormalizar
fuertemente los modelos de datos. Los registros detallados se reorganizaban en registros
maestros, cuyas estructuras se colapsaban en archivos planos, y las estructuras lgicas
limpias y transparentes se convertan en estructuras que resultaban familiares para los
programadores en COBOL/VSAM. Esta forma de proceder era el resultado del elevado
precio de los equipos informticos y de que los mdulos (engine) de las bases de datos
relacionales eran bastantes lentos. Los consultores afirmaban que podan multiplicar por
diez el rendimiento de la base de datos si realizaban una desnormalizacin masiva. La
creencia ms extendida era que los modelos normalizados eran buenos en teora, pero
no funcionaban correctamente en la prctica. La solucin era crear modelos de datos
lgicos normalizados y construir base de datos basadas en archivos planos.
Esta estrategia tuvo resultados desastrosos. Cuando estos sistemas entraron en la fase
productiva, se encontraron con los mismos problemas que tuvieron en los sistemas
tradicionales de archivos planos. Especficamente eran poco flexibles y cualquier
modificacin resultaba extremadamente cara. Si se necesitaba utilizar una funcionalidad
no diseada explcitamente en la base de datos, haca falta realizar modificaciones muy
profundas en la estructura de datos. Hacia finales de 1980, la comunidad de las base de
datos comenz a darse cuenta de su error de diseo. A pesar de que el rendimiento del
sistema mejoraba cuando ste entraba en funcionamiento, el coste de mantener y
modificar estos sistemas era prohibitivo.

Sin embargo se pueden llevar a la prctica cierto tipo de desnormalizacin que no tendr
un impacto muy profundo en la capacidad del sistema para dar respuesta a los futuros
requisitos. En ste captulo analizaremos algunas de las tcnicas de desnormalizacin
mas conocidas que se pueden utilizar sin impactar profundamente en la naturaleza
flexible de un modelo de datos de calidad.
Hay que tener presente que nunca se puede realizar una desnormalizacin sin algn
coste. En la mayora de los casos, cuando se mejora el rendimiento en una parte del
sistema, se degrada en otra parte. La normalizacin es un estilo de de modelizacin que
la mayora de los diseadores de datos tienen bastante claro.
La denormalizacin es un arte idiosincrsico. Cuanto ms estructuras se encuentres
desnormalizadas, ms difcil ser que otros diseadores puedan trabajar con ellas.
Se trata de un problema de extrema gravedad. Los diseadores vienen y van. Contar
con modelos que puedan leer y comprender los futuros diseadores es de trascendental
importancia.
Tampoco se debe tomar a la ligera a la denormalizacin, puede o no mejorar el
rendimiento. Ciertamente, dificultar la lectura del modelo. Salvo que se realice de una
manera muy cuidada, se reducir la flexibilidad del modelo. Entonces. para que
desnormalizar? Hay varias situaciones en las que pueden ser necesarios:

Se puede desnormalizar por razones de rendimiento. Tal ves tenga un modelo de


datos complejo y extremadamente voluminoso con decenas de millones de filas
en sus tablas centrales. En estos casos, puede ocurrir que slo consiga tener un
rendimiento aceptable si desnormaliza.

Se puede desnormalizar para simplificar la lgica de la aplicacin. Puede ser que


para producir un informe determinado o una pantalla se tengan que acceder entre
10 y 20 tablas con el fin de recuperar una determinada pieza de informacin. Si
almacenamos de manera redundante esta informacin en algn lugar de la base
de datos, puede que seamos capaces de reducir enormemente la complejidad de
la lgica de la programacin.

Si desea desnormalizar nicamente por el segundo motivo, siempre deber contemplar


la alternativa de utilizar un avista actualizable en lugar de desnormalizar. En lugar de
crear una columna redundante, cree una vista mostrando dicha columna. Deber
manejar con cuidado las vistas, ya que unirse a las vistas dificulta la puesta a punto de
las consultas. Sin embargo, si puede utilizar una vista simple de una nica tabla, en la
que haya creado todas las columnas adicionales mediante funciones incrustadas. Podra
unir a la vista cualquier columna sin funcin sin que apenas se produjera un impacto
apreciable en el rendimiento, salvo el lgico referido a la ejecucin de la funcin.
Utilizar vistas basadas en varias tablas suele, con frecuencia, dificultar al mximo en
anlisis de la tabla completa. En cualquier caso, se podr seguir una estrategia si el
objetivo final es simplificar la lgica de la aplicacin. Si puede alcanzar un rendimiento
adecuado con las vistas, utilcelas, actuando as no complicar demasiado el modelo de
datos.
Para desnormalizar, se crean con frecuencia atributos redundantes. Un atributo
redundante es una funcin de otros objetos existentes en una clase de objetos, dentro de
la base de datos. Un ejemplo de sta situacin sera aadir un Precio extendido que
fuera igual a Cantidad existente x Precio existente. Otro ejemplo es un MAYS
(nombre) donde se almacenan redundantemente las letras maysculas de un nombre.
Se trata de una tcnica bastante comn y se utiliza para poder ejecutar consultas que no
distinguen en el uso de maysculas y minsculas en el campo del nombre. El motivo de
que no pueda realizar la consulta en tiempo de ejecucin sin ms que introducir
MAYS en el campo es porque poner una funcin en una columna dentro de una
clusula WHERE derrota al ndice. El nico caso en el que se utiliza siempre sta
tcnica es cuando resulte necesario introducir un ndice en la columna redundante.
Tcnicas de desnormalizacin
Hemos identificado 11 tipos de desnormalizacin que resultan necesarios para facilitar
la codificacin o para mejorar el rendimiento. Describiremos cada uno de ellos y
mostraremos ejemplos especficos para ilustrar estas tcnicas.

Campos total redundante


La desnormalizacin ms frecuente es almacenar en una columna detallada, dentro de la
tabla maestra, el toral de una cantidad. Por ejemplo, podr introducir un atributo en una
orden de compra que sea la suma de los detalles. Los datos almacenados en esta
columna debern encontrarse sincronizados bien mediante el uso de desencadenadores
(triggers) que acten sobre la clase de detalle o utilizando programas de mandato
(batch) capaces de actualizar estos valores. Tericamente, estos detalles tambin podran
sincronizarse utilizando cdigo de aplicacin. Sin embrago, esta forma de proceder hace
que el cdigo sea poco estable y no resulta demasiado recomendable.
Si desnormaliza utilizando campos totales redundante, podr ver lo totales sin tener que
realizar la unin en la agregacin. Otra ventaja de esta tcnica es que podr generar un
ndice. Esta forma de proceder resultar de utilidad si desea localizar rdenes de compra
que tengan un tamao que se encuentre comprendido dentro de un determinado rango o
para encontrar las rdenes de compra de mayor o de menor tamao. La nica forma de
evitar el barrido completo de la tabla y el clculo de cada uno de los detalles de la orden
de compra ser mediante la creacin de una columna redundante. Las columnas de este
tipo no solo tendrn que ser simples sumas de los registros detallados. Tambin podra
generar una columna que almacenara la cantidad incluida en una cuenta de cliente, pero
esta forma de proceder exigira un clculo bastante complejo. En general si va a crear
una columna calculada, sta deber encontrarse indexada para que se puedan realizar
consultas sobre ella con gran rapidez.
ATRIBUTOS REDUNDANTES ENLA FILA DE UNA TABLA
Tal y como se comento en la introduccin de este capitulo, para facilitar la bsqueda de
informacin textual se suele crear una columna redundante, que es, simplemente, una
transformacin a maysculas de los datos originales (MAYS).
Este suele ser el procedimiento mas comnmente utilizado. En muy pocos casos, se
trata de un problema difcil de resolver, particularmente cuando se manejan altos
volmenes de datos. Un ejemplo seria la comparacin de direcciones almacenadas en
dos sistemas distintos. En ocasiones, se introducen inadvertidamente espacios en blanco
adicionales entre el nmero y el nombre de la calle o, por ejemplo, se utilizan

abreviaturas de una manera inconsistente. Para resolver este problema se puede utilizar
el siguiente algoritmo.
1.- Convertir la direccin a maysculas.
2.- Eliminar todos los caracteres extraos, tales como tabuladores, espacios, retornos
duros de lnea, signos de puntuacin.
3.- Homogeneizar las abreviaturas de todas las palabras (por ejemplo, Oeste se
convertir en O u Oest).
4.- Sustituir texto del tipo 1 por PRIMERO para crear consistencia.
5.- Coger nicamente los diez primeros caracteres.
Mediante este algoritmo, conseguir comparar de manera bastante fiable las direcciones.
Cuando se tenga que enfrentar con bsquedas de nombres y direcciones en sistemas de
gran tamao, podr almacenar cada palabra en su propia columna e indexar cada
columna para realizar bsquedas eficientes en millones de registros para localizar la
informacin apropiada. Cualquiera de estos mtodos se puede llevar a cabo con
facilidad mediante desencadenadores de la base de datos. El diseador de aplicaciones
slo tendr que utilizar estas columnas en caso necesario. Como las desencadenadores
no necesitan interactuar con el disco, el rendimiento resultante es bastante bueno.
Este mtodo derrocha bastante espacio en el disco. Sin embargo, el cuello de botella de
las aplicaciones no suele encontrarse en el espacio de disco, sino en su rendimiento.
COLUMNAS ADICIONALES DE CLAVES EXTERNAS EN EL LUGAR EL
QUE NO PERTENECEN
Cuando tenga que trabajar con una cadena particularmente larga de relaciones maestro
detalle que se extiende por varias clases de objetos, podr introducir una clave externa o
una referencia a un puntero de objeto desde un extremo de la cadena al otro, tal y como
se muestra en la Figura 18.1.
En este ejemplo queremos realizar bsquedas por nombre en un subconjunto de los
detalles de la reclamacin. Tradicionalmente, deberamos unir tablas para lograr este
objetivo. En cambio, al introducir una referencia de objeto o una clave externa en
Detalle de reclamaciones que apunte a Grupo, podremos recuperar con rapidez los
detalles de la reclamacin que se encuentren asociados con el grupo. Esta introduccin

de columnas redundantes de clave primaria puede simplificar en gran medida la


codificacin de los informes y aplicaciones.
ERD

Detalle
Reclamaciones

Reclamacin

Pliza

Coste

Plan

Grupo

UML
Detalle
Reclamaciones

Reclamacin

Pliza

1
Coste

1
Plan

1
Grupo

Figura 18.1. Estructura que requiere el uso de columnas de clave externa.


COLUMNAS REDUNDANTES PARA EL HISTORICO
Incluso aunque un modelo almacene informacin particular, recuperar esta informacin
puede resultar relativamente difcil. En el diagrama mostrado en la figura 18.2, si
deseamos agregar ventas por departamento, tendremos que unir Ventas a Dep. Slo
cuando la fecha de la transaccin de la venta se encuentre comprendida entre las fechas
inicial y final en las que un determinado empleado se encontraba adscrito a dicho
departamento. Una unin normal contara dos veces todas las ventas cuando un
empleado cambiara de departamento.
Si almacena de forma redundante una referencia a un objeto o una clave externa en la
tabla VENTAS para indicar en que departamento trabajaba el empleado cuando se

efectu dicha venta, entonces resultara sencillo agregar ventas por departamentos. En
ocasiones, podr utilizarse esta tcnica en lugar de tener que analizar la informacin
histrica. En el ejemplo anterior, el nico motivo para tener que analizar la historia del
empleo de un determinado empleado ser para poder asignar el volumen correcto de
ventas al departamento adecuado. Si ste es el nico requisito del sistema, podr
modelizar la relacin tal y como se mue4stra en la Fig 18.3
Si utiliza esta estructura, nunca necesitaremos la clase historia del ejemplo, ya que todas
las relaciones se podrn describir mediante las relaciones adicionales existentes entre
Dep. y Ventas. Tendremos que agregar un desencadenador con el fin de poblar
automticamente la referencia Dep. cada vez que se genere una nueva venta.
Este ejemplo es de gran importancia, ya que demuestra que estamos intentando
encontrar las reglas del sistema que definen nuestro modelo de datos. Como se podr
imaginar, podremos plasmar las mismas reglas del sistema utilizando modelos
diferentes. Sin embargo, una simplificacin de este tipo slo deber realizarse despus
de haber realizado un anlisis profundo. En este caso, no creemos adecuado simplificar
el modelo eliminando la estructura de la historia del Empleo. Para hacerlos, tendr que
estar absolutamente convencido de que el nico motivo para seguir conservando la
historia del empleo es analizar el funcionamiento del departamento mediante la
contabilidad histrica de ventas. Recientemente, trabajamos en un proyecto en el que
deba mantenerse la historia, finalmente, la opinin del cliente fue la que se logr
imponer. Antes de que el sistema llegara a ponerse en marcha, descubrimos que varios
de los informes necesarios no se podan producir de manera segura sin mantener la
historia del empleo.
Nota: El coste asociado con el hecho de tener que modelizar una entidad de manera
ms flexible es, normalmente, mucho menor que el vernos obligados despus a tener
que modificar un sistema completo para acomodar un requisito nuevo o, simplemente,
que fue pasado por alto.

ERD
Departament
o

Historia
del empleo

Venta

Empresa

Historia del empleo


FECHA _ INICIAL
FECHA _ FINAL

Realizado por

Venta

Empresa *

Departamento

Figura 18.2. Estructura que puede utilizar columnas histricas redundantes.

Venta

Empresa

Departamento

UML
Venta

Realizado por

Empresa
Trabaja actualmente para

Acreditado para

Departamento

Figura 18.3. Seguimiento alternativo de la historia.

Nivel de Recursividad
Para ciertas aplicaciones que contengas estructuras recursivas que representan un rbol,
red lista vinculada, etc. Resulta til en que nivel de una jerarqua se encuentra un
determinado registro. Si utiliza CONNECT BY podr conocer el nivel como un valor
almacenado en una columna del sistema. Si no utiliza CONNECT BY o si no ha
comenzado en el nivel superior de la jerarqua, tal ves no resulte posible determinar el
nivel deseado o los niveles devueltos tendrn un elevado grado de inexactitud. La
columna Nivel no resulta necesaria con frecuencia. Sin embrago, puede resultar de
utilidad durante la fase de depuracin de aplicaciones. El desencadenador que se
necesita para mantener esta funcin es barato y ocupa un espacio despreciable.
La existencia de la columna Nivel tambin alerta a los diseadores de la presencia de
una estructura recursiva. Por nuestra parte, recomendamos la inclusin de Nivel como
columna redundante en muchas estructuras recursivas.
Escritura de tablas maestras
Si una clase de generalizacin no es abstracta (es decir, que se haya instanciado en
forma de tabla), no existe manera de determinar con facilidad el tipo de cada registro al
analizar una fila de la tabla de generalizacin. Ser necesario mirar todos los registros
contenidos en cada una de las tablas de especializacin para determinar el lugar en el
que se encuentra un determinado registro. Una solucin a este problema es almacenar el
nombre de la tabla de especializacin aplicable en la generalizacin. De esta forma, tal y
como se encuentra en la figura 18.4 podremos modificar nuestro ejemplo de
generalizacin estndar de los empleados por horas y asalariados.
Utilizando esta estructura, almacenaremos el tipo de empleo (asalariado o por horas) en
la tabla Empleado.

UML

Empleado

Tipo de empleo
1
Consistente con

Asalariado

Por horas
Figura 18.4. Tabla redundante que

muestra la generalizacin.

Redundancia en el Desarrollo COBS


Como mencionamos en el captulo 14, en el desarrollo de objetos complejos (COBS) no
se suelen utilizar columnas redundantes. Podr encontrar ms detalles sobre este tema
en el captulo 16.
Violaciones de la Primera Forma Normal
No recomendamos transgredir la primera forma normal. Sin embargo, hemos
considerado esta posibilidad en diferentes ocasiones. Por ejemplo, imagnese el caso en
que se modeliza un presupuesto con todos sus detalles. Cada detalle del presupuesto
incluye la parte de sus fondos correspondiente a cada uno de los cuatro trimestres. Este
sistema se puede modelizar tal y como se muestra en la figura 18.5.
Si utiliza esta estructura y, adems, las reglas del sistema cambian siempre, y, por otro
lado, se necesitan asignaciones semianuales o mensuales. Habr que modificar el
modelo y todas las aplicaciones. Para modelizar este sistema tal y como se muestra en la
figura 18.6 tendremos que hacer el modelo mas flexible para que pueda trabajar con
prorrateos de presupuestos en cualquier intervalo temporal.
Este tipo de estructura requiere un mayor tiempo de desarrollo y proporciona un menor
rendimiento. Si el rendimiento es un objetivo primario, las circunstancias pueden

justificar la transgresin de la primera forma normal. Recuerde que si utiliza el primer


modelo, nos encontraremos con problemas de gran calibre si, posteriormente, se
necesita realizar alguna modificacin.

UML

ERD

Detalle
Presupuesto.

Detalle
presupuesto

Trimestre 1
Trimestre 2
Trimestre 3
Trimestre 4

Presupuesto

Presupuesto
Figura 18.5 de la Primera Forma Normal.

Detalle
presupuesto

ERD

Prorrateo
Detalle presupuesto

Presupuest
o

UML
Prorrateo
Detalle presupuesto

Detalle presupuesto

FECHA _ INICIO
FECHA _ FINAL

1
Presupuesto

Figura 18.6. Presupuesto flexible.

Columnas Sobrecargadas
Sobrecargar columnas puede disminuir el nmero de atributos que se deben mantener en
una tabla. No recomendamos el empleo de esta estrategia.
Nota.- Es importante que cada atributo almacene uno y slo un tipo de informacin.

Las nicas excepciones a esta regla pueden ocurrir en modelizaciones genricas en las
que se utilice columnas del tipo valor. Cada vez que se almacenen diferentes tipos de
informacin en la misma columna, inevitablemente surgen los problemas. Un ejemplo
de las dificultades que se presentan cuando utilizan columnas sobrecargadas ocurre en
un sistema de control de contratos. A nivel detalle, los contratos se descomponen en
materiales y trabajo. A nivel material, los fabricantes ofertan un precio para los
materiales necesitados. El precio del trabajo se encuentra fijado y los fabricantes
facturan el nmero de horas de trabajo que han sido necesarias. A nivel factura, el
vendedor factura un nmero que representa una cantidad de dinero o el nmero de otras
que han sido necesarias dependiente de lo que se est facturando. Esta forma de
modelizar la estructura disminuye en una unidad el nmero de atributos que hay que
mantener, pero incrementa en docenas de horas el tiempo de desarrollo de la aplicacin
para manejar este error al sobrecargar una columna. No confunda este error con una
columna utilizada en la generalizacin a nivel clase., que puede ser de mucha ayuda.
Por ejemplo, en un mdulo denominado Demogrfico, los pases se dividen en
subunidades para enviar el correo. Estas subunidades pueden ser estados, provincias o
algn otro tipo de unidad.
Normalmente para manejar esta situacin, existir una nica clase para pases y otra
clase para las subdivisiones del pas que pueden representar un estado, provincia, etc.
En este caso, el atributo nombre de la subdivisin se referir al nombre del estado o
de la provincia. Desde una perspectiva terica, los nombres de estado provienen de un
dominio diferente que los nombres de las provincias, pero ambos se utilizan en la
misma forma. Desde una perspectiva del sistema, ambos nombres son equivalentes. Por
tanto, si el sistema siempre utiliza igual la informacin, estamos ante un caso claro de
empleo de columna sobrecargada. En caso contrario, la columna sobrecargada causar
problemas de manera inevitable en algn instante posterior.
Columnas Multiatributos
Una estrategia utilizada con frecuencia en campos tales como Nmeros de Partes o
Nmeros de contratos es incluir la informacin en la columna. Solo deber utilizar esta
estrategia si la nica actividad que va a realizar con los componentes pertenecientes al
campo es ensamblarlos. Por ejemplo, siempre se almacenarn juntos el ao con un ID

generado por el sistema. Una ves que se instancia el campo nunca se deber alterar los
componentes. Si se cumplen todas estas condiciones, se podrn utilizar las columnas
multiatributos.
Sin embargo, hay que reconocer que esta forma de proceder no es la mejor forma de
modelizar un sistema. La informacin del sistema cambiar de manera inevitable. Es
muy raro que todos los campos mantengan siempre fija la informacin que almacenan.
Tablas Histricas Redundantes
Si estamos intentando controlar la contabilidad almacenada en el libro mayor, la
actividad de una cartera de valores, o contabilizar los gastos de un departamento, el
volumen de estas transacciones suele ser suficientemente elevado y requiere una
estructura muy compleja. Para generar informes, solo tendremos que recoger la
informacin perteneciente al primer nivel de agregacin. Para calcular los gastos totales
o los ingresos obtenidos durante un determinado periodo de tiempo, necesitaremos
agregar todas las transacciones que hayan tenido lugar durante dicho periodo de tiempo.
Resolver un problema de este tipo puede ser un autentico quebradero de cabeza desde
el punto de vista del rendimiento del sistema. Se podra utilizar una tabla redundante
para almacenar la informacin peridica sobre una estructura. Tal y como se muestra
en la figura 18.7, esta estructura incluir una clase compuesta que comtendra toda la
informacin que deseamos supervisar.
Los campos contenidos en la tabla historia son los siguientes:

Fecha del valor (la fecha en la que deseamos analizar la informacin)

Valor actual de la cartera de valores en un determinado da.

Cifras de gastos e ingresos a nivel mensual.

Cifras de gastos e ingresos a nivel anual.

En un lugar de almacenar diariamente los gastos e ingresos, utilizaremos un truco. Si


almacenamos diariamente los gastos y queremos calcular el total de ingresos obtenidos
durante un determinado periodo de tiempo, tendramos que sumar los ingresos diarios
que hubieran tenido lugar durante dicho periodo de tiempo. En lugar de proceder a si,
podemos almacenar de manera acumulativa los ingresos y gastos desde un instante
inicial arbitrario. De esta forma, para determinar

el nmero de ingresos/gastos

producidos en cualquier periodo arbitrario de tiempo, solo tendramos que recuperar


dos registros: el tiempo inicial y final del intervalo. Finalmente, tan solo tendramos que
restar dos valores: esta forma de proceder resulta mucho ms eficaz que sumar los
valores almacenados en todo un rango. Podr utilizar este tipo de tablas histricas para
mejorar en gran medida el rendimiento del sistema y, con frecuencia, puede hacer
innecesario la construccin de un almacn de datos independiente.

ERD
Histori
a
cartera
valores

UML
Historia cartera valores
Fecha valor
Valor de la cartera
Gastos mensuales
Gastos anuales
Gastos acumulados
Revisin mensual
Revisin anual
Revisin acumulada
*
1

Cartera

valores

FIGURA 18.7. Ejemplo de clase compuesta

DESARROLLO FISICO DE LA DESNORMALIZACION


En esta seccin presentaremos ejemplos de las 11 tcnicas de desnormalizacin
descritas anteriormente. La pregunta que siempre habr que tener en la mente cuando
lea esta informacin es si los posibles beneficios obtenidos cuando se desnormaliza
realmente superan al coste aadido debido al esfuerzo adicional de codificacin y

documentacin. Con frecuencia

la desnormalizacin

se

ejecuta para obtener

beneficios en el rendimiento de las funciones de generacin de informes. Sin embrago,


habremos de tener siempre presente que desnormalizacin reduce el rendimiento desde
la perspectiva del proceso de transacciones, de esta forma , habr que evaluar qu es
mejor para nosotros, acelerar la generacin de informes o disminuir el rendimiento de
las transacciones.
Muchas empresas desarrollan un sistema de informacin que contiene una instantnea
(fotografa) de la base de datos de los procesos de transacciones en lnea (OLTP). El
valor de esta instantnea se refresca de forma peridica. Se trata de una buena solucin,
suponiendo que su empresa no necesite conocer realmente la informacin actualizada al
segundo.
El mtodo ideal para realizar la desnormalizacin es utilizando desencadenadores. Si
puede permitirse el lujo de esperar para realizar actualizaciones en modo diferido,
entonces podr desarrollar un OLAP para este tipo de sistemas de informacin y no
tendr

que sacrificar la integridad de su diseo OLTP con el fin de mejorar el

rendimiento de la generacin de informes. En nuestra opinin, no deber


desnormalizarce los sistemas de generacin de informes para mejorar las prestaciones.

Tcnicas de desnormalizacin
Hemos identificado 11 tipos de de desnormalizacin que pueden ser necesarios para
facilitar el cdigo o por motivos de rendimiento. Describiremos cada una de estas
tcnicas y mostraremos ejemplos que harn referencia a las descripciones utilizadas en
primera parte de este capitulo para ilustrarlos.

Campos total redundante


Utilizaremos el escenario definido por las rdenes de compra simple y detallada para
el ejemplo del campo total. Por desgracia, este ejemplo cae en el tema de la tabla de
mutacin, salvo que creemos una tercera que duplique la tabla OC_DTL.
Suponga que queremos obtener cantidades en dlares divididas por segundo por orden
de compra. Podremos satisfacer este requisito aadiendo una columna X-CANT a la

tabla OC. Esta columna se actualizar con el valor total en dlares de la OC si mas que
sumar los valores individuales en dlares de cada OC_DTL asociada con una OC
determinada. Para el presente ejemplo, hemos creado tres tablas OC, OC_DTL y
X_OC_DTLy un desencadenador AIU_X_OC_DTL para la tabla X_OC_DTL, tal y
como se muestra en el cdigo ejemplo18.1

CREATE TABLE OC (
OC_ID
NUMBER (10)
NOTNULL,
DESCR_TXT
VARCHAR2 (100)
NOTNULL,
DIREC_ID_COM_TO NUMBER (10)
NOTNULL,
DIREC_ID_FACT_TO NUMBER (10)
NOTNULL,
CTCT_ID
NUMBER (10)
NOTNULL,
VENDEDOR_ID
NUMBER (10)
NOTNULL,
X_CANT
NUMBER (10,2)
NOTNULL )
/
CREATE TABLE OC_DTL (
OC_ID
NUMBER (10)
NOTNULL,
OC_DTL_ID
NUMBER (10)
NOTNULL,
ARTIC_ID
NUMBER (10)
NOTNULL,
ORDEN_CANT
NUMBER (10,2)
NOTNULL,
ORDEN_PRC
NUMBER (10,2)
NOTNULL )
/
CREATE TABLE X_OC_DTL (
OC_ID
NUMBER (10)
NOTNULL,
OC_DTL_ID
NUMBER (10)
NOTNULL,
ARTIC_ID
NUMBER (10)
NOTNULL,
ORDEN_CANT
NUMBER (10,2)
NOTNULL,
ORDEN_PRC
NUMBER (10,2)
NOTNULL )
/
CREATE TABLE OR REPLACE TRIGGER AIU_OC_DTL
AFTER INSERT OR UPDATE
ON X_OC_DTL
FOR EACH ROW
DECLARE
CURSOR C1 IS
SELECT ORDEN_CANT * ORDEN_PRC X_CANT_OC_DTL
FROM X_OC_DTL
WHERE OC_ID =:NEW.OC_ID;
X_CANT_OC

OC.X_CANT%TYPE :=0;

BEGIN
FOR C1_REC IN C1 LOOP
X_CANT_OC :=X_CANT_OC + C1_REC.X_CANT_OC_DTL;
END LOOP;
UPDATE OC SET X_CANT =X_CANT_OC WHERE OC_ID =:NEW.OC_ID;
END;
/

Cdigo ejemplo 18.1


El principal inconveniente de este caso es que debemos crear una tercera una tercera
tabla, X_OC_DTL, lo que no es muy prctico de cara a la desnormalizacin. El
principal inconveniente es el almacenamiento adicional de una tabla del mismo tamao
que la tabla OC_DTL. Aunque es cierto que el espacio de almacenamiento en disco es
relativamente barato; esta forma de actuar dificulta la administracin del sistema.
Cualquier modificacin a la estructura de la tabla OC_DTL, tambin deber propagarse
ala tabla X_OC_DTL. Podemos evitar el tema de la tabla mutante si calculamos y
actualizamos la OC de cada registro de la aplicacin en lugar d e hacerlo en el servidor.

Empleo de mays. Para el desarrollo de ndices


La comparacin de cadenas de texto es realmente un problema de difcil resolucin.
Cuando se comparan direcciones es fcil encontrarse con distintas variedades de una
misma palabra. Por ejemplo, AVDA, Avda, Avenida, AVENIDA y otras

variaciones adicionales tienen el mismo significado y se refieren a lo mismo, pero las


comparaciones dirn que no, salvo que previamente manipule las cadenas de texto para
mejorar la consistencia.
Utilizar un algoritmo como el que describimos anteriormente en este capitulo tiene
mucho sentido. Analizar cada cadena de texto en busca de entradas comunes y
sustituirles por un formato uniforme permite realizar bsquedas seguras, por desgracia,
las cadenas de texto pueden ser ms complicadas de lo que inicialmente hemos
podido suponer.
Por ejemplo, en la direccin avenida del parque de las avenidas ,120, Madrid, 28027
nos encontramos dos veces con la palabra avenida. Deber ser capaz de identificar el
formato uniformen sus datos de origen antes de intentar encontrar un coincidencia para
poder tener una mnima probabilidad de xito. En otras palabras deber conocer que la
referencia a la calle solo ocurrir en los primeros caracteres de la direccin, o alguna
otra regla similar... en caso contrario, no garantizar que la localizacin se realice de
forma correcta.
Podr llevar acabo esta lgica en un desencadenador en la tabla en la que se almacena
la cadena de texto. Solo interactuar con datos en el registro, por lo que no se
encontrar con el problema de la tabla mutante la siguiente asignacin
:NEW.X_DIR_TXT :=UPPER(cadena _ texto)

Es la parte sencilla de la tarea. La parte complicada es la lgica de bsqueda. No hay


muchas empresas que deseen llevar adelante esta tarea.

Columnas adicionales de claves externas en el lugar al que no


pertenecen
Agregar nuevas claves externas puede, ciertamente aumentar la velocidad en la
elaboracin de informes. El inconveniente es la complejidad aadida del modelo de
datos. El modelo de datos mostrado en la figura 18.1 indica una relacin implcita e ntre
Detalle de Reclamaciones y Grupo mediante Reclamacin, Pliza, Coste y Plan.
Por desgracia, la unin de varias tiende a formar cuello de botella desde el punto de
vista del rendimiento. El cdigo ejemplo 18.2 muestra esta tcnica.

CREATE TABLE GRP (


GRP_ID
NUMBER (10) NOT NULL PRIMARY KEY,
DESCR_TX VARCHAR2 (40) NOT NULL)
/
CREATE TABLE PLAN (
PLAN_ID
NUMBER (10) NOT NULL PRIMARY KEY,
DESCR_TX VARCHAR2 (40) NOT NULL,
GRP_ID
NUMBER (10) NOT NULL
REFERENCES GRP (GRP_ID))
/
CREATE TABLE COSTE (
COSTE_ID NUMBER (10) NOT NULL PRIMARY KEY,
CANT
NUMBER (10,2) NOT NULL,
PLAN_ID
NUMBER (10) NOT NULL
REFERENCES PLAN (PLAN_ID))
/
CREATE TABLE POLIZA (
POLIZA_ID NUMBER (10) NOT NULL PRIMARY KEY,
DESCR_TX VARCHAR2 (40) NOT NULL
COSTE_ID
NUMBER (10) NOT NULL
REFERENCES COSTE (COSTE_ID))
/
CREATE TABLE RECLAM (
RECLAM_ID NUMBER (10) NOT NULL PRIMARY KEY,
PACIENTE_APELL VARCHAR2 (40) NOT NULL,
PACIENTE_NOMBP VARCHAR2 (40) NOT NULL,
POLIZA_ID
NUMBER (10) NOT NULL,
REFERENCES POLIZA (PLIZA _ ID),
CREAR _ FECHA
DATE)
/
CREATE TABLE RECLAM_DTL (
RECLAM_ID NUMBER (10) NOT NULL,
REFERENCES RECLAM (RECLAM_ID),
RECLAM_DTL_ID NUMBER (3) NOT NULL,
DESCR_TX
VARCHAR2 (40),
DIAGNOSIS_CD VARCHAR2 (10),
GPR_ID
NUMBER (10) NOT NULL
REFERENCES GRP (GRP_ID))
/
Podemos evitar la unin de las seis tablas definiendo una clave externa desde
RECLAM_DTL a GRUPO, como demuestran las instrucciones en negrita del Cdigo
ejemplo 18.2

Otra opcin seria convertir al identificador nico de cada una de estas tablas en una
clave concatenada. De esta forma, podr informar de los Detalles de las Reclamaciones
mediante Reclamacin, Pliza, Coste, Plan o Grupo, y su consulta solo tendr que
acceder a Reclamacin Detallada y, opcionalmente, a una o mas de otras tablas, si en la
consulta solicitada se comprueba que solo se podr obtener informacin adicional de
una de estas tablas. El cdigo correspondiente a esta opcin se muestra en el Cdigo
ejemplo 18.3.
CREATE TABLE GRP (
GRP_ID
NUMBER (10) NOT NULL PRIMARY KEY,
DESCR_TX VARCHAR2 (40) NOT NULL)
/
CREATE TABLE PLAN (
PLAN_ID
NUMBER (10) NOT NULL,
DESCR_TX VARCHAR2 (40) NOT NULL,
GRP_ID
NUMBER (10) NOT NULL
REFERENCES GRP (GRP_ID),
PRIMARY KEY (PLAN_ID, GRP_ID))
/
CREATE TABLE COSTE (
COSTE_ID NUMBER (10) NOT NULL,
CANT
NUMBER (10,2) NOT NULL,
PLAN_ID
NUMBER (10) NOT NULL,
GRP_ID
NUMBER (10) NOT NULL,
PRIMARY KEY (COSTE_ID, PLAN_ID, GRP_ID),
FOREING KEY (PLAN_ID, GRP_ID)
REFERENCES PLAN (PLAN_ID, GRP_ID))
/
CREATE TABLE POLIZA (
POLIZA_ID
NUMBER (10) NOT NULL,
DESCR_TX VARCHAR2 (40) NOT NULL,
COSTE_ID
NUMBER (10) NOT NULL,
PLAN_ID
NUMBER (10) NOT NULL,
GRP_ID
NUMBER (10) NOT NULL,
PRIMARY KEY (PLIZA_ID, COSTE_ID, PLAN_ID, GRP_ID),
FOREING KEY (COSTE_ID, PLAN_ID, GRP_ID)
REFERENCES COSTE (COSTE_ID, PLAN_ID, GRP_ID))
/
CREATE TABLE RECLAM (
RECLAM_ID NUMBER (10) NOT NULL,
PACIENTE_APELL VARCHAR2 (40) NOT NULL,
PACIENTE_NOMBP VARCHAR2 (40) NOT NULL,
CREAR _ FECHA
DATE,
POLIZA_ID
NUMBER (10) NOT NULL,

COSTE_ID
NUMBER (10) NOT NULL,
PLAN_ID
NUMBER (10) NOT NULL,
GRP_ID
NUMBER (10) NOT NULL,
PRIMARY KEY (RECLAM_ID,
PLIZA_ID,
COSTE_ID,
PLAN_ID,
GRP_ID),
FOREING KEY (PLIZA_ID,
COSTE_ID,
PLAN_ID,
GRP_ID)
REFERENCES
POLIZA (PLIZA _ ID,
COSTE_ID,
PLAN_ID,
GRP_ID))
/
CREATE TABLE RECLAM_DTL (
RECLAM_ID NUMBER (10) NOT NULL,
RECLAM_DTL_ID NUMBER (3) NOT NULL,
DESCR_TX
VARCHAR2 (40),

DIAGNOSIS_CD VARCHAR2 (10),


POLIZA_ID
NUMBER (10) NOT NULL,
COSTE_ID
NUMBER (10) NOT NULL,
PLAN_ID
NUMBER (10) NOT NULL,
GRP_ID
NUMBER (10) NOT NULL,
PRIMARY KEY (RECLAM_ID,
RECLAM_DTL_ID,
PLIZA _ ID,
COSTE _ ID,
PLAN_ID,
GRP_ID),
FOREING KEY (RECLAM_ID,
PLIZA _ ID,
COSTE _ ID,
PLAN_ID,
GRP_ID),
REFERENCES
RECLAM (RECLAM_ID,
PLIZA _ ID,
COSTE_ID,
PLAN_ID,
GRP_ID))
/

Como puede ver, la concatenacin de claves primarias puede hacer que sus requisitos
de almacenamiento de datos se vayan por las nubes. Realizando un cuidadoso anlisis,
podr determinar la ruta ptima para su proyecto.
Columnas redundantes para el histrico
Podr desarrollar las columnas redundantes para el histrico en la misma forma que
utilizamos la tcnica de la desnormalizacin para las columnas adicionales de claves
externas no necesitara informacin adicional.
Escritura de tablas de detalle
Esta aproximacin es similar a la clave externa adicional y a las columnas redundantes
para las tcnicas del historial, aunque en este caso una clave externa redundante es una
clave externa de la tabla maestra ( al contrario de ser una clave primaria de la tabla
maestra). De nuevo, esta forma de actuar sirve para facilitar la elaboracin de informes,
aunque dificultara la comprensin del modelo.
Violaciones de la primera forma normal
Violar la primera forma normal implica que esta codificando una regla del sistema que
su empresa suele tener almacenada en la estructura de la base de datos. Una decisin tal
como esta no deber tomarse a la ligera. El cdigo ejemplo 18.4 indica que la actual
estrategia presupuestaria de esta empresa se lleva a cabo por trimestres. Pero que
ocurrir si esta divisin temporal cambia en el futuro? Una modificacin de esta
magnitud exigira cambios sustanciales en la base de datos, en todas las aplicaciones
(por ejemplo, formularios e informes) y en cualquier interfaz que intercambia
informacin con esta base de datos. Estos inconvenientes son lo suficientemente
costosos y no se pueden tomar a la ligera.
CREATE TABLE PRESUP (
PRESUP_ID
NUMBER
(10) NOT NULL,
DESCR_TXT
VARCHAR2 (100) NOT NULL,
CUENT_CD
VARCHAR2 (20) NOT NULL,
/
CREATE TABLE PRESUP_DTL (
PRESUP_ID
NUMBER
(10) NOT NULL,
TRM1_CANT
NUMBER
(10, 2) NOT NULL,
TRM2_CANT
NUMBER
(10, 2) NOT NULL,
TRM3_CANT
NUMBER
(10, 2) NOT NULL,
TRM4_CANT
NUMBER
(10, 2) NOT NULL,
Codigo ejemplo 18.4
Por el contrario podemos llevar a cabo un modelo mas flexible que pueda acomodar con
el tiempo las modificaciones que tengan lugar sobre la estructura del presupuesto. Esta
aproximacin exigir nuevas estructuras de datos que utilizaremos para definir la
estructura presupuestaria.

Columnas sobrecargadas
Para desarrollar el ejemplo de la subdivisin geogrfica tendremos que definir dos
tablas, PAS y ST_PROV, tal y como se muestra en el cdigo ejemplo 18.5.
CREATE TABLE PAS (
PAS_ID
NUMBER (10) NOT NULL PRIMARY KEY,
DESCR_TXT
VARCHAR2 (50) NOT NULL)
/
CREATE TABLE ST_PROV (
PAS_ID
NUMBER (10) NOT NULL
REFERENCES PAS (PAS_ID),
ST_PROV_ID
NUMBER (10) NOT NULL,
DESCR_TXT
VARCHAR2 (50) NOT NULL,
ESTADO_YN
VARCHAR2 (1) NOT NULL)/
Cdigo ejemplo 18.5
La columna DESCR_TXT perteneciente a la tabla DT_PROV almacena los nombres de
estados y provincias. En principio, no est claro que un valor determinado contenido en
la columna DESCR_TXT de la tabla ST_PROV sea un estado o una provincia si no se
consulta tambin el contenido de la columna ESTADO_YN, que indica si un
determinado registro se ha definido como ESTADO O PROVINCIA.
Columnas Multiatributos
Un lugar muy normal en donde ocurre este tipo de desnormalizacin es en el caso de los
identificadores de inventario. En ocasiones, el identificador nico de un elemento se
encuentra almacenado en una nica columna, pero, en realidad, puede descomponerse
en varios componentes, tales como el nmero de almacn, tipo de elemento y nmero de
elemento. En lugar de introducir estos valores de datos distintos en una nica columna,
recomendamos descomponerlos de manera individual. Ciertamente, esta forma de
actuar simplifica la lectura del modelo y los valores se podrn seguir mostrando juntos
para satisfacer las preferencias del usuario, tal y como se muestra en el cdigo ejemplo
18.6.
CREATE TABLE ARTIC (
ARTIC_ID
NUMBER (10) NOT NULL, PRIMARY KEY,

DESCR_TX
VARCHAR2 NOT NULL)
/
INSERT INTO ARTIC (ARTIC_ID, DESCR_TX)
VALUES (0113561111, WIDGET)
/
Cdigo ejemplo 18.6
El cdigo ejemplo 18.6 utiliza la columna ARTIC_ID para almacenar una cadena
combinada que contiene el tipo del elemento (por ejemplo, 011 caracteres 1-3), el
identificador del elemento (por ejemplo, 1111 caracteres 7-10).
Esta forma de actuar presenta un par de problemas. En primer lugar, los usuarios de este
sistema deben saber lo que significa 011, porque el sistema no almacena una
descripcin para este cdigo. En segundo lugar, consultar las ventas de artculos por tipo
de artculo es una tarea que no puede ser indexada, porque tendr que analizar el tipo
empleo de la funcin SUBSTR, que, de manera inherente, ignora los ndices. En tercer
lugar, qu ocurrira si su elemento fuera reclasificado como algn otro tipo de artculo
o fuera almacenado en algn otro almacn en el futuro? Estos cambios exigiran la
actualizacin de la clave primaria, un extremo bastante inconveniente.
La forma ms correcta de trabajar ser normalizar cuando vea este tipo de escenarios y
est convencido de que su estructura puede cambiar y, probablemente pueda, cambiar en
el futuro. Las estructuras mostradas en el Cdigo ejemplo 18.7 seran seguras.

CREATE TABLE ALAC (


ALMAC_CD
VARCGAR2 (4) NOT NULL PRIMARY KEY,
DESCR_TX
VARCHAR (50) NOT NULL)
/
CREATE TABLE ARTIC_TIPO (
ARTIC_TIPO_CD
VARCHAR2 (3) NOT NULL PRIMARY KEY,
DESCR_TX
VARCHAR2 (50))
/
CREATE TABLE ARTIC (
ARTIC_CD
VARCHAR2 (3) NOT NULL,
DESCR_TX
VARCHAR2 (50) NOT NULL,
ALMAC_CD
VARCHAR2 (4) NOT NULL
REFERENCES ALCAM (ALMAC_CD),

ARTIC_TIPO_CD
VARCHAR2 (3) NOT NULL
REFENBRENCES ARTIC_TIPO (ARTIC_TIPO_CD)
/
Cdigo ejemplo 18.7
Este ejemplo, identificara de manera nica los artculos utilizando el cdigo de artculo,
no la combinacin de cdigo de artculo, cdigo de almacn y cdigo de tipo de
artculo. De esta forma, se permitira que el tipo de artculos o el almacn cambien con
el tiempo. Si est convencido que estos valores no van a cambiar con el tiempo, podr
seguir utilizando este diseo y , simplemente, modificar la clave primaria de la tabla
ARTIC para incluir los cdigos de almacn y de tipo de artculo. De esta forma,
obtendr el texto descriptivo de los tipos de almacenes y artculos, y garantizar que la
combinacin de estos tres campos representa un nico artculo.
Naturalmente, existen datos que nunca necesitarn este tipo de descomposicin. El
tpico ejemplo son los cdigos postales. Muchos de nosotros no somos concientes de
que, en la mayora de los pases, el cdigo postal esta realmente formado por varios
cdigos de menor extensin. En realidad, la mayora de nosotros nunca nos hemos
preocupado por este hecho. Lo que realmente interesa en la mayora de los sistemas es
el cdigo postal completo; por tanto, no requiere una normalizacin como suceda en el
ejemplo del artculo que hemos analizado anteriormente.
Conclusin:

Cada uno de los sistemas de desnormalizacin que hemos comentado aqu, con la
excepcin de la primera forma normal (que no se ha recomendado), comienzan con un a
base de datos en la tercera forma normal plenamente normalizada a la que se agrega una
columna redundante. Se trata de un concepto clave para obtener buenos modelos, ya que
ayuda a mantener un esquema conceptualmente claro. Todo lo que hemos tenido que
hacer es agregar al modelo sin sacrificar ni su flexibilidad ni su claridad conceptual.
Agregando trozos que han sido claramente identificados como desnormalizados gracias
a las convenciones de denominacin utilizadas, generando una documentacin
cuidadosa que indiquen de donde vienen dichos campos y plasmando estos mediante
desencadenadores de base de datos, obtendremos lo mejor de ambos mundos: Un
modelo claro y tericamente correcto y un rendimiento adecuado.

Funcionaria siempre esta forma de trabajar? No. Para los grandes sistemas bancarios
de elevado nmero de transacciones, grandes sistemas comerciales al por menor,
sistemas de reservas de lneas areas, o cualquier otro sistema que tenga que almacenar
miles de transacciones por segundo, debern sacrificarse ciertas correcciones tericas
para alcanzar el rendimiento adecuado. Esta forma de proceder deber utilizarse como
ltima alternativa. Los beneficios de un modelo de datos ntido son su facilidad de
mantenimiento y la facilidad con la que los nuevos grupos de diseadores lo entendern.

Potrebbero piacerti anche