Fundamentos de bases de datos (5º ed.) Silberschatz-Korth-Sudarshan_Parte 2

Page 1

476

Capítulo 14

Optimización de consultas

Π nombre_cliente

Π nombre_cliente σ ciudad_sucursal=Arganzuela

σ ciudad_sucursal=Arganzuela sucursal cuenta

impositor

(a) Árbol inicial de la expresión Figura 14.1

sucursal

cuenta

impositor

(b) Árbol transformado de la expresión Expresiones equivalentes.

Para hallar el plan de evaluación de consultas menos costoso el optimizador necesita generar planes alternativos que produzcan el mismo resultado que la expresión dada y escoger el de menor coste. La generación de planes de evaluación de consultas implica tres etapas: (1) la generación de expresiones que sean equivalentes lógicamente a la expresión dada, (2) la estimación del coste de cada plan de evaluación y (3) la anotación de las expresiones alternativas resultantes para generar planes distintos de ejecución. Las etapas (1) y (3) se encuentran entrelazadas en el optimizador de consultas; algunas expresiones se generan y se anotan, luego se generan y se anotan otras expresiones, etc. La etapa (2) se realiza en segundo plano recopilando información estadística sobre las relaciones, tales como sus tamaños y la profundidad de los índices, para hacer una buena estimación del coste de un plan. Para implementar la primera etapa el optimizador de consultas debe generar expresiones equivalentes a la expresión dada. Esto se lleva a cabo mediante las reglas de equivalencia, que especifican el modo de transformar una expresión en otra lógicamente equivalente. Estas reglas se describen en el Apartado 14.2. En el Apartado 14.3 se describe el modo de estimar las estadísticas de los resultados de cada operación en los planes de consultas. El empleo de estas estadísticas con las fórmulas de costes del Capítulo 13 permite estimar los costes de cada operación. Los costes individuales se combinan para determinar el coste estimado de la evaluación de la expresión de álgebra relacional dada, como se indicó previamente en el Apartado 13.7. En el Apartado 14.4 se describe el modo de escoger un plan de evaluación de consultas. Se puede escoger uno basado en el coste estimado de los planes. Dado que el coste es una estimación, el plan seleccionado no es necesariamente el menos costoso; no obstante, siempre y cuando las estimaciones sean buenas, es probable que el plan sea el menos costoso, o no mucho más costoso. Esta optimización, denominada optimización basada en costes, se describe en el Apartado 14.4.2. Finalmente, las vistas materializadas ayudan a acelerar el procesamiento de ciertas consultas. En el Apartado 14.5 se estudia el modo de “mantener” las vistas materializadas (es decir, mantenerlas actualizadas) y la manera de llevar a cabo la optimización de consultas con las vistas materializadas.

14.2 Transformación de expresiones relacionales

Las consultas se pueden expresar de varias maneras diferentes, con costes de evaluación diferentes. En este apartado, en lugar de tomar la expresión relacional original, se consideran expresiones alternativas equivalentes. Se dice que dos expresiones del álgebra relacional son equivalentes si, en cada ejemplar legal de la base de datos, las dos expresiones generan el mismo conjunto de tuplas (recuérdese que un ejemplar legal de la base de datos es la que satisface todas las restricciones de integridad especificadas en el esquema de la base de datos). Obsérvese que el orden de las tuplas resulta irrelevante; puede que las dos expresiones generen las tuplas en órdenes diferentes, pero se considerarán equivalentes siempre que el conjunto de tuplas sea el mismo.

www.detodoprogramacion.com


14.2

Transformación de expresiones relacionales

477

Regla 5 θ

θ

E1

E2

E2

E1

Regla 6.a

E3 E1

E1

E2

E2 Regla 7.a

σθ

Si θ sólo tiene atributos de E1 E1

E3

E2 Figura 14.2

σθ

E2

E1

Representación gráfica de las equivalencias.

En SQL las entradas y las salidas son multiconjuntos de tuplas, y se usa la versión para multiconjuntos del álgebra relacional para evaluar las consultas de SQL. Se dice que dos expresiones de la versión para multiconjuntos del álgebra relacional son equivalentes si en cada base de datos legal las dos expresiones generan el mismo multiconjunto de tuplas. El estudio de este capítulo se basa en el álgebra relacional. Las extensiones a la versión para multiconjuntos del álgebra relacional se dejan al lector como ejercicios. 14.2.1 Reglas de equivalencia

Una regla de equivalencia establece que dos expresiones son equivalentes. Se puede sustituir la primera por la segunda forma, o viceversa, ya que las dos expresiones generan el mismo resultado en cualquier base de datos válida. El optimizador usa las reglas de equivalencia para transformar las expresiones en otras lógicamente equivalentes. A continuación se enumeran varias reglas generales de equivalencia para las expresiones del álgebra relacional. Algunas de las equivalencias relacionadas aparecen en la Figura 14.2. Se usan θ, θ1 , θ2 , etc., para denotar los predicados, L1 , L2 , L3 , etc., para denotar las listas de atributos y E, E1 , E2 , etc. para denotar las expresiones del álgebra relacional. El nombre de relación r no es más que un caso especial de expresión del álgebra relacional y puede usarse siempre que aparezca E. 1. Las operaciones de selección conjuntivas pueden dividirse en una secuencia de selecciones individuales. Esta transformación se denomina cascada de σ. σθ1 ∧θ2 (E) = σθ1 (σθ2 (E)) 2. Las operaciones de selección son conmutativas. σθ1 (σθ2 (E)) = σθ2 (σθ1 (E)) 3. Sólo son necesarias las últimas operaciones de una secuencia de operaciones de proyección, las demás pueden omitirse. Esta transformación también puede denominarse cascada de Π. ΠL1 (ΠL2 (. . . (ΠLn (E)) . . .)) = ΠL1 (E) 4. Las selecciones pueden combinarse con los productos cartesianos y con las reuniones zeta. a. σθ (E1 × E2 ) = E1 1θ E2 . Esta expresión es precisamente la definición de la reunión zeta. b. σθ1 (E1 1θ2 E2 ) = E1 1θ1 ∧θ2 E2

www.detodoprogramacion.com


478

Optimización de consultas

Capítulo 14

5. Las operaciones de reunión zeta son conmutativas. E1 1θ E2 = E2 1θ E1 Realmente, el orden de los atributos es diferente en el término de la derecha y en el de la izquierda, por lo que la equivalencia no se cumple si se tiene en cuenta el orden de los atributos. Se puede añadir una operación proyección a uno de los lados de la equivalencia para reordenar los atributos de la manera adecuada, pero para mayor sencillez se omite la proyección y se ignora el orden de los atributos en la mayor parte de los ejemplos. Recuérdese que el operador de reunión natural es simplemente un caso especial del operador de reunión zeta; por tanto, las reuniones naturales también son conmutativas. 6.

a. Las operaciones de reunión natural son asociativas. (E1 1 E2 ) 1 E3 = E1 1 (E2 1 E3 ) b. Las reuniones zeta son asociativas en el sentido siguiente: (E1 1θ1 E2 ) 1θ2 ∧θ3 E3 = E1 1θ1 ∧θ3 (E2 1θ2 E3 ) donde θ2 implica solamente atributos de E2 y de E3 . Cualquiera de estas condiciones puede estar vacía; por tanto, se deduce que la operación producto cartesiano (×) también es asociativa. La conmutatividad y la asociatividad de las operaciones de reunión son importantes para la reordenación de las reuniones en la optimización de las consultas.

7. La operación selección se distribuye por la operación reunión zeta bajo las dos condiciones siguientes: a. Cuando todos los atributos de la condición de selección θ0 implican únicamente los atributos de una de las expresiones (por ejemplo, E1 ) que se están reuniendo. σθ0 (E1 1θ E2 ) = (σθ0 (E1 )) 1θ E2 b. Cuando la condición de selección θ1 implica únicamente los atributos de E1 y θ2 implica únicamente los atributos de E2 . σθ1 ∧θ2 (E1 1θ E2 ) = (σθ1 (E1 )) 1θ (σθ2 (E2 )) 8. La operación proyección se distribuye entre la operación reunión zeta bajo las condiciones siguientes. a. Sean L1 y L2 atributos de E1 y de E2 , respectivamente. Supóngase que la condición de reunión θ implica únicamente los atributos de L1 ∪ L2 . Entonces, ΠL1 ∪L2 (E1 1θ E2 ) = (ΠL1 (E1 )) 1θ (ΠL2 (E2 )) b. Considérese una reunión E1 1θ E2 . Sean L1 y L2 conjuntos de atributos de E1 y de E2 , respectivamente. Sean L3 los atributos de E1 que están implicados en la condición de reunión θ, pero que no están en L1 ∪ L2 , y sean L4 los atributos de E2 que están implicados en la condición de reunión θ, pero que no están en L1 ∪ L2 . Entonces, ΠL1 ∪L2 (E1 1θ E2 ) = ΠL1 ∪L2 ((ΠL1 ∪L3 (E1 )) 1θ (ΠL2 ∪L4 (E2 ))) 9. Las operaciones de conjuntos unión e intersección son conmutativas. E1 ∪ E2 = E2 ∪ E1 E1 ∩ E2 = E2 ∩ E1 La diferencia de conjuntos no es conmutativa. 10. La unión y la intersección de conjuntos son asociativas. (E1 ∪ E2 ) ∪ E3 = E1 ∪ (E2 ∪ E3 ) (E1 ∩ E2 ) ∩ E3 = E1 ∩ (E2 ∩ E3 )

www.detodoprogramacion.com


14.2

Transformación de expresiones relacionales

479

11. La operación selección se distribuye por las operaciones de unión, intersección y diferencia de conjuntos. σP (E1 − E2 ) = σP (E1 ) − σP (E2 ) De manera parecida, la equivalencia anterior, con − sustituido por ∪ o por ∩ , también es válida. Además, σP (E1 − E2 ) = σP (E1 ) − E2 La equivalencia anterior, con − sustituido por ∩, también es válida, pero no se cumple si − se sustituye por ∪. 12. La operación proyección es distributiva con respecto a la operación unión. ΠL (E1 ∪ E2 ) = (ΠL (E1 )) ∪ (ΠL (E2 )) Ésta es sólo una lista parcial de las equivalencias. En los ejercicios se estudian más equivalencias que implican a los operadores relacionales extendidos, como la reunión externa y la agregación. 14.2.2 Ejemplos de transformaciones

Ahora se mostrará el empleo de las reglas de equivalencia. Se usará el ejemplo del banco con los esquemas de relaciones: Esquema_sucursal = (nombre_sucursal, ciudad_sucursal, activos) Esquema_cuenta = (número_cuenta, nombre_sucursal, saldo) Esquema_impositor = (nombre_cliente, número_cuenta) Las relaciones sucursal, cuenta e impositor son ejemplos de estos esquemas. En el ejemplo del Apartado 14.1 la expresión Πnombre_cliente (σciudad_sucursal = “Arganzuela” (sucursal 1 (cuenta 1 impositor))) se transformaba en la expresión siguiente, Πnombre_cliente ((σciudad_sucursal = “Arganzuela” (sucursal)) 1 (cuenta 1 impositor)) la cual es equivalente a la expresión algebraica original, pero generando relaciones intermedias de menor tamaño. Esta transformación se puede llevar a cabo empleando la regla 7.a. Recuérdese que la regla sólo dice que las dos expresiones son equivalentes; no dice que una sea mejor que la otra. Se pueden usar varias reglas de equivalencia, una tras otra, sobre una consulta o sobre partes de una consulta. Como ejemplo, supóngase que se modifica la consulta original para restringir la atención a los clientes que tienen un saldo superior a 1000 e. La nueva consulta del álgebra relacional es Πnombre_cliente (σciudad_sucursal = “Arganzuela” ∧ saldo >1000 (sucursal 1 (cuenta 1 impositor))) No se puede aplicar el predicado de la selección directamente a la relación sucursal, ya que éste implica atributos tanto de la relación sucursal como de la relación cuenta. No obstante, se puede aplicar antes la regla 6.a (asociatividad de la reunión natural) para transformar la reunión sucursal 1 (cuenta 1 impositor) en (sucursal 1 cuenta) 1 impositor: Πnombre_cliente (σciudad_sucursal = “Arganzuela” ∧ saldo > 1000 ((sucursal 1 cuenta) 1 impositor)) Luego, empleando la regla 7.a, se puede reescribir la consulta como Πnombre_cliente ((σciudad_sucursal = “Arganzuela” ∧ saldo > 1000 (sucursal 1 cuenta)) 1 impositor) Considérese ahora la subexpresión de selección de esta expresión. Empleando la regla 1 se puede dividir la selección en dos, para obtener la subexpresión siguiente: σciudad_sucursal = “Arganzuela” (σsaldo > 1000 (sucursal 1 cuenta))

www.detodoprogramacion.com


480

Capítulo 14

Optimización de consultas

Las dos expresiones anteriores seleccionan tuplas con ciudad_sucursal = “Arganzuela” y saldo > 1000. Sin embargo, la última forma de la expresión ofrece una nueva oportunidad de aplicar la regla 7.a (“llevar a cabo primero las selecciones”), que da lugar a la subexpresión σciudad_sucursal = “Arganzuela” (sucursal) 1 σsaldo > 1000 (cuenta) La Figura 14.3 muestra la expresión inicial y la expresión final después de todas estas transformaciones. También se podría haber usado la regla 7.b para obtener directamente la expresión final, sin usar la regla 1 para dividir la selección en dos selecciones. De hecho, la regla 7.b puede obtenerse de las reglas 1 y 7.a. Se dice que un conjunto de reglas de equivalencia es mínimo si no se puede obtener ninguna regla a partir de una reunión de las demás. El ejemplo anterior muestra que el conjunto de reglas de equivalencia del Apartado 14.2.1 no es mínimo. Se puede generar una expresión equivalente a la original de diferentes maneras; el número de maneras diferentes de generar una expresión aumenta cuando se usa un conjunto de reglas de equivalencia que no es mínimo. Los optimizadores de consultas, por tanto, usan conjuntos mínimos de reglas de equivalencia. Considérese ahora la siguiente forma de la consulta de ejemplo: Πnombre_cliente ((σciudad_sucursal = “Arganzuela” (sucursal) 1 cuenta) 1 impositor) Cuando se calcula la subexpresión (σciudad_sucursal = “Arganzuela” (sucursal) 1 cuenta) se obtiene una relación cuyo esquema es: (nombre_sucursal, ciudad_sucursal, activos, número_cuenta, saldo) Es posible eliminar varios atributos del esquema, forzando las proyecciones de acuerdo con las reglas de equivalencia 8.a y 8.b. Los únicos atributos que se deben conservar son los que aparecen en el resultado de la consulta y los que se necesitan para procesar las operaciones subsiguientes. Al eliminar los atributos innecesarios se reduce el número de columnas del resultado intermedio. Por tanto, se reduce el tamaño del resultado intermedio. En el ejemplo el único atributo que se necesita de la reunión de sucursal y de cuenta es número_cuenta. Por tanto, se puede modificar la expresión hasta Πnombre_cliente ( ( Πn u´ mero_cuenta ((σciudad_sucursal = “Arganzuela” (sucursal)) 1 cuenta)) 1 impositor) La proyección Πn u´ mero_cuenta reduce el tamaño de los resultados de las reuniones intermedias.

Π nombre_cliente

Π nombre_cliente

σ ciudad_sucursal=Arganzuela

^

saldo < 1000

impositor

σ ciudad_sucursal=Arganzuela σsaldo < 1000 sucursal

cuenta

impositor

(a) Árbol inicial de la expresión Figura 14.3

sucursal

cuenta

(b) Árbol tras varias transformaciones Varias transformaciones.

www.detodoprogramacion.com


14.2

Transformación de expresiones relacionales

481

14.2.3 Ordenación de las reuniones

Es importante conseguir una buena ordenación de las operaciones reunión para reducir el tamaño de los resultados temporales; por tanto, la mayor parte de los optimizadores de consultas prestan mucha atención al orden de las reuniones. Como se mencionó en el Capítulo 3 y en la regla de equivalencia 6.a, la operación reunión natural es asociativa. Por tanto, para todas las relaciones r1 , r2 y r3 , (r1 1 r2 ) 1 r3 = r1 1 (r2 1 r3 ) Aunque estas expresiones sean equivalentes, los costes de calcular cada una de ellas pueden ser diferentes. Considérese una vez más la expresión Πnombre_cliente ((σciudad_sucursal = “Arganzuela” (sucursal)) 1 cuenta 1 impositor) Se podría escoger calcular primero cuenta 1 impositor y luego combinar el resultado con σciudad_sucursal = “Arganzuela” (sucursal) Sin embargo, es probable que cuenta 1 impositor sea una relación de gran tamaño, ya que contiene una tupla por cada cuenta. En cambio, σciudad_sucursal = “Arganzuela” (sucursal) 1 cuenta es, probablemente, una relación de pequeño tamaño. Para comprobar que es así, se observa que, dado que el banco tiene un gran número de sucursales ampliamente distribuidas, es probable que sólo una pequeña parte de los clientes del banco tenga cuenta en las sucursales ubicadas en Arganzuela. Por tanto, la expresión anterior da lugar a una tupla por cada cuenta abierta por un residente de Arganzuela. Así, la relación temporal que se debe almacenar es menor que si se hubiera calculado primero cuenta 1 impositor. Hay otras opciones a considerar a la hora de evaluar la consulta. No hay que preocuparse del orden en que aparecen los atributos en las reuniones, ya que resulta sencillo cambiarlo antes de mostrar el resultado. Por tanto, para todas las relaciones r1 y r2 , r1 1 r2 = r2 1 r1 Es decir, la reunión natural es conmutativa (regla de equivalencia 5). Mediante la asociatividad y la conmutatividad de la reunión natural (reglas 5 y 6) se puede considerar reescribir la expresión del álgebra relacional como Πnombre_cliente (((σciudad_sucursal = “Arganzuela” (sucursal)) 1 impositor) 1 cuenta) Es decir, se puede calcular primero (σciudad_sucursal = “Arganzuela” (sucursal)) 1 impositor y, luego, reunir el resultado con cuenta. Obsérvese, no obstante, que no existen atributos en común entre Esquema_sucursal y Esquema_impositor, por lo que la reunión no es más que un producto cartesiano. Si hay s sucursales en Arganzuela e i tuplas en la relación impositor, este producto cartesiano genera s ∗ i tuplas, una por cada par posible de tuplas de impositor y de sucursal (independientemente de si la cuenta de impositor está abierta en la sucursal). Por tanto, parece que este producto cartesiano producirá una relación temporal de gran tamaño. En consecuencia, esta estrategia se rechaza. No obstante, si el usuario ha introducido la expresión anterior, se pueden usar la asociatividad y la conmutatividad de la reunión natural para transformarla en la expresión más eficiente que se usó anteriormente. 14.2.4 Enumeración de expresiones equivalentes

Los optimizadores de consultas usan las reglas de equivalencia para generar de manera sistemática expresiones equivalentes a la expresión de consulta dada. Conceptualmente el proceso se desarrolla de la manera siguiente. Dada una expresión, si alguna subexpresión coincide con el lado izquierdo o derecho de una regla de equivalencia, el optimizador genera una nueva expresión con la subexpresión transformada de modo que coincida con el otro lado de la regla. Este proceso continúa hasta que no se puedan generar expresiones nuevas.

www.detodoprogramacion.com


482

Capítulo 14

Optimización de consultas

El proceso anterior resulta costoso tanto en espacio como en tiempo. Éste es el modo en que se puede reducir los requisitos de espacio: si se genera una expresión E1 a partir de una expresión E2 empleando una regla de equivalencia, E1 y E2 son parecidas en estructura y tienen subexpresiones que son idénticas. Las técnicas de representación de expresiones que permiten que las dos expresiones apunten a las subexpresiones compartidas pueden reducir de manera significativa los requisitos de espacio, y muchos optimizadores de consultas las usan. Además, no siempre resulta necesario generar todas las posibles expresiones con las reglas de equivalencia. Si un optimizador tiene en cuenta las estimaciones de costes, puede que logre evitar el examen de algunas de las expresiones, como se verá en el Apartado 14.4. Se puede reducir el tiempo necesario para la optimización empleando técnicas como éstas. 14.3 Estimación de las estadísticas de los resultados de las expresiones

El coste de cada operación depende del tamaño y de otras estadísticas de sus valores de entrada. Dada una expresión como a 1 (b 1 c), para estimar el coste de combinar a con (b 1 c) hay que hacer estimaciones de estadísticas como el tamaño de b 1 c. En este apartado se relacionarán en primer lugar algunas estadísticas de las relaciones de bases de datos que se almacenan en los catálogos de los sistemas de bases de datos y luego se mostrará el modo de usar las estadísticas para estimar estadísticas de los resultados de varias operaciones relacionales. Algo que quedará claro más adelante en este apartado es que las estimaciones no son muy precisas, ya que se basan en suposiciones que pueden no cumplirse exactamente. El plan de evaluación de consultas que tenga el coste estimado de ejecución más reducido puede, por tanto, no tener el coste real de ejecución más bajo. Sin embargo, la experiencia real ha mostrado que, aunque las estimaciones no sean muy precisas, los planes con los costes estimados más reducidos tienen costes de ejecución reales que, o bien son los más reducidos o bien se hallan cercanos al menor coste real de ejecución. 14.3.1 Información de catálogo

Los catálogos de los SGBD almacenan la siguiente información estadística sobre las relaciones de las bases de datos: • nr , el número de tuplas de la relación r. • br , el número de bloques que contienen tuplas de la relación r. • tr , el tamaño de cada tupla de la relación r en bytes. • fr , el factor de bloqueo de la relación r —es decir, el número de tuplas de la relación r que caben en un bloque. • V (A, r), el número de valores distintos que aparecen en la relación r para el atributo A. Este valor es igual que el tamaño de ΠA (r). Si A es una clave de la relación r, V (A, r) es nr . La última estadística, V (A, r), también puede calcularse para conjuntos de atributos, si se desea, en vez de sólo para atributos aislados. Por tanto, dado un conjunto de atributos, A, V (A, r) es el tamaño de ΠA (r). Si se da por supuesto que las tuplas de la relación r se almacenan físicamente juntas en un archivo, se cumple la ecuación siguiente: » ¼ nr br = fr Las estadísticas sobre los índices, como las alturas de los árboles B+ y el número de páginas hojas de los índices, también se conservan en el catálogo. Por tanto, si se desean conservar estadísticas precisas, cada vez que se modifica una relación también hay que actualizar las estadísticas. Esta actualización supone una sobrecarga sustancial. Por tanto, la

www.detodoprogramacion.com


EstimaciĂłn de las estadĂ­sticas de los resultados de las expresiones

14.3

483

Figura 14.4

Ejemplo de histograma.

mayor parte de los sistemas no actualizan las estadísticas con cada modificación. En lugar de eso, actualizan las estadísticas durante los periodos de poca carga del sistema. En consecuencia, puede que las estadísticas usadas para escoger una estrategia de procesamiento de consultas no sean completamente exactas. Sin embargo, si no se producen demasiadas actualizaciones en los intervalos entre las actualizaciones de las estadísticas, Êstas serån lo bastante precisas como para proporcionar una buena estimación de los costes relativos de los diferentes planes. La información estadística indicada aquí estå simplificada. Los optimizadores reales suelen conservar información estadística adicional para mejorar la precisión de sus estimaciones de costes de los planes de evaluación. Por ejemplo, la mayoría de las bases de datos almacenan la distribución de los valores de cada atributo en forma de histograma: en los histogramas los valores del atributo se dividen en una serie de rangos, y con cada rango el histograma asocia el número de tuplas cuyo valor del atributo se halla en ese rango. En la Figura 14.4 se muestra un ejemplo de histograma para un atributo entero que toma valores en el rango de 1 a 25. Los histogramas usados en los sistemas de bases de datos registran normalmente el número de los valores distintos en cada rango, ademås del número de tuplas con en ese rango. Como ejemplo de histograma, el rango de valores del atributo edad de la relación persona puede dividirse en 0 – 9, 10– 19, . . . , 90 –99 (suponiendo una edad måxima de 99). Con cada rango se almacena un recuento del número de tuplas persona cuyos valores de edad se hallan en ese rango, junto con el número de valores distintos de edad que se encuentran en ese rango. Sin la información del histograma un optimizador tendría que suponer que la distribución de los valores es uniforme; es decir, que cada rango tiene el mismo recuento. Un histograma ocupa muy poco espacio, por lo que los histogramas sobre varios atributos diferentes se pueden almacenar en el catålogo del sistema. En los sistemas de bases de datos se usan varios tipos de histogramas. Por ejemplo, el histograma de equianchura divide el rango de valores en rangos de igual tamaùo, mientras que el histograma de equiprofundidad ajusta las fronteras de los rangos de forma que cada rango tenga el mismo número de valores. 14.3.2 Estimación del tamaùo de la selección

La estimaciĂłn del tamaĂąo del resultado de una operaciĂłn selecciĂłn depende del predicado de la selecciĂłn. En primer lugar se considerarĂĄ un solo predicado de igualdad, luego un solo predicado de comparaciĂłn y, finalmente, combinaciones de predicados. • ĎƒA = a (r): Si se supone una distribuciĂłn uniforme de los valores (es decir, que cada valor aparece con igual probabilidad), se puede estimar que el resultado de la selecciĂłn tiene nr /V (A, r) tuplas, suponiendo que el valor a aparece en el atributo A de algĂşn registro de r. La suposiciĂłn de que el valor a de la selecciĂłn aparece en algĂşn registro suele ser cierta, y las estimaciones de costes suelen hacerla de manera implĂ­cita. No obstante, no suele ser realista suponer que cada valor aparece con igual probabilidad. El atributo nombre_sucursal de la relaciĂłn cuenta es un ejemplo en

www.detodoprogramacion.com


484

Capítulo 14

Optimización de consultas

el que esta suposición no es válida. Hay una tupla de la relación cuenta para cada cuenta. Resulta razonable esperar que las sucursales grandes tengan más cuentas que las pequeñas. Por tanto, algunos valores nombre_sucursal aparecen con mayor probabilidad que otros. Pese al hecho de que la suposición de distribución uniforme no suele ser correcta, resulta una aproximación razonable de la realidad en muchos casos, y ayuda a que la representación siga siendo relativamente sencilla. Si hay disponible un histograma sobre el atributo A, se puede localizar el rango que contiene el valor a y modificar la estimación anterior nr /V (A, r) usando el contador de frecuencia para el rango en lugar de nr , y el número de valores distintos que aparecen en el rango en lugar de V (A, r). • σA≤v (r): Considérese una selección de la forma σA≤v (r). Si el valor real usado en la comparación (v) está disponible en el momento de la estimación del coste, puede hacerse una estimación más precisa. Los valores mínimo y máximo (min(A, r) y max(A, r)) del atributo pueden almacenarse en el catálogo. Suponiendo que los valores están distribuidos de manera uniforme, se puede estimar el número de registros que cumplirán la condición A ≤ v como 0 si v < min(A, r), como nr si v ≥ max(A, r) y como v − min(A, r) nr · max(A, r) − min(A, r) en el resto de los casos. Si hay disponible un histograma sobre el atributo A, se puede obtener una estimación más precisa; se dejan los detalles al lector. En algunos casos, como cuando la consulta forma parte de un procedimiento almacenado, puede que el valor v no esté disponible cuando se optimice la consulta. En esos casos, se supondrá que aproximadamente la mitad de los registros cumplen la condición de comparación. Es decir, se supone que el resultado tiene nr /2 tuplas; la estimación puede resultar muy imprecisa, pero es lo mejor que se puede hacer sin más información. • Selecciones complejas: ¤ Conjunción. Una selección conjuntiva es una selección de la forma σθ1 ∧θ2 ∧···∧θn (r) Se puede estimar el tamaño del resultado de esta selección: para cada θi , se estima el tamaño de la selección σθi (r), denotada por si , como se ha descrito anteriormente. Por tanto, la probabilidad de que una tupla de la relación satisfaga la condición de selección θi es si /nr . La probabilidad anterior se denomina selectividad de la selección σθi (r). Suponiendo que las condiciones sean independientes entre sí, la probabilidad de que una tupla satisfaga todas las condiciones es simplemente el producto de todas estas probabilidades. Por tanto, se estima el número de tuplas de la selección completa como nr ∗

s1 ∗ s2 ∗ · · · ∗ sn nnr

¤ Disyunción. Una selección disyuntiva es una selección de la forma σθ1 ∨θ2 ∨···∨θn (r) Una condición disyuntiva se satisface por la unión de todos los registros que satisfacen las condiciones simples θi . Como anteriormente, admitamos que si /nr denota la probabilidad de que una tupla satisfaga la condición θi . La probabilidad de que la tupla satisfaga la disyunción es, pues, 1 menos la probabilidad de que no satisfaga ninguna de las condiciones: s2 sn s1 ) ∗ (1 − ) ∗ · · · ∗ (1 − ) 1 − (1 − nr nr nr Multiplicando este valor por nr se obtiene el número estimado de tuplas que satisfacen la selección.

www.detodoprogramacion.com


14.3

Estimación de las estadísticas de los resultados de las expresiones

485

¤ Negación. A falta de valores nulos el resultado de una selección σ¬θ (r) es simplemente las tuplas de r que no están en σθ (r). Ya se sabe el modo de estimar el número de tuplas de σθ (r). El número de tuplas de σ¬θ (r) se estima, por tanto, que es n(r) menos el número estimado de tuplas de σθ (r). Se pueden tener en cuenta los valores nulos estimando el número de tuplas para las que la condición θ se evalúa como desconocida, y restar ese número de la estimación anterior que ignora los valores nulos. La estimación de ese número exige conservar estadísticas adicionales en el catálogo. 14.3.3 Estimación del tamaño de las reuniones

En este apartado se verá el modo de estimar el tamaño del resultado de una reunión. El producto cartesiano r × s contiene nr ∗ ns tuplas. Cada tupla de r × s ocupa tr + ts bytes, de donde se puede calcular el tamaño del producto cartesiano. La estimación del tamaño de una reunión natural resulta algo más complicada que la estimación del tamaño de una selección del producto cartesiano. Sean r(R) y s(S) dos relaciones. • Si R ∩ S = ∅, es decir, las relaciones no tienen ningún atributo en común, entonces r 1 s es igual que r × s, y se puede usar la técnica de estimación anterior para los productos cartesianos. • Si R ∩ S es clave de R, entonces se sabe que cada tupla de s se combinará como máximo con una tupla de r. Por tanto, el número de tuplas de r 1 s no es mayor que el número de tuplas de s. El caso de que R ∩ S sea clave de S es simétrico al caso que se acaba de describir. Si R ∩ S forma una clave externa de S, que hace referencia a R, el número de tuplas de r 1 s es exactamente el mismo que el número de tuplas de s. • El caso más difícil es que R∩S no sea clave de R ni de S. En ese caso se supone, como se hizo para las selecciones, que todos los valores aparecen con igual probabilidad. Considérese una tupla t de r y supóngase que R ∩ S = {A}. Se estima que la tupla t produce ns V (A, s) tuplas en r 1 s, ya que este número es el número promedio de tuplas de s con un valor dado para los atributos A. Considerando todas las tuplas de r se estima que hay nr ∗ ns V (A, s) tuplas in r 1 s. Obsérvese que, si se invierten los papeles de r y de s en la estimación anterior, se obtiene una estimación de nr ∗ ns V (A, r) tuplas en r 1 s. Estas dos estimaciones son diferentes si V (A, r) 6= V (A, s). Si esta situación se produce, probablemente haya tuplas pendientes que no participen en la reunión. Por tanto, probablemente la menor de las dos estimaciones sea la más precisa. La estimación anterior del tamaño de la reunión puede ser demasiado elevada si los valores de V (A, r) para el atributo A de r tienen pocas tuplas en común con los valores de V (A, s) para el atributo A de s. No obstante, es improbable que se dé esta situación en la realidad, ya que las tuplas pendientes o bien no existen o sólo constituyen una pequeña fracción de las tuplas, en la mayor parte de las relaciones reales. Lo más importante es que la estimación anterior depende de la suposición de que todos los valores aparecen con igual probabilidad. Hay que usar técnicas más sofisticadas para la estimación del tamaño si esta suposición no resulta válida. Por ejemplo, si se tuviesen histogramas sobre los atributos de la reunión de ambas relaciones, y ambos histogramas tuviesen los mismos rangos, se podría usar la técnica de la estimación anterior en los dos rangos usando el número de filas con valores en el rango en lugar de nr o de ns , y el número de valores distintos en el rango en lugar de V (A, r) o de V (A, s). Después se sumarían las estimaciones de tamaño obtenidas para cada rango para estimar el tamaño total. Como ejercicio, se deja al lector el caso en que ambas

www.detodoprogramacion.com


486

Capítulo 14

Optimización de consultas

relaciones tengan histogramas sobre el atributo de la reunión, pero con rangos diferentes en los histogramas. Se puede estimar el tamaño de una reunión zeta r 1θ s reescribiendo la reunión como σθ (r × s) y empleando las estimaciones de tamaño de los productos cartesianos junto con las estimaciones de tamaño de las selecciones, que se vieron en el Apartado 14.3.2. Para ilustrar todas estas maneras de estimar el tamaño de las reuniones, considérese la expresión: impositor 1 cliente Supóngase que se dispone de la siguiente información de catálogo sobre las dos relaciones: • ncliente = 10.000. • fcliente = 25, lo que implica que bcliente = 10.000/25 = 400. • nimpositor = 5.000. • fimpositor = 50, lo que implica que bimpositor = 5.000/50 = 100. • V (nombre_cliente, impositor) = 2.500, lo que implica que, en promedio, cada cliente tiene dos cuentas. Supóngase también que nombre_cliente de impositor es clave externa de cliente. En el ejemplo de impositor 1 cliente, nombre_cliente de impositor es una clave externa que hace referencia a cliente; por tanto, el tamaño del resultado es exactamente nimpositor , que es 5.000. Calculemos ahora las estimaciones de tamaño de impositor 1 cliente sin usar la información sobre las claves externas. Como V (nombre_cliente, impositor) = 2.500 y V (nombre_cliente, cliente) = 10.000, las dos estimaciones que se consiguen son 5.000 ∗ 10.000/2.500 = 20.000 y 5.000 ∗ 10.000/10.000 = 5.000, y se escoge la menor. En este caso, la menor de las estimaciones es igual que la que se calculó anteriormente a partir de la información sobre las claves externas. 14.3.4 Estimación del tamaño de otras operaciones

A continuación se esbozará el modo de estimar el tamaño de los resultados de otras operaciones del álgebra relacional. • Proyección: El tamaño estimado (número de registros de las tuplas) de una proyección de la forma ΠA (r) es V (A, r), ya que la proyección elimina los duplicados. • Agregación: El tamaño de A GF (r) es simplemente V (A, r), ya que hay una tupla de A GF (r) por cada valor distinto de A. • Operaciones de conjuntos: Si las dos entradas de una operación de conjuntos son selecciones de la misma relación se puede reescribir la operación de conjuntos como disyunciones, conjunciones o negaciones. Por ejemplo, σθ1 (r)∪σθ2 (r) puede reescribirse como σθ1 ∨θ2 (r). De manera parecida, las intersecciones se pueden reescribir como conjunciones y la diferencia de conjuntos empleando la negación, siempre que las dos relaciones que participan en la operación de conjuntos sean selecciones de la misma relación. Luego se pueden usar las estimaciones de las selecciones que impliquen conjunciones, disyunciones y negaciones del Apartado 14.3.2. Si las entradas no son selecciones de la misma relación se estiman los tamaños de esta manera: el tamaño estimado de r ∪ s es la suma de los tamaños de r y de s. El tamaño estimado de r ∩ s es el mínimo de los tamaños de r y de s. El tamaño estimado de r − s es el mismo tamaño de r. Las tres estimaciones pueden ser imprecisas, pero proporcionan cotas superiores para los tamaños. • Reunión externa: El tamaño estimado de r 1 s es el tamaño de r 1 s más el tamaño de r; el de r 1 s es simétrico, mientras que el de r 1 s es el tamaño de r 1 s más los tamaños de r y s. Las tres estimaciones pueden ser imprecisas, pero proporcionan cotas superiores para los tamaños.

www.detodoprogramacion.com


14.4

Elección de los planes de evaluación

487

14.3.5 Estimación del número de valores distintos

Para las selecciones el número de valores distintos de un atributo (o de un conjunto de atributos) A en el resultado de una selección, V (A, σθ (r)), puede estimarse de la manera siguiente: • Si la condición de selección θ obliga a que A adopte un valor especificado (por ejemplo, A = 3), V (A, σθ (r)) = 1. • Si θ obliga a que A adopte un valor de entre un conjunto especificado de valores (por ejemplo, (A = 1∨A = 3∨A = 4)), entonces V (A, σθ (r)) se define como el número de valores especificados. • Si la condición de selección θ es de la forma Aopv, donde op es un operador de comparación, V (A, σθ (r)) se estima que es V (A, r) ∗ s, donde s es la selectividad de la selección. • En todos los demás casos de selecciones se da por supuesto que la distribución de los valores de A es independiente de la distribución de los valores para los que se especifican las condiciones de selección y se usa una estimación aproximada de min min(V (A, r), nσθ (r) ). Se puede obtener una estimación más precisa para este caso usando la teoría de la probabilidad, pero la aproximación anterior funciona bastante bien. Para las reuniones el número de valores distintos de un atributo (o de un conjunto de atributos) A en el resultado de una reunión, V (A, r 1 s), puede estimarse de la manera siguiente: • Si todos los atributos de A proceden de r, V (A, r 1 s) se estima como min(V (A, r), nr1s ), y de manera parecida si todos los atributos de A proceden de s, V (A, r 1 s) se estima que es min(V (A, s), nr1s ). • Si A contiene atributos A1 de r y A2 de s, entonces V (A, r 1 s) se estima como min(V (A1, r) ∗ V (A2 − A1, s), V (A1 − A2, r) ∗ V (A2, s), nr1s ) Obsérvese que algunos atributos pueden estar en A1 y en A2, y que A1 − A2 y A2 − A1 denotan, respectivamente, a los atributos de A que sólo proceden de r y a los atributos de A que sólo proceden de s. Nuevamente, se pueden obtener estimaciones más precisas usando la teoría de la probabilidad, pero las aproximaciones anteriores funcionan bastante bien. Las estimaciones de los distintos valores son directas para las proyecciones: son iguales en ΠA (r) que en r. Lo mismo resulta válido para los atributos de agrupación de las agregaciones. Para los resultados de suma, cuenta y promedio, se puede suponer, por simplificar, que todos los valores agregados son distintos. Para min(A) y max(A), el número de valores distintos puede estimarse como min(V (A, r), V (G, r)), donde G denota los atributos de agrupamiento. Se omiten los detalles de la estimación de los valores distintos para otras operaciones.

14.4 Elección de los planes de evaluación

La generación de expresiones sólo es una parte del proceso de optimización de consultas, ya que cada operación de la expresión puede implementarse con algoritmos diferentes. Por tanto, se necesita un plan de evaluación para definir exactamente el algoritmo que se usará para cada operación y el modo en que se coordinará la ejecución de las operaciones. La Figura 14.5 muestra un plan de evaluación posible para la expresión de la Figura 14.3. Como ya se ha visto, se pueden emplear varios algoritmos diferentes para cada operación relacional, lo que da lugar a planes de evaluación alternativos. Además, hay que tomar decisiones sobre el encauzamiento. En esta figura, los trazos de las operaciones de selección hasta la operación reunión mezcla están marcados como encauzados; el encauzamiento es factible si las operaciones de selección generan sus resultados ordenados según los atributos de reunión. Lo harán si los índices de sucursal y cuenta almacenan los registros con valores iguales de los atributos de índice ordenados por nombre_sucursal.

www.detodoprogramacion.com


488

Capítulo 14

Optimización de consultas

Π nombre_cliente (ordenar para eliminar duplicados)

(reunión por asociación)

(reunión por mezcla) encauzamiento

encauzamiento

σ ciudad_sucursal = Arganzuela

σ saldo < 1000 (usar exploración lineal)

(usar índice 1) sucursal

impositor

cuenta Figura 14.5

Un plan de evaluación.

14.4.1 Interacción de las técnicas de evaluación

Una manera de escoger un plan de evaluación para una expresión de consulta es sencillamente escoger el algoritmo más económico para evaluar cada operación. Se puede escoger cualquier ordenación de las operaciones que asegure que las operaciones ubicadas por debajo en el árbol se ejecuten antes que las operaciones situadas más arriba. Sin embargo, la selección del algoritmo más económico para cada operación no es necesariamente una buena idea. Aunque puede que una reunión por mezcla en un nivel dado resulte más costosa que una reunión por asociación, puede que proporcione un resultado ordenado que haga más económica la evaluación de operaciones posteriores (como la eliminación de duplicados, la intersección u otra reunión por asociación). De manera parecida, puede que una reunión en bucle anidado indexada proporcione oportunidades para el encauzamiento de los resultados de la operación siguiente y, por tanto, puede que resulte útil aunque no sea la manera más económica de llevar a cabo la reunión. Para escoger el mejor algoritmo global hay que considerar incluso los algoritmos no óptimos para cada una de las operaciones. Por tanto, además de considerar las expresiones alternativas de cada consulta, también hay que considerar los algoritmos alternativos para cada operación de cada expresión. Se pueden usar reglas muy parecidas a las reglas de equivalencia para definir los algoritmos que pueden usarse para cada operación, y si su resultado puede encauzarse o se debe materializar. Se pueden usar estas reglas para generar todos los planes de evaluación de consultas para una expresión dada. Dado un plan de evaluación, se puede estimar su coste empleando las estadísticas estimadas mediante las técnicas del Apartado 14.3 junto con las estimaciones de costes de varios algoritmos y métodos de evaluación descritos en el Capítulo 13. Dependiendo de los índices disponibles, ciertas operaciones selección se pueden evaluar sólo con un índice y sin acceder a la relación en sí. Eso sigue dejando el problema de la selección del mejor plan de evaluación de la consulta. Hay dos enfoques generales: el primero busca todos los planes y escoge el mejor de una manera basada en los costes. El segundo usa la heurística para escoger el plan. A continuación se estudiarán los dos enfoques. Los optimizadores de consultas prácticos incorporan elementos de ambos enfoques.

14.4.2 Optimización basada en el coste

Los optimizadores basados en el coste generan una gama de planes de evaluación a partir de la consulta dada empleando las reglas de equivalencia y escogen el de coste mínimo. Para las consultas complejas el número de planes de consulta diferentes que son equivalentes a un plan dado puede ser grande. A modo de ejemplo, considérese la expresión r1 1 r2 1 · · · 1 rn

www.detodoprogramacion.com


14.4

Elección de los planes de evaluación

489

en la que las reuniones se expresan sin ninguna ordenación. Con n = 3, hay 12 ordenaciones diferentes de la mezcla: r1 1 (r2 1 r3 ) r1 1 (r3 1 r2 ) (r2 1 r3 ) 1 r1 r2 1 (r1 1 r3 ) r2 1 (r3 1 r1 ) (r1 1 r3 ) 1 r2 r3 1 (r1 1 r2 ) r3 1 (r2 1 r1 ) (r1 1 r2 ) 1 r3

(r3 1 r2 ) 1 r1 (r3 1 r1 ) 1 r2 (r2 1 r1 ) 1 r3

En general, con n relaciones, hay (2(n − 1))!/(n − 1)! órdenes de reunión diferentes (se deja el cálculo de esta expresión al lector en el Ejercicio 14.10). Para las reuniones que implican números pequeños de relaciones, este número resulta aceptable; por ejemplo, con n = 5, el número es 1.680. Sin embargo, a medida que n se incrementa, este número crece rápidamente. Con n = 7, el número es 665.280; con n = 10, ¡el número es mayor de 17.600 millones! Afortunadamente, no es necesario generar todas las expresiones equivalentes a la expresión dada. Por ejemplo, supóngase que se desea hallar el mejor orden de reunión de la forma (r1 1 r2 1 r3 ) 1 r4 1 r5 que representa todos los órdenes de reunión en que r1 , r2 y r3 se reúnen primero (en algún orden), y el resultado se reúne (en algún orden) con r4 and r5 . Hay doce órdenes de reunión diferentes para calcular r1 1 r2 1 r3 , y otros doce órdenes para calcular la reunión de este resultado con r4 y r5 . Por tanto, parece que hay 144 órdenes de reunión que examinar. Sin embargo, una vez hallado el mejor orden de reunión para el subconjunto de relaciones {r1 , r2 , r3 }, se puede usar ese orden para las reuniones posteriores con r4 and r5 , y se pueden ignorar todos los órdenes de reunión más costosos de r1 1 r2 1 r3 . Por lo que, en lugar de examinar 144 opciones, sólo hace falta examinar 12 + 12 opciones. Usando esta idea se puede desarrollar un algoritmo de programación dinámica para hallar los órdenes de reunión óptimos. Los algoritmos de programación dinámica almacenan los resultados de los cálculos y los vuelven a usar, un procedimiento que puede reducir enormemente el tiempo de ejecución. En la Figura 14.6 aparece un procedimiento recursivo que implementa el algoritmo de programación dinámica. El procedimiento almacena los planes de evaluación que calcula en el array asociado mejorplan, que está indexado por conjuntos de relaciones. Cada elemento del array asociativo contiene dos componentes: el coste del mejor plan de S y el propio plan. El valor de mejorplan[S].coste se supone que se inicializa como ∞ si mejorplan[S] no se ha calculado todavía. El procedimiento comprueba en primer lugar si el mejor plan para calcular la reunión del conjunto de relaciones dado S se ha calculado ya (y se ha almacenado en el array asociativa mejorplan); si es así, devuelve el plan ya calculado. Si S contiene sólo una relación, se registra en mejorplan la mejor forma de acceder a S (teniendo en cuenta las selecciones sobre S, si las hay). Esto puede implicar el uso de un índice para identificar las procedure HallarMejorPlan(S) if (mejorplan[S].coste 6= ∞) /* mejorplan[S] ya se ha calculado */ return mejorplan[S] if (S contiene sólo una relación) establecer mejorplan[S].plan y mejorplan[S].coste en función de la mejor manera de acceder a S else for each subconjunto no vacío S1 de S tal que S1 6= S P1 = HallarMejorPlan(S1) P2 = HallarMejorPlan(S − S1) A = mejor algoritmo para reunir los resultados de P 1 y de P 2 coste = P 1.coste + P 2.coste + coste de A if coste < mejorplan[S].coste mejorplan[S].coste = coste mejorplan[S].plan = “ejecutar P 1.plan; ejecutar P 2.plan; reunir resultados de P 1 y P 2 usando A” return mejorplan[S] Figura 14.6

Algoritmo de programación dinámica para la optimización del orden de la reunión.

www.detodoprogramacion.com


490

Capítulo 14

Optimización de consultas

tuplas, y después buscar las tuplas (conocido frecuentemente como exploración del índice), o explorar la relación completa (conocido frecuentemente como exploración de la relación)1 . En caso contrario, el procedimiento prueba todas las manerasposibles de dividir S en dos subconjuntos disjuntos. Para cada división el procedimiento halla de manera recursiva los mejores planes para cada uno de los dos subconjuntos y luego calcula el coste del plan global usando esa división. El procedimiento escoge el plan más económico de entre todas las alternativas para dividir S en dos conjuntos. El procedimiento almacena el plan más económico y su coste en el array mejorplan y los devuelve. La complejidad temporal del procedimiento puede demostrarse que es O(3n ) (véase el Ejercicio práctico 14.8). En realidad, el orden en que la reunión de un conjunto de relaciones genera las tuplas también es importante para hallar el mejor orden global de reunión, ya que puede afectar al coste de las reuniones posteriores (por ejemplo, si se usa una mezcla). Se dice que un orden determinado de las tuplas es un orden interesante si puede resultar útil para alguna operación posterior. Por ejemplo, la generación del resultado de r1 1 r2 1 r3 ordenado según los atributos comunes con r4 o r5 puede resultar útil, pero generarlo ordenado según los atributos comunes solamente con r1 y r2 no resulta útil. El uso de la reunión por mezcla para calcular r1 1 r2 1 r3 puede resultar más costoso que emplear algún otro tipo de técnica de reunión, pero puede que proporcione un resultado ordenado según un orden interesante. Por tanto, no basta con hallar el mejor orden de reunión para cada subconjunto del conjunto de n relaciones dadas. Por el contrario, hay que hallar el mejor orden de reunión para cada subconjunto para cada orden interesante de la reunión resultante para ese subconjunto. El número de subconjuntos de n relaciones es 2n . El número de criterios de ordenación interesantes no suele ser grande. Así, hay que almacenar alrededor de 2n expresiones de reunión. El algoritmo de programación dinámica para hallar el mejor orden de reunión puede extenderse de manera sencilla para que trabaje con los criterios de ordenación. El coste del algoritmo extendido depende del número de órdenes interesantes para cada subconjunto de relaciones; dado que se ha hallado que este número en la práctica es pequeño, el coste se queda en O(3n ). Con n = 10 este número es de alrededor de 59.000, que es mucho mejor que los 17.600 millones de órdenes de reunión diferentes. Y lo que es más importante, el almacenamiento necesario es mucho menor que antes, ya que sólo hace falta almacenar un orden de reunión por cada orden interesante de cada uno de los 1024 subconjuntos de r1 , . . . , r10 . Aunque los dos números siguen creciendo rápidamente con n, las reuniones que se producen con frecuencia suelen tener menos de diez relaciones y pueden manejarse con facilidad. Se pueden usar varias técnicas para reducir aún más el coste de la búsqueda entre un gran número de planes. Por ejemplo, al examinar los planes para una expresión se puede concluir tras examinar sólo una parte de la expresión si se determina que el plan más económico para esa parte ya resulta más costoso que el plan de evaluación más económico para una expresión completa examinada anteriormente. De manera parecida, supóngase que se determina que la manera más económica de evaluar una subexpresión es más costosa que el plan de evaluación más económico para una expresión completa examinada anteriormente. Entonces, no hace falta examinar ninguna expresión completa que incluya esa subexpresión. Se puede reducir aún más el número de planes de evaluación que hay que considerar completamente llevando a cabo antes una selección heurística de un buen plan y estimando el coste de ese plan. Luego, sólo unos pocos planes competidores necesitarán un análisis completo de los costes. Estas optimizaciones pueden reducir de manera significativa la sobrecarga de la optimización de consultas. Las complejidades de SQL introducen complicaciones para los optimizadores de consultas. El tratamiento de las consultas anidadas se describe brevemente en el Apartado 14.4.4. La optimización descrita anteriormente se concentra en la optimización del orden de la reunión. En cambio, los optimizadores usados en algunos otros sistemas, principalmente en SQL Server de Microsoft, se basan en reglas de equivalencia. La ventaja de usar reglas de equivalencia es que se puede ampliar fácilmente el optimizador con nuevas reglas. Por ejemplo, las consultas anidadas se pueden representar usando constructoras del álgebra relacional extendida, y las transformaciones de las consultas anidadas se pueden expresar como reglas de equivalencia. Para que este enfoque sea eficaz se requieren técnicas 1. Si un índice contiene todos los atributos de la relación que se usan en la consulta, es posible realizar una exploración sólo del índice que recupera los valores de atributo requeridos del índice sin capturar las tuplas reales.

www.detodoprogramacion.com


14.4

Elección de los planes de evaluación

491

eficientes para detectar las derivaciones de duplicados, y una forma de programación dinámica para evitar optimizar de nuevo las mismas subexpresiones. Este enfoque se propuso en el proyecto de investigación Volcano. Véanse las notas bibliográficas para consultar referencias con más información. 14.4.3 Heurísticas de optimización

Un inconveniente de la optimización basada en el coste es el coste de la propia optimización. Aunque el coste de la optimización de las consultas puede reducirse mediante algoritmos inteligentes, el número de planes de evaluación distintos para una consulta puede ser muy grande y buscar el plan óptimo a partir de este conjunto requiere un gran esfuerzo de cómputo. Por ello, muchos sistemas usan la heurística para reducir el coste de la optimización. Un ejemplo de regla heurística es la siguiente regla para la transformación de consultas del álgebra relacional: • Realizar las operaciones de selección tan pronto como sea posible. Los optimizadores heurísticos usan esta regla sin averiguar si se reduce el coste mediante esta transformación. En el primer ejemplo de transformación del Apartado 14.2 se forzó la operación selección en una reunión. Se dice que la regla anterior es heurística porque suele ayudar a reducir el coste, aunque no lo haga siempre. Como ejemplo de dónde puede dar lugar a un incremento del coste, considérese una expresión σθ (r 1 s), donde la condición θ sólo hace referencia a atributos de s. Ciertamente, la selección puede llevarse a cabo antes de la reunión. Sin embargo, si r es tremendamente pequeña comparada con s, y si hay un índice basado en los atributos de reunión de s pero no hay ningún índice basado en los atributos usados por θ, probablemente resulte una mala idea llevar a cabo la selección pronto. Llevar a cabo pronto la selección (es decir, directamente sobre s) exigiría hacer una exploración de todas las tuplas de s. Es posible que resulte más económico calcular la reunión usando el índice y luego rechazar las tuplas que no superen la selección. La operación proyección, como la operación selección, reduce el tamaño de las relaciones. Por tanto, siempre que haya que generar una relación temporal, resulta ventajoso aplicar inmediatamente cuantas proyecciones sea posible. Esta ventaja sugiere un acompañante a la heurística “realizar las selecciones tan pronto como sea posible”: • Realizar las proyecciones tan pronto como sea posible. Suele resultar mejor llevar a cabo las selecciones antes que las proyecciones, ya que las selecciones tienen la posibilidad de reducir mucho el tamaño de las relaciones y permiten el empleo de índices para tener acceso a las tuplas. Un ejemplo parecido al usado para la heurística de selección debería convencer al lector de que esta heurística no siempre reduce el coste. La mayoría de optimizadores de consultas tienen más heurísticas para reducir el coste de la optimización. Por ejemplo, muchos optimizadores de consultas, como el optimizador de System R, no toman en consideración todos los órdenes de reunión, sino que restringen la búsqueda a tipos concretos de órdenes de reunión. El optimizador de System R sólo toma en consideración los órdenes de reunión en que el operando de la derecha de cada reunión es una de las relaciones iniciales r1 , . . . , rn . Estos órdenes de reunión se denominan órdenes de reunión en profundidad por la izquierda. Los órdenes de reunión en profundidad por la izquierda resultan especialmente convenientes para la evaluación encauzada, ya que el operando de la derecha es una relación almacenada y, así, sólo se encauza una entrada por cada reunión. La Figura 14.7 muestra la diferencia entre un árbol de reunión en profundidad por la izquierda y otro que no lo es. El tiempo que se tarda en tomar en consideración todos los órdenes de reunión en profundidad por la izquierda es O(n!), que es mucho menor que el tiempo necesario para tomar en consideración todos los órdenes de reunión. Con el empleo de las optimizaciones de programación dinámica, el optimizador de System R puede hallar el mejor orden de reunión en un tiempo de O(n2n ). Compárese este coste con el tiempo de O(3n ) necesario para hallar el mejor orden de reunión global.

www.detodoprogramacion.com


492

CapĂ­tulo 14

OptimizaciĂłn de consultas

Figura 14.7

Ă rboles de reuniĂłn en profundidad por la izquierda.

El optimizador System R usa la heurĂ­stica para forzar el desplazamiento de las selecciones y de las proyecciones hacia la parte inferior del ĂĄrbol de consultas. El enfoque heurĂ­stico para reducir el coste de la selecciĂłn del orden de reuniĂłn, que se usĂł originalmente en algunas versiones de Oracle, funciona bĂĄsicamente de esta manera: para cada reuniĂłn de grado n toma en consideraciĂłn n planes de evaluaciĂłn. Cada plan usa un orden de reuniĂłn en profundidad por la izquierda, comenzando con una relaciĂłn diferente de las n existentes. La heurĂ­stica crea el orden de reuniĂłn para cada uno de los n planes de evaluaciĂłn seleccionando de manera repetida la “mejorâ€? relaciĂłn que reunir a continuaciĂłn, con base en la clasificaciĂłn de los caminos de acceso disponibles. Se escoge la reuniĂłn en bucle anidado o mezcla-ordenaciĂłn para cada una de las reuniones, en funciĂłn de los caminos de acceso disponibles. Finalmente, la heurĂ­stica escoge uno de los n planes de evaluaciĂłn de manera heurĂ­stica, basada en la minimizaciĂłn del nĂşmero de reuniones de bucle anidado que no tienen disponible un Ă­ndice para la relaciĂłn interna y en el nĂşmero de reuniones por mezcla-ordenaciĂłn. Los enfoques de la optimizaciĂłn de consultas que integran la selecciĂłn heurĂ­stica y la generaciĂłn de planes de acceso alternativos se han adoptado en varios sistemas. El enfoque usado en System R y en su sucesor, el proyecto Starburst, es un procedimiento jerĂĄrquico basado en el concepto de bloques anidados de SQL. Las tĂŠcnicas de optimizaciĂłn basadas en costes aquĂ­ descritas se usan por separado para cada bloque de la consulta. Los optimizadores de varios productos de bases de datos, como DB2 de IBM y Oracle, se basan en este enfoque, con extensiones para tratar otras operaciones como la agregaciĂłn. Para las consultas compuestas de SQL (que usan la operaciĂłn âˆŞ, ∊ o −), el optimizador procesa cada componente por separado y combina los planes de evaluaciĂłn para formar el plan global de evaluaciĂłn. Muchas aplicaciones ejecutan la misma consulta repetidamente pero con diferentes valores de las constantes. Por ejemplo, una aplicaciĂłn bancaria puede ejecutar repetidamente una consulta para hallar las transacciones recientes sobre una cuenta, pero con diferentes valores del nĂşmero de cuenta. Como heurĂ­stica, muchos optimizadores optimizan una vez la consulta con los valores de la primera vez que se emitiĂł, y almacenan en cachĂŠ el plan de la consulta. Cada vez que se ejecuta de nuevo la consulta, quizĂĄs con nuevos valores de las constantes, el plan de la consulta en cachĂŠ se reutiliza (obviamente usando los nuevos valores de las constantes). El plan Ăłptimo para las nuevas constantes puede diferir del plan Ăłptimo para los valores iniciales, pero como heurĂ­stica se reutiliza el plan guardado en la cachĂŠ. Incluso con el uso de la heurĂ­stica la optimizaciĂłn de consultas basada en los costes impone una sobrecarga sustancial al procesamiento de las consultas. No obstante, el coste aĂąadido de la optimizaciĂłn de las consultas basada en los costes suele compensarse con creces por el ahorro en tiempo de ejecuciĂłn de la consulta, que queda dominado por los accesos lentos a los discos. La diferencia en el tiempo de ejecuciĂłn entre un buen plan y uno malo puede ser enorme, lo cual hace que la optimizaciĂłn de las consultas sea esencial. El ahorro conseguido se multiplica en las aplicaciones que se ejecutan de manera regular, en las que se puede optimizar la consulta una sola vez y usarse el plan de consultas seleccionado cada vez que se ejecute la consulta. Por tanto, la mayor parte de los sistemas comerciales incluyen

www.detodoprogramacion.com


14.4

Elección de los planes de evaluación

493

optimizadores relativamente sofisticados. Las notas bibliográficas dan referencias de las descripciones de los optimizadores de consultas de los sistemas de bases de datos reales.

∗∗

14.4.4 Optimización de subconsultas anidadas

SQL trata conceptualmente a las subconsultas anidadas de la cláusula where como funciones que to-

man parámetros y devuelven un solo valor o un conjunto de valores (quizás, un conjunto vacío). Los parámetros son las variables de la consulta del nivel externo que se usan en la subconsulta anidada (estas variables se denominan variables de correlación). Por ejemplo, supóngase que se tiene la consulta siguiente: select nombre_cliente from prestatario where exists (select * from impositor where impositor.nombre_cliente = prestatario.nombre_cliente) Conceptualmente, la subconsulta puede considerarse como una función que toma un parámetro (aquí, prestatario.nombre_cliente) y devuelve el conjunto de todos los impositores con el mismo nombre. SQL evalúa la consulta global (conceptualmente) calculando el producto cartesiano de las relaciones de la cláusula from externa y comprobando luego los predicados de la cláusula where para cada tupla del producto. En el ejemplo anterior, el predicado comprueba si el resultado de la evaluación de la subconsulta está vacío. Esta técnica para evaluar una consulta con una subconsulta anidada se denomina evaluación correlacionada. La evaluación correlacionada no resulta muy eficiente, ya que la subconsulta se evalúa por separado para cada tupla de la consulta del nivel externo. Puede dar lugar a gran número de operaciones aleatorias de E/S a disco. Por tanto, los optimizadores de SQL intentan transformar las subconsultas anidadas en reuniones, siempre que resulta posible. Los algoritmos de reunión eficientes evitan las costosas operaciones aleatorias de E/S. Cuando la transformación no resulta posible el optimizador conserva las subconsultas como expresiones independientes, las optimiza por separado y luego las evalúa mediante la evaluación correlacionada. Como ejemplo de transformación de una subconsulta anidada en una reunión, la consulta del ejemplo anterior puede reescribirse como select nombre_cliente from prestatario, impositor where impositor.nombre_cliente = prestatario.nombre_cliente Para reflejar correctamente la semántica de SQL no debe cambiar el número de derivaciones duplicadas debido a la reescritura; la consulta reescrita puede modificarse para asegurarse de que se cumple esta propiedad, como se verá en breve. En el ejemplo la subconsulta anidada era muy sencilla. En general, puede que no resulte posible desplazar las relaciones de la subconsulta anidada a la cláusula from de la consulta externa. En lugar de eso, se crea una relación temporal que contiene el resultado de la consulta anidada sin las selecciones empleando las variables de correlación de la consulta externa y se reúne la tabla temporal con la consulta del nivel exterior. Por ejemplo, una consulta de la forma select . . . from L1 where P1 and exists (select * from L2 where P2 ) donde P2 es una conjunción de predicados más sencillos, puede reescribirse como

www.detodoprogramacion.com


494

Capítulo 14

Optimización de consultas

create table t1 as select distinct V from L2 where P21 select . . . from L1 , t1 where P1 and P22 donde P21 contiene los predicados de P2 sin las selecciones que implican las variables de correlación, y P22 reintroduce las selecciones que implican las variables de correlación (con las relaciones a que se hace referencia en el predicado renombradas adecuadamente). Aquí V contiene todos los atributos que se usan en las selecciones con las variables de correlación en la subconsulta anidada. En el ejemplo la consulta original se habría transformado en: create table t1 as select distinct nombre_cliente from impositor select nombre_cliente from prestatario, t1 where t1 .nombre_cliente = prestatario.nombre_cliente La consulta que se reescribió para mostrar la creación de relaciones temporales puede obtenerse simplificando la consulta transformada más arriba, suponiendo que el número de duplicados de cada tupla no importa. El proceso de sustituir una consulta anidada por una consulta con una reunión (acaso con una relación temporal) se denomina descorrelación. La descorrelación resulta más complicada cuando la subconsulta anidada usa la agregación o cuando el resultado de la subconsulta anidada se usa para comprobar la igualdad, o cuando la condición que enlaza la subconsulta anidada con la consulta exterior es not exists, etc. No se intentará dar algoritmos para el caso general y, en vez de eso, se remitirá al lector a los elementos de importancia en las notas bibliográficas. La optimización de las subconsultas anidadas complejas es una labor difícil, como puede deducirse del estudio anterior, y muchos optimizadores sólo llevan a cabo una cantidad limitada de descorrelación. Resulta más conveniente evitar el empleo de subconsultas anidadas complejas, siempre que sea posible, ya que no se puede asegurar que el optimizador de consultas tenga éxito en su conversión a una forma que pueda evaluarse de manera eficiente.

∗∗

14.5 Vistas materializadas

Cuando se define una vista, normalmente la base de datos sólo almacena la consulta que define la vista. Por el contrario, una vista materializada es una vista cuyo contenido se calcula y se almacena. Las vistas materializadas constituyen datos redundantes, en el sentido de que su contenido puede deducirse de la definición de la vista y del resto del contenido de la base de datos. No obstante, resulta mucho más económico en muchos casos leer el contenido de una vista materializada que calcular el contenido de la vista ejecutando la consulta que la define. Las vistas materializadas resultan importantes para la mejora del rendimiento de algunas aplicaciones. Considérese esta vista, que da el importe total de los préstamos de cada sucursal: create view total_préstamos_sucursal(nombre_sucursal, total_préstamos) as select nombre_sucursal, sum(importe) from préstamos group by nombre_sucursal

www.detodoprogramacion.com


14.5

Vistas materializadas∗∗

495

Supóngase que el importe total de los préstamos de la sucursal se solicita con frecuencia (antes de conceder un nuevo préstamo, por ejemplo). El cálculo de la vista exige la lectura de cada tupla de préstamos correspondiente a la sucursal y sumar los importes de los préstamos, lo que puede llevar mucho tiempo. En cambio, si la definición de la vista del importe total de los préstamos estuviera materializada, el importe total de los préstamos podría hallarse buscando una sola tupla de la vista materializada. 14.5.1 Mantenimiento de las vistas

Un problema con las vistas materializadas es que hay que mantenerlas actualizadas cuando se modifican los datos empleados en la definición de la vista. Por ejemplo, si se actualiza el valor importe de un préstamo, la vista materializada se vuelve inconsistente con los datos subyacentes y hay que actualizarla. La tarea de mantener actualizada una vista materializada con los datos subyacentes se denomina mantenimiento de la vista. Las vistas pueden mantenerse mediante código escrito a mano: es decir, cada fragmento del código que actualiza el valor importe del préstamo puede modificarse para actualizar el importe total de los préstamos de la sucursal correspondiente. Otra opción para el mantenimiento de las vistas materializadas es la definición de desencadenadores para la inserción, el borrado y la actualización de cada relación de la definición de la vista. Los desencadenadores deben modificar el contenido de la vista materializada para tener en cuenta el cambio que ha provocado que se active el desencadenador. Una manera sencilla de hacerlo es volver a calcular completamente la vista materializada con cada actualización. Una opción mejor consiste en modificar sólo las partes afectadas de la vista materializada, lo que se conoce como mantenimiento incremental de la vista. En el Apartado 14.5.2 se describe la manera de llevar a cabo el mantenimiento incremental de la vista. Los sistemas modernos de bases de datos proporcionan más soporte directo para el mantenimiento incremental de las vistas. Los programadores de bases de datos ya no necesitan definir disparadores para el mantenimiento de las vistas. Por el contrario, una vez que se ha declarado materializada una vista, el sistema de bases de datos calcula su contenido y actualiza de manera incremental el contenido cuando se modifican los datos subyacentes. La mayoría de sistemas de bases de datos realizan un mantenimiento inmediato de las vistas; es decir, se realiza un mantenimiento incremental tan pronto como sucede una actualización como parte de una transacción de actualización. Algunos sistemas de bases de datos también permiten el mantenimiento diferido de las vistas, donde se difiere el mantenimiento a un momento posterior; por ejemplo, las actualizaciones se pueden recopilar a lo largo del día y las vistas materializadas se pueden actualizar durante la noche. Este enfoque reduce la sobrecarga en las transacciones de actualización. Sin embargo, es posible que las vistas materializadas con mantenimiento diferido no sean consistentes con las relaciones sobre las que están definidas. 14.5.2 Mantenimiento incremental de las vistas

Para comprender el modo de mantener de manera incremental las vistas materializadas se comenzará por considerar las operaciones individuales y luego se verá la manera de manejar una expresión completa. Los cambios de cada relación que puedan hacer que se quede desactualizada una vista materializada son las inserciones, los borrados y las actualizaciones. Para simplificar la descripción se sustituyen las actualizaciones a cada tupla por el borrado de esa tupla seguida de la inserción de la tupla actualizada. Por tanto, sólo hay que considerar las inserciones y los borrados. Los cambios (inserciones y borrados) en la relación o en la expresión se denominan su diferencial. 14.5.2.1 La operación reunión

Considérese la vista materializada v = r 1 s. Supóngase que se modifica r insertando un conjunto de tuplas denotado por ir . Si el valor antiguo de r se denota por rvieja y el valor nuevo de r por rnueva , rnueva = rvieja ∪ ir . Ahora bien, el valor antiguo de la vista, v vieja viene dado por rvieja 1 s, y el valor nuevo v nueva viene dado por rnueva 1 s. Se puede reescribir rnueva 1 s como (rvieja ∪ ir ) 1 s, lo que se

www.detodoprogramacion.com


496

Capítulo 14

Optimización de consultas

puede reescribir una vez más como (rvieja 1 s) ∪ (ir 1 s). En otras palabras, v nueva = v vieja ∪ (ir 1 s) Por tanto, para actualizar la vista materializada v, sólo hace falta añadir las tuplas ir 1 s al contenido antiguo de la vista materializada. Las inserciones en s se manejan de una manera completamente simétrica. Supóngase ahora que se modifica r borrando un conjunto de tuplas denotado por dr . Usando el mismo razonamiento que anteriormente se obtiene v nueva = v vieja − (dr 1 s) Las operaciones de borrado en s se manejan de una manera completamente simétrica. 14.5.2.2 Las operaciones selección y proyección

Considérese una vista v = σθ (r). Si se modifica r insertando un conjunto de tuplas ir , el nuevo valor de v puede calcularse como v nueva = v vieja ∪ σθ (ir ) De manera parecida, si se modifica r borrando un conjunto de tuplas er , el valor nuevo de v puede calcularse como v nueva = v vieja − σθ (er ) La proyección es una operación más difícil de tratar. Hay que considerar una vista materializada v = ΠA (r). Supóngase que la relación r está en el esquema R = (A, B) y que r contiene dos tuplas, (a, 2) y (a, 3). Entonces, ΠA (r) tiene una sola tupla, (a). Si se borra la tupla (a, 2) de r, no se puede borrar la tupla (a) de ΠA (r): si se hiciera, el resultado sería una relación vacía, mientras que en realidad ΠA (r) sigue teniendo una tupla ((a)). El motivo es que la misma tupla ((a)) se obtiene de dos maneras, y que el borrado de una tupla de r sólo borra una de las formas de obtener (a); la otra sigue presente. Este motivo también ofrece una pista de la solución: para cada tupla de una proyección como ΠA (r), se lleva la cuenta del número de veces que se ha obtenido. Cuando se borra un conjunto de tuplas dr de r, para cada tupla t de dr hay que hacer lo siguiente. t.A denota la proyección de t sobre el atributo A. Se busca (t.A) en la vista materializada y se disminuye la cuenta almacenada con ella en 1. Si la cuenta llega a 0, se borra (t.A) de la vista materializada. El manejo de las inserciones resulta relativamente directo. Cuando un conjunto de tuplas ir se inserta en r, para cada tupla t de ir se hace lo siguiente. Si (t.A) ya está presente en la vista materializada, se incrementa la cuenta almacenada con ella en 1. En caso contrario, se añade (t.A) a la vista materializada con la cuenta puesta a 1. 14.5.2.3 Las operaciones de agregación

Las operaciones de agregación se comportan aproximadamente como las proyecciones. Las operaciones de agregación en SQL son count, sum, avg, min y max: • count. Considérese la vista materializada v =A Gcount(B) (r), que calcula la cuenta del atributo B, después de agrupar r según el atributo A. Cuando se inserta un conjunto de tuplas ir en r, para cada tupla t de ir se realiza lo siguiente. Se busca el grupo t.A en la vista materializada. Si no se halla presente, se añade (t.A, 1) a la vista materializada. Si el grupo t.A se halla presente, se añade 1 a su cuenta. Cuando un conjunto er se borra de r, para cada tupla t de er se realiza lo siguiente. Se busca el grupo t.A en la vista materializada y se resta 1 de la cuenta del grupo. Si la cuenta llega a 0, se borra la tupla para el grupo t.A de la vista materializada. • sum. Considérese la vista materializada v =A Gsum(B) (r). Cuando un conjunto de tuplas ir se inserta en r, para cada tupla t de ir se realiza lo siguiente. Se busca el grupo t.A en la vista materializada. Si no se halla presente se añade (t.A, t.B) a la vista materializada; además, se almacena una cuenta de 1 asociada con (t.A, t.B), igual que se

www.detodoprogramacion.com


14.5

Vistas materializadas∗∗

497

hizo para las proyecciones. Si el grupo t.A se halla presente, se añade el valor de t.B al valor agregado para el grupo y se añade 1 a su cuenta. Cuando se borra un conjunto de tuplas er de r, para cada tupla t de er se realiza lo siguiente. Se busca el grupo t.A en la vista materializada y se resta t.B del valor agregado para el grupo. También se resta 1 de la cuenta del grupo y, si la cuenta llega a 0, se borra la tupla para el grupo t.A de la vista materializada. Si no se guardara el valor de cuenta adicional no se podría distinguir el caso de que la suma para el grupo sea 0 del caso en que se ha borrado la última tupla de un grupo. • avg. Considérese la vista materializada v =A Gavg(B) (r). La actualización directa del promedio de una inserción o de un borrado no resulta posible, ya que no sólo depende del promedio antiguo y de la tupla que se inserta o borra, sin también del número de tuplas del grupo. En lugar de eso, para tratar el caso de avg, se conservan los valores de agregación sum y count como se describieron anteriormente y se calcula el promedio como la suma dividida por la cuenta. • min, max. Considérese la vista materializada v =A Gmin(B) (r) (el caso de max es completamente equivalente). El tratamiento de las inserciones en r es inmediato. La conservación de los valores de agregación min and max para los borrados puede resultar más costoso. Por ejemplo, si la tupla correspondiente al valor mínimo para un grupo se borra de r, hay que examinar las demás tuplas de r que están en el mismo grupo para hallar el nuevo valor mínimo. 14.5.2.4 Otras operaciones

La operación de conjuntos intersección se conserva de la manera siguiente. Dada la vista materializada v = r ∩ s, cuando una tupla se inserta en r se comprueba si está presente en s y, en caso afirmativo, se añade a v. Si se borra una tupla de r, se borra de la intersección si se halla presente. Las otras operaciones con conjuntos, unión y diferencia de conjuntos, se tratan de manera parecida; los detalles se dejan al lector. Las reuniones externas se tratan de manera muy parecida a las reuniones, pero con algún trabajo adicional. En el caso del borrado de r hay que manejar las tuplas de s que ya no coinciden con ninguna tupla de r. En el caso de una inserción en r, hay que manejar las tuplas de s que no coincidían con ninguna tupla de r. De nuevo se dejan los detalles al lector. 14.5.2.5 Tratamiento de expresiones

Hasta ahora se ha visto el modo de actualizar de manera incremental el resultado de una sola operación. Para tratar una expresión entera se pueden obtener expresiones para el cálculo del cambio incremental en el resultado de cada subexpresión, comenzando por las de menor tamaño. Por ejemplo, supóngase que se desea actualizar de manera incremental la vista materializada E1 1 E2 cuando se inserta un conjunto de tuplas ir en la relación r. Supóngase que r se usa sólo en E1 . Supóngase que el conjunto de tuplas que se va a insertar en E1 viene dado por la expresión D1 . Entonces, la expresión D1 1 E2 da el conjunto de tuplas que hay que insertar en E1 1 E2 . Véanse las notas bibliográficas para obtener más detalles sobre la conservación incremental de las vistas con expresiones. 14.5.3 Optimización de consultas y vistas materializadas

La optimización de consultas puede llevarse a cabo tratando las vistas materializadas igual que a las relaciones normales. No obstante, las vistas materializadas ofrecen más oportunidades para la optimización: • Reescritura de las consultas para el empleo de vistas materializadas: Supóngase que está disponible la vista materializada v = r 1 s y que un usuario emite la consulta r 1 s 1 t. Puede que la reescritura de la consulta como v 1 t proporcione un plan de

www.detodoprogramacion.com


498

Capítulo 14

Optimización de consultas

consulta más eficiente que la optimización de la consulta tal y como se ha emitido. Por tanto, es función del optimizador de consultas reconocer si se puede usar una vista materializada para acelerar una consulta. • Sustitución del uso de una vista materializada por la definición de la vista: Supóngase que está disponible la vista materializada v = r 1 s, pero sin ningún índice definido sobre ella, y que un usuario emite la consulta σA=10 (v). Supóngase también que s tiene un índice sobre el atributo común B, y que r tiene un índice sobre el atributo A. Puede que el mejor plan para esta consulta sea sustituir v por r 1 s, lo que puede llevar al plan de consulta σA=10 (r) 1 s; la selección y la reunión pueden llevarse a cabo de manera eficiente empleando los índices sobre r.A y sobre s.B, respectivamente. Por el contrario, puede que la evaluación de la selección directamente sobre v necesite una exploración completa de v, lo que puede resultar más costoso. Las notas bibliográficas dan indicaciones para investigar el modo de llevar a cabo de manera eficiente la optimización de las consultas con vistas materializadas. Otro problema de optimización relacionado es el de la selección de las vistas materializadas, es decir, “la identificación del mejor conjunto de vistas para su materialización”. Esta decisión debe tomarse con base en la carga de trabajo del sistema, que es una secuencia de consultas y de actualizaciones que refleja la carga típica del sistema. Un criterio sencillo sería la selección de un conjunto de vistas materializadas que minimice el tiempo global de ejecución de la carga de trabajo de consultas y de actualizaciones, incluido el tiempo empleado para conservar las vistas materializadas. Los administradores de bases de datos suelen modificar este criterio para tener en cuenta la importancia de las diferentes consultas y actualizaciones: puede ser necesaria una respuesta rápida para algunas consultas y actualizaciones, mientras que puede resultar aceptable una respuesta lenta para otras. Los índices son como las vistas materializadas, en el sentido de que también son datos obtenidos, pueden acelerar las consultas y pueden desacelerar las actualizaciones. Por tanto, el problema de la selección de índices se halla íntimamente relacionado con el de la selección de las vistas materializadas, aunque resulta más sencillo. Estos problemas se examinan con más detalle en los Apartados 23.1.5 y 23.1.6. La mayoría de sistemas de bases de datos proporcionan herramientas para ayudar a los administradores de bases de datos en la selección de los índices y de las vistas materializadas. Estas herramientas examinan el historial de consultas y de actualizaciones y sugieren los índices y las vistas que hay que materializar. Database Tuning Assistant de SQL Server de Microsoft, Design Advisor de DB2 de IBM y Tuning Wizard de SQL de Oracle son ejemplos de estas herramientas. 14.6 Resumen

• Dada una consulta, suele haber gran variedad de métodos para calcular la respuesta. Es responsabilidad del sistema transformar la consulta tal y como la introdujo el usuario en una consulta equivalente que pueda calcularse de manera más eficiente. El proceso de búsqueda de una buena estrategia para el procesamiento de la consulta se denomina optimización de consultas. • La evaluación de las consultas complejas implica muchos accesos a disco. Dado que la transferencia de los datos desde el disco resulta lenta en comparación con la velocidad de la memoria principal y de la CPU del sistema informático, merece la pena asignar una cantidad considerable de procesamiento a la elección de un método que minimice los accesos al disco. • Hay varias reglas de equivalencia que se pueden emplear para transformar una expresión en otra equivalente. Estas reglas se emplean para generar de manera sistemática todas las expresiones equivalentes a la consulta dada. • Cada expresión del álgebra relacional representa una secuencia concreta de operaciones. El primer paso para la selección de una estrategia de procesamiento de consultas es la búsqueda de una expresión del álgebra relacional que sea equivalente a la expresión dada y que se estime menos costosa de ejecutar.

www.detodoprogramacion.com


Términos de repaso

499

• La estrategia que escoja el sistema de bases de datos para la evaluación de una operación depende del tamaño de cada relación y de la distribución de los valores dentro de las columnas. Para que puedan basar su elección de estrategia en información de confianza, los sistemas de bases de datos almacenan estadísticas para cada relación r. Entre estas estadísticas están ¤ El número de tuplas de la relación r. ¤ El tamaño del registro (tupla) de la relación r en bytes. ¤ El número de valores diferentes que aparecen en la relación r para un atributo determinado. • La mayoría de sistemas de bases de datos usan histogramas para almacenar el número de valores de un atributo en cada rango de valores. • Estas estadísticas permiten estimar el tamaño del resultado de varias operaciones, así como el coste de su ejecución. La información estadística sobre las relaciones resulta especialmente útil cuando se dispone de varios índices para ayudar al procesamiento de una consulta. La presencia de estas estructuras tiene una influencia significativa en la elección de una estrategia de procesamiento de consultas. • Los planes alternativos de evaluación para cada expresión pueden generarse mediante reglas de equivalencia y se puede escoger el plan más económico para todas las expresiones. Se dispone de varias técnicas de optimización para reducir el número de expresiones y planes alternativos que hace falta generar. • Se usan heurísticas para reducir el número de planes considerados y, por tanto, para reducir el coste de la optimización. Entre las reglas heurísticas para transformar las consultas del álgebra relacional están “Llevar a cabo las operaciones de selección tan pronto como sea posible”, “Llevar a cabo las proyecciones tan pronto como sea posible” y “Evitar los productos cartesianos”. • Las vistas materializadas pueden usarse para acelerar el procesamiento de las consultas. La conservación incremental de las vistas es necesaria para actualizar de forma eficiente las vistas materializadas cuando se modifican las relaciones subyacentes. El diferencial de cada operación puede calcularse mediante expresiones algebraicas que impliquen a los diferenciales de las entradas de la operación. Entre otros aspectos relacionados con las vistas materializadas están el modo de optimizar las consultas haciendo uso de las vistas materializadas disponibles y el modo de seleccionar las vistas que hay que materializar. Términos de repaso

• Optimización de consultas.

• Histogramas.

• Transformación de expresiones.

• Estimación de los valores distintos.

• Equivalencia de expresiones.

• Elección de los planes de evaluación.

• Reglas de equivalencia.

• Interacción de las técnicas de evaluación.

¤ Conmutatividad de la reunión. ¤ Asociatividad de la reunión. • Conjunto mínimo de reglas de equivalencia.

• Optimización basada en el coste. • Optimización del orden de reunión. ¤ Algoritmo de programación dinámica. ¤ Orden de reunión en profundidad por la izquierda.

• Enumeración de las expresiones equivalentes. • Estimación de la estadística. • Información de catálogo. • Estimación del tamaño. ¤ Selección. ¤ Selectividad. ¤ Reunión.

• Optimización heurística. • Elección del plan de acceso. • Evaluación correlacionada. • Descorrelación. • Vistas materializadas.

www.detodoprogramacion.com


500

Capítulo 14

Optimización de consultas

• Mantenimiento de las vistas materializadas. ¤ ¤ ¤ ¤

Recálculo. Mantenimiento incremental. Inserción. Borrado.

¤ Actualización. • Optimización de las consultas con las vistas materializadas. • Selección de índices. • Selección de las vistas materializadas.

Ejercicios prácticos

14.1 Demuéstrese que se cumplen las equivalencias siguientes. Explíquese el modo en que se pueden aplicar para mejorar la eficiencia de determinadas consultas: a. E1 1θ (E2 − E3 ) = (E1 1θ E2 − E1 1θ E3 ). b. σθ (A GF (E)) = A GF (σθ (E)), donde θ sólo usa atributos de A. c. σθ (E1 1 E2 ) = σθ (E1 ) 1 E2 , donde θ sólo usa atributos de E1 . 14.2 Para cada uno de los siguientes pares de expresiones, dense ejemplos de relaciones que muestren que las expresiones no son equivalentes. a. ΠA (R − S) y ΠA (R) − ΠA (S). b. σB<4 (A Gmax (B) (R)) y A Gmax (B) (σB<4 (R)). c. En las expresiones anteriores, si las dos apariciones de max se sustituyeran por min, indicar si las expresiones serían equivalentes. d. (R 1 S) 1 T y R 1 (S 1 T ) En otras palabras, la reunión externa por la izquierda no es asociativa. Sugerencia: supóngase que los esquemas de las tres relaciones son R(a, b1), S(a, b2) y T (a, b3), respectivamente. e. σθ (E1 1 E2 ) y E1 1 σθ (E2 ), donde θ usa sólo atributos de E2 . 14.3 SQL permite las relaciones con duplicados (Capítulo 3). a. Defínanse las versiones de las operaciones básicas del álgebra relacional σ, Π, ×, 1, −, ∪ y ∩ que se utilizan en relaciones con duplicados, de manera consistente con SQL. b. Compruébese cuáles de las reglas de equivalencia de la 1 a la 7.b se cumplen para la versión multiconjunto del álgebra relacional definida en el apartado a. 14.4 Considérense las relaciones r1 (A, B, C), r2 (C, D, E) y r3 (E, F ), con las claves principales A, C, and E, respectivamente. Supóngase que r1 tiene 1.000 tuplas, r2 tiene 1.500 tuplas y r3 tiene 750 tuplas. Estímese el tamaño de r1 1 r2 1 r3 y diséñese una estrategia eficiente para el cálculo de la reunión. 14.5 Considérense las relaciones r1 (A, B, C), r2 (C, D, E) y r3 (E, F ) del Ejercicio práctico 14.4. Supóngase que no hay claves principales, excepto el esquema completo. Sean V (C, r1 ) 900, V (C, r2 ) 1.100, V (E, r2 ) 50 y V (E, r3 ) 100. Supóngase que r1 tiene 1.000 tuplas, r2 tiene 1.500 tuplas y que r3 tiene 750 tuplas. Estímese el tamaño de r1 1 r2 1 r3 y diséñese una estrategia eficiente para el cálculo de la reunión. 14.6 Supóngase que se dispone de un árbol B+ para ciudad_sucursal para la relación sucursal y que no se dispone de ningún otro índice. Indíquese la mejor manera de tratar las siguientes selecciones que implican a la negación: a. σ¬(ciudad_sucursal<“Arganzuela”) (sucursal) b. σ¬(ciudad_sucursal=“Arganzuela”) (sucursal) c. σ¬(ciudad_sucursal<“Arganzuela” ∨ activos<5000) (sucursal) 14.7 Demuéstrese que, con n relaciones, hay (2(n − 1))!/(n − 1)! órdenes de reunión diferentes. Sugerencia: un árbol binario completo es aquél en el que cada nodo interno tiene exactamente dos hijos. Utilícese el hecho de que el número de árboles binarios completos diferentes con n

www.detodoprogramacion.com


Ejercicios

501

nodos hojas es

µ ¶ 1 2(n − 1) n (n − 1) Si se desea, se puede obtener la fórmula para el número de árboles binarios completos con n nodos a partir de la fórmula para el número de árboles binarios con n nodos. El número de árboles binarios con n nodos es µ ¶ 2n 1 n+1 n Este número se conoce como número de Catalan y su obtención puede hallarse en cualquier libro de texto estándar sobre estructuras de datos o algoritmos.

14.8 Demuéstrese que el orden de reunión de menor coste puede calcularse en un tiempo O(3n ). Supóngase que se puede almacenar y examinar la información sobre un conjunto de relaciones (como el orden óptimo de reunión para el conjunto y el coste de ese orden de reunión) en un tiempo constante. (Si se encuentra difícil este ejercicio, demuéstrese al menos la cota de tiempo menos estricta de O(22n )). 14.9 Demuéstrese que, si sólo se toman en consideración los árboles de reunión en profundidad por la izquierda, como en el optimizador System R, el tiempo empleado en buscar el orden de reunión más eficiente es del orden de n2n . Supóngase que sólo hay un orden interesante. 14.10 Descorrelación: a. Escríbase una consulta anidada sobre la relación cuenta para buscar, para cada sucursal cuyo nombre comience por B, todas las cuentas con el saldo máximo de cada sucursal. b. Reescríbase la consulta anterior, sin emplear consultas anidadas; en otras palabras, descorrelaciónese la consulta. c. Diséñese un procedimiento (parecido al descrito en el Apartado 14.4.4) para descorrelacionar estas consultas. Ejercicios

14.11 Supóngase que se dispone de un árbol B+ para (nombre_sucursal, ciudad_sucursal) para la relación sucursal. Indíquese la mejor manera de tratar la selección siguiente: σ(ciudad_sucursal<“Arganzuela”) ∧ (activos<5000)∧(nombre_sucursal=“Centro”) (sucursal) 14.12 Muéstrese el modo de obtener las equivalencias siguientes mediante una secuencia de transformaciones usando las reglas de equivalencia del Apartado 14.2.1. a. σθ1 ∧θ2 ∧θ3 (E) = σθ1 (σθ2 (σθ3 (E))) b. σθ1 ∧θ2 (E1 1θ3 E2 ) = σθ1 (E1 1θ3 (σθ2 (E2 ))), donde θ2 sólo implica atributos de E2 14.13 Se dice que un conjunto de reglas de equivalencia está completo si, siempre que dos expresiones son equivalentes, se puede obtener una de la otra mediante una secuencia de usaciones de las reglas de equivalencia. Indíquese si el conjunto de reglas de equivalencia que se consideró en el Apartado 14.2.1 es completo. Sugerencia: considérese la equivalencia σ3=5 (r) = {}. 14.14 Descríbase el modo de usar un histograma para estimar el tamaño de una selección de la forma σA≤v (r). 14.15 Supóngase que dos relaciones r y s tienen histogramas sobre los atributos r.A y s.A respectivamente, pero con rangos diferentes. Sugiérase el modo de usar los histogramas para estimar el tamaño de r 1 s. Sugerencia: divídanse más los rangos de cada histograma. 14.16 Descríbase el modo de conservar de manera incremental el resultado de las operaciones siguientes, tanto para inserciones como para borrados: a. Unión y diferencia de conjuntos. b. Reunión externa por la izquierda.

www.detodoprogramacion.com


502

Capítulo 14

Optimización de consultas

14.17 Dese un ejemplo de expresión que defina una vista materializada y dos situaciones (conjuntos de estadísticas para las relaciones de entrada y sus diferenciales) tales que la conservación incremental de la vista sea mejor que su recálculo en una de las situaciones y el recálculo sea mejor en la otra. 14.18 Supóngase que se desea obtener resultados ordenados para r 1 s según un atributo de r y sólo se desean las primeras K respuestas para algún K relativamente pequeño. Dese una buena forma de evaluar la consulta a. Cuando la reunión es sobre una clave externa de r que referencia a s. b. Cuando la reunión no es sobre una clave externa. 14.19 Considérese la relación r(A, B, C) con un índice sobre el atributo A. Dese un ejemplo de una consulta que se pueda responder usando sólo el índice, sin tener que examinar las tuplas de la relación. (Los planes de consulta que usan sólo el índice sin acceder a la relación se denominan planes sólo de índices).

Notas bibliográ cas

El trabajo precursor de Selinger et al. [1979] describe la selección del camino de acceso en el optimizador System R, que fue uno de los primeros optimizadores de consultas relacionales.El procesamiento de consultas en Starburst, que se describe en Haas et al. [1989], construye las bases de la optimización de consultas en DB2 de IBM. Graefe y McKenna [1993] describen Volcano, un optimizador de consultas basado en reglas de equivalencia que, junto a su sucesor Cascades (Graefe [1995]) forma el fundamento de la optimización de consultas en SQL Server de Microsoft. Véanse los Capítulos 27, 28 y 29 para más información sobre el procesamiento y optimización de consultas en Oracle, DB2 de IBM y SQL Server de Microsoft respectivamente. Estadísticas y estimación del coste: la estimación de las estadísticas de los resultados de las consultas, como el tamaño del resultado, se aborda en Ioannidis y Poosala [1995], Poosala et al. [1996] y Ganguly et al. [1996], entre otros. Las distribuciones no uniformes de valores causan problemas para la estimación del tamaño y del coste de las consultas. Las técnicas de estimación del coste que usan histogramas de las distribuciones de los valores se han propuesto para abordar el problema. Ioannidis y Christodoulakis [1993], Ioannidis y Poosala [1995] y Poosala et al. [1996] presentan los resultados en este área. Todos los principales sistemas de bases de datos comerciales usan en gran medida los histogramas para la estimación del coste. También soportan el muestreo para calcular eficientemente los histogramas sin necesidad de examinar la relación completa: es muy probable que un histograma construido a partir de un subconjunto de la relación seleccionado aleatoriamente sea muy parecido al histograma de la relación completa si el subconjunto de muestra es suficientemente grande. Heurísticas: la búsqueda exhaustiva de todos los planes de consultas no resulta práctica para la optimizacion de las reuniones que implican a muchas relaciones. La mayoría de optimizadores usan heurísticas para encontrar algunos planes buenos, además de usar un algoritmo exhaustivo para generar órdenes alternativos de la reunión. Los algoritmos exhaustivos terminan cuando se excede un límite de sobrecarga; por ejemplo, si el coste de optimización alcanza una fracción significativa del coste estimado de ejecución. Optimización paramétrica de consultas: Ioannidis et al. [1992], Ganguly [1998] y Hulgeri y Sudarshan [2003] han propuesto técnicas para optimizar consultas cuando la selectividad de los parámetros de la consulta no se conoce en el momento de la optimización. Se calcula un conjunto de planes (uno por cada una de las diferentes selectividades de las consultas) y el optimizador lo almacena, en el momento de la compilación. Uno de estos planes se elige en el momento de la ejecución, con base en las selectividades reales, evitando el coste de la optimización completa en el momento de la ejecución. Optimización de agregación: Klug [1982] fue uno de los primeros trabajos sobre optimización de expresiones del álgebra relacional con funciones de agregación. Yan y Larson [1995] and Chaudhuri y Shim [1994] estudian la optimización de consultas con agregación. La optimización de las consultas que con-

www.detodoprogramacion.com


Notas bibliográficas

503

tienen reuniones externas se describe en Rosenthal y Reiner [1984], Galindo-Legaria y Rosenthal [1992] y Galindo-Legaria [1994]. Optimización de los primeros K: muchas consultas recuperan los resultados ordenados bajo algunos atributos y requieren solamente los resultados de los primeros K para algún K. Cuando K es pequeño, un plan de la optimización de consulta que genere el conjunto completo de resultados, después ordene y genere los primeros K sería muy ineficaz puesto que desecharía la mayoría de los resultados intermedios que calcula. Se han propuesto varias técnicas para optimizar estas consultas de los primeros K. Un enfoque es usar los planes encauzados que puedan generar los resultados ordenados. Otro enfoque es estimar el mayor valor de los atributos que aparecerán en la salida de los primeros K, e introducir los predicados de selección que eliminan los valores mayores. Si se generan tuplas adicionales por debajo de los primeros K, se desechan y, si se generan muy pocas tuplas, entonces se cambia la condición de la selección y se ejecuta nuevamente la consulta. La optimización de consultas de los primeros K se trata en Carey y Kossmann [1998] y en Bruno et al. [2002]. El lenguaje SQL plantea varios desafíos para la optimización de las consultas, incluidas la presencia de valores duplicados y nulos y la semántica de las subconsultas anidadas. La extensión del álgebra relacional a los valores duplicados se describe en Dayal et al. [1982]. La optimización de las subconsultas anidadas se trata en Kim [1982], Ganski y Wong [1987], Dayal [1987], Seshadri et al. [1996] y, más recientemente, en Galindo-Legaria y Joshi [2001]. Minimización de la reunión: cuando las consultas se generan mediante vistas, se suelen reunir más relaciones de las necesarias para el cálculo de cada consulta. Se ha agrupado un conjunto de técnicas para la minimización de las reuniones bajo el nombre de optimización con tableau. El concepto de tableau lo introdujeron Aho et al. [1979b] y Aho et al. [1979a] y lo ampliaron Sagiv y Yannakakis [1981]. Ullman [1988] y Maier [1983] proporcionan un tratamiento de los tableaux con un nivel de libro de texto. Optimización de multiconsultas: Sellis [1988] y Roy et al. [2000] describen la optimización de multiconsultas, que es el problema de optimización de la ejecución de varias consultas como si fueran un grupo. Si se toma en consideración todo un grupo de consultas, resulta posible descubrir subexpresiones comunes que pueden evaluarse una sola vez para todo el grupo. Finkelstein [1982] y Hall [1976] consideran la optimización de un grupo de consultas y el empleo de las subexpresiones comunes. Dalvi et al. [2001] estudia los problemas de optimización en los encauzamientos con espacio de memorias intermedias limitado combinadas con el compartimiento de subexpresiones comunes. Optimización semántica de consultas: la optimización de consultas puede hacer uso de la información semántica, como las dependencias funcionales y otras restricciones de integridad. La optimización semántica de consultas en las bases de datos relacionales se estudia en King [1981], Chakravarthy et al. [1990] y, en el contexto de la agregación, en Sudarshan y Ramakrishnan [1991]. Vistas materializadas: Blakeley et al. [1986], Blakeley et al. [1989] y Griffin y Libkin [1995] describen las técnicas para la conservación de las vistas materializadas. Gupta y Mumick [1995] proporcionan una reseña de la conservación de las vistas materializadas. La optimización de los planes de conservación de las vistas materializadas se describe en Vista [1998] y Mistry et al. [2001]. La optimización de consultas en presencia de vistas materializadas se aborda en Larson y Yang [1985], Chaudhuri et al. [1995], Dar et al. [1996] y Roy et al. [2000]. La selección de índices y la selección de vistas materializadas se aborda en Ross et al. [1996], Labio et al. [1997], Gupta [1997], Chaudhuri y Narasayya [1997] y Roy et al. [2000]. Los problemas que aparecen en la selección de índices y vistas materializadas se estudian más tarde en los Apartados 23.1.5, 23.1.6 y 23.1.7. Optimización de actualizaciones: Galindo-Legaria et al. [2004] describe el proceso y la optimización de consultas para las actualizaciones de la base de datos, incluyendo la optimización del mantenimiento del índice, los planes materializados del mantenimiento de la visión y la comprobación de las restricciones de integridad. Las preguntas de la actualización implican a menudo subconsultas en las cláusulas set y where, que también deben tomarse en consideración al optimizar la actualización. Las actualizaciones que implican una selección en la columna actualizada (e.g. dan un aumento del 10 por ciento a todos los empleados cuyo sueldo sea ≥ 100.000 e) se deben tratar con cuidado. Si se hace la actualización mientras una exploración del índice evalúa la selección, se puede volver a insertar una tupla actualizada en el índice por delante de la zona explorada y la exploración puede volver a tenerla en cuenta; la misma tupla de empleado, por tanto, se puede actualizar varias veces de manera

www.detodoprogramacion.com


504

Capítulo 14

Optimización de consultas

incorrecta (un número infinito de veces, en este caso). Un problema parecido se presenta también con las actualizaciones que implican subconsultas cuyo resultado queda afectado por la actualización. El problema de que una actualización afecte a la ejecución de una consulta asociada a la actualización se conoce como problema de Halloween (denominado así por la fecha en que IBM lo reconoció por primera vez). Este problema se puede evitar ejecutando en primer lugar las consultas que definen la actualización, creando una lista de tuplas afectadas y actualizando las tuplas y los índices como último paso. Sin embargo, dividir el plan de ejecución de esa manera aumenta el coste de ejecución. Los planes de actualización se pueden optimizar comprobando si se puede dar el problema de Halloween y, si no es el caso, las actualizaciones se pueden llevar a cabo mientras se procesa la consulta, reduciendo la sobrecarga de actualización. Este tipo de optimización se implementa en la mayor parte de los sistemas de bases de datos, y se describe, por ejemplo, en Galindo-Legaria et al. [2004]. Indexación, procesamiento de consultas y optimización de consultas XML: la indexación de datos XMLy el procesamiento y optimización de consultas XML han sido áreas de gran interés en los últimos años. Se ha publicado gran cantidad de artículos en este área. Uno de los retos de la indexación de datos es que las consultas puedan especificar una selección de ruta, tal como /a/b//c[d=“CSE”]; el índice debe soportar la recuperación eficiente de los nodos que satisfagan la especificación de ruta y la selección de valores. En Pal et al. [2004] y Kaushik et al. [2004] se puede encontrar trabajo reciente sobre la indexación de datos XML. Si los datos se dividen y almacenan en relaciones, la evaluación de las expresiones de ruta se corresponde con el cálculo de reuniones. Se han propuesto varias técnicas para el cálculo eficiente de esas reuniones, en especial cuando la expresión de ruta especifica cualquier descendiente (//). Se han propuesto varias técnicas para la numeración de los nodos de los datos XML que se pueden usar para comprobar de manera eficiente si un nodo es un descendiente de otro; véase, por ejemplo, O’Neil et al. [2004]. McHugh y Widom [1999], Wu et al. [2003] y Krishnaprasad et al. [2004] son trabajos sobre la optimización de consultas XML.

www.detodoprogramacion.com


P

A

R

T

E

5

Gestión de transacciones

El término transacción hace referencia a un conjunto de operaciones que forman una única unidad lógica de trabajo. Por ejemplo, la transferencia de dinero de una cuenta a otra es una transacción que consta de dos actualizaciones, una para cada cuenta. Resulta importante que, o bien se ejecuten completamente todas las acciones de una transacción, o bien, en caso de fallo, se deshagan los efectos parciales de cada transacción incompleta. Esta propiedad se denomina atomicidad. Además, una vez ejecutada con éxito una transacción, sus efectos deben persistir en la base de datos — un fallo en el sistema no debe tener como consecuencia que la base de datos descarte una transacción que se haya completado con éxito. Esta propiedad se denomina durabilidad. En los sistemas de bases de datos en los que se ejecutan de manera concurrente varias transacciones, si no se controlan las actualizaciones de los datos compartidos, existe la posibilidad de que las transacciones operen sobre estados intermedios inconsistentes creados por las actualizaciones de otras transacciones. Esta situación puede dar lugar a actualizaciones erróneas de los datos almacenados en la base de datos. Por tanto, los sistemas de bases de datos deben proporcionar los mecanismos para aislar las transacciones de otras transacciones que se ejecuten de manera concurrente. Esta propiedad se denomina aislamiento. El Capítulo 15 describe con detalle el concepto de transacción, incluidas las propiedades de atomicidad, durabilidad, aislamiento y otras propiedades proporcionadas por la abstracción de las transacciones. En concreto, el capítulo precisa el concepto de aislamiento por medio de un concepto denominado secuencialidad. El Capítulo 16 describe varias técnicas de control de concurrencia que ayudan a implementar la propiedad del aislamiento. El Capítulo 17 describe el componente de las bases de datos para la administración de las recuperaciones, que implementa las propiedades de atomicidad y de durabilidad. Entendido como un todo, el componente de gestión de transacciones de un sistema de bases de datos permite a los desarrolladores de bases de datos centrarse en la implementación de las transacciones individualmente, ignorando los aspectos de concurrencia y tolerancia a fallos.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

15

Transacciones

A menudo, desde el punto de vista del usuario de una base de datos, se considera a un conjunto de varias operaciones sobre una base de datos como una única operación. Por ejemplo, una transferencia de fondos desde una cuenta corriente a una cuenta de ahorros es una operación simple desde el punto de vista del cliente; sin embargo, en el sistema de base de datos, está compuesta internamente por varias operaciones. Evidentemente es esencial que tengan lugar todas las operaciones o que, en caso de fallo, ninguna de ellas se produzca. Sería inaceptable efectuar el cargo de la transferencia en la cuenta corriente y que no se abonase en la cuenta de ahorros. Se llama transacción a una colección de operaciones que forman una única unidad lógica de trabajo. Un sistema de base de datos debe asegurar que la ejecución de las transacciones se realice adecuadamente a pesar de la existencia de fallos—o se ejecuta la transacción completa o no se ejecuta en absoluto. Además debe gestionar la ejecución concurrente de las transacciones evitando introducir inconsistencias. Volviendo al ejemplo de la transferencia de fondos, una transacción que calcule el saldo total del cliente podría ver el saldo de la cuenta corriente antes de que sea cargado por la transacción de la transferencia de fondos, y el saldo de la cuenta de ahorros después del abono. Como resultado, se obtendría un resultado incorrecto. Este capítulo es una introducción a los conceptos básicos en el procesamiento de transacciones. En los Capítulos 16 y 17 se incluyen más detalles sobre el procesamiento concurrente de transacciones y la recuperación de fallos. En el Capítulo 24 se tratan temas adicionales acerca del procesamiento de transacciones. 15.1 Concepto de transacción

Una transacción es una unidad de la ejecución de un programa que accede y posiblemente actualiza varios elementos de datos. Una transacción se inicia por la ejecución de un programa de usuario escrito en un lenguaje de manipulación de datos de alto nivel o en un lenguaje de programación (por ejemplo SQL, C++ o Java), y está delimitado por instrucciones (o llamadas a función) de la forma begin transaction (inicio transacción) y end transaction (fin transacción). La transacción consiste en todas las operaciones que se ejecutan entre begin transaction y end transaction. Para asegurar la integridad de los datos se necesita que el sistema de base de datos mantenga las siguientes propiedades de las transacciones: • Atomicidad. O bien todas las operaciones de la transacción se realizan adecuadamente en la base de datos o ninguna de ellas. • Consistencia. La ejecución aislada de la transacción (es decir, sin otra transacción que se ejecute concurrentemente) conserva la consistencia de la base de datos. 507

www.detodoprogramacion.com


508

Capítulo 15

Transacciones

• Aislamiento. Aunque se ejecuten varias transacciones concurrentemente, el sistema garantiza que para cada par de transacciones Ti y Tj , se cumple que para los efectos de Ti , o bien Tj ha terminado su ejecución antes de que comience Ti , o bien que Tj ha comenzado su ejecución después de que Ti termine. De este modo, cada transacción ignora al resto de las transacciones que se ejecuten concurrentemente en el sistema. • Durabilidad. Tras la finalización con éxito de una transacción, los cambios realizados en la base de datos permanecen, incluso si hay fallos en el sistema. Estas propiedades a menudo reciben el nombre de propiedades ACID; el acrónimo se obtiene de la primera letra de cada una de las cuatro propiedades en inglés (Atomicity, Consistency, Isolation y Durability, respectivamente). Para comprender mejor las propiedades ACID y la necesidad de dichas propiedades, considérese un sistema bancario simplificado constituido por varias cuentas y un conjunto de transacciones que acceden y actualizan dichas cuentas. Por ahora se asume que la base de datos reside permanentemente en disco, pero una porción de la misma reside temporalmente en la memoria principal. El acceso a la base de datos se lleva a cabo mediante las dos operaciones siguientes: • leer(X), que transfiere el dato X de la base de datos a una memoria intermedia local perteneciente a la transacción que ejecuta la operación leer. • escribir(X), que transfiere el dato X desde la memoria intermedia local de la transacción que ejecuta la operación escribir a la base de datos. En un sistema de base de datos real, la operación escribir no tiene por qué producir necesariamente una actualización de los datos en disco; la operación escribir puede almacenarse temporalmente en memoria y llevarse a disco más tarde. Sin embargo, por el momento se supondrá que la operación escribir actualiza inmediatamente la base de datos. Se volverá a este tema en el Capítulo 17. Sea Ti una transacción para transferir 50 e de la cuenta A a la cuenta B. Se puede definir dicha transacción como Ti : leer(A); A := A − 50; escribir(A); leer(B); B := B + 50; escribir(B). Considérense ahora cada una de las propiedades ACID (para una presentación más cómoda, se consideran en distinto orden al indicado por A-C-I-D). • Consistencia. En este caso el requisito de consistencia es que la suma de A y B no sea alterada al ejecutar la transacción. Sin el requisito de consistencia, ¡la transacción podría crear o destruir dinero! Se puede comprobar fácilmente que si una base de datos es consistente antes de ejecutar una transacción, sigue siéndolo después de ejecutar dicha transacción. La responsabilidad de asegurar la consistencia de una transacción es del programador de la aplicación que codifica dicha transacción. La comprobación automática de las restricciones de integridad puede facilitar esta tarea, como se vio en el Apartado 4.2. • Atomicidad. Supóngase que justo antes de ejecutar la transacción Ti los valores de las cuentas A y B son de 1.000 e y de 2.000 e, respectivamente. Supóngase ahora que durante la ejecución de la transacción Ti se produce un fallo que impide que dicha transacción finalice con éxito su ejecución. Ejemplos de este tipo de fallos pueden ser los fallos en la alimentación, los fallos del hardware y los errores software. Además, supóngase que el fallo tiene lugar después de ejecutarse la operación escribir(A), pero antes de ejecutarse la operación escribir(B). Es ese caso, los valores de las cuentas A y B que se ven reflejados en la base de datos son 950 e y 2.000 e. Se han

www.detodoprogramacion.com


15.1

Concepto de transacción

509

perdido 50 e de la cuenta A como resultado de este fallo. En particular se puede ver que ya no se conserva la suma A + B. Así, como resultado del fallo, el estado del sistema deja de reflejar el estado real del mundo que se supone que modela la base de datos. Un estado así se denomina estado inconsistente. Hay que asegurarse de que estas inconsistencias no sean visibles en un sistema de base de datos. Obsérvese, sin embargo, que un sistema puede en algún momento alcanzar un estado inconsistente. Incluso si la transacción Ti se ejecuta por completo, existe un punto en el que el valor de la cuenta A es de 950 e y el de la cuenta B es de 2.000 e, lo cual constituye claramente un estado inconsistente. Este estado, sin embargo, se sustituye eventualmente por otro estado consistente en el que el valor de la cuenta A es de 950 e y el de la cuenta B es de 2.050 e. De este modo, si la transacción no empieza nunca o se garantiza que se complete, un estado inconsistente así no será visible excepto durante la ejecución de la transacción. Ésta es la razón de que aparezca el requisito de atomicidad. Si se proporciona la propiedad de atomicidad, o todas las acciones de la transacción se ven reflejadas en la base de datos, o ninguna de ellas. La idea básica para asegurar la atomicidad es la siguiente. El sistema de base de datos mantiene los valores antiguos (en disco) de aquellos datos sobre los que una transacción realiza una escritura y, si la transacción no completa su ejecución, los valores antiguos se recuperan para que parezca que la transacción no se ha ejecutado. Estas ideas se muestran más adelante en el Apartado 15.2. La responsabilidad de asegurar la atomicidad es del sistema de base de datos; en concreto, lo maneja un componente llamado componente de gestión de transacciones, que se describe en detalle en el Capítulo 17. • Durabilidad. Una vez que se completa con éxito la ejecución de una transacción, y después de comunicar al usuario que inició la transacción que se ha realizado la transferencia de fondos, un fallo en el sistema no debe producir la pérdida de datos correspondientes a dicha transferencia. La propiedad de durabilidad asegura que, una vez que se completa con éxito una transacción, persisten todas las modificaciones realizadas en la base de datos, incluso si hay un fallo en el sistema después de completarse la ejecución de dicha transacción. A partir de ahora se asume que un fallo en la computadora del sistema produce una pérdida de datos de la memoria principal, pero los datos almacenados en disco nunca se pierden. Se puede garantizar la durabilidad si se asegura que 1. Las modificaciones realizadas por la transacción se guardan en disco antes de que finalice la transacción. 2. La información de las modificaciones realizadas por la transacción guardada en disco es suficiente para permitir a la base de datos reconstruir dichas modificaciones cuando el sistema se reinicie después del fallo. La responsabilidad de asegurar la durabilidad pertenece a un componente software del sistema de base de datos llamado componente de gestión de recuperaciones. El componente de gestión de transacciones y el componente de gestión de recuperaciones están estrechamente relacionados, y su implementación se describe en el Capítulo 17. • Aislamiento. Incluso si se aseguran las propiedades de consistencia y de atomicidad para cada transacción, si varias transacciones se ejecutan concurrentemente, se pueden entrelazar sus operaciones de un modo no deseado, produciendo un estado inconsistente. Por ejemplo, como se ha visto antes, la base de datos es inconsistente temporalmente durante la ejecución de la transacción para transferir fondos de la cuenta A a la cuenta B, con el total deducido escrito ya en A y el total incrementado todavía sin escribir en B. Si una segunda transacción que se ejecuta concurrente lee A y B en este punto intermedio y calcula A + B, observará un valor inconsistente. Además, si esta segunda transacción realiza después modificaciones en A y B basándose en los valores leídos, la base de datos puede permanecer en un estado inconsistente aunque ambas transacciones terminen. Una solución para el problema de ejecutar transacciones concurrentemente es ejecutarlas secuencialmente — es decir, una tras otra. Sin embargo, la ejecución concurrente de transacciones

www.detodoprogramacion.com


510

Capítulo 15

Transacciones

produce notables beneficios en el rendimiento, como se verá en el Apartado 15.4. Se han desarrollado otras soluciones que permiten la ejecución concurrente de varias transacciones. Los problemas que causa la ejecución concurrente de transacciones se muestra en el Apartado 15.4. La propiedad de aislamiento asegura que el resultado obtenido al ejecutar concurrentemente las transacciones es un estado del sistema equivalente a uno obtenido al ejecutar una tras otra en algún orden. Los principios de aislamiento se presentarán más adelante en el Apartado 15.5. La responsabilidad de asegurar la propiedad de aislamiento es de un componente del sistema de base de datos llamado componente de control de concurrencia, que se presenta en el Capítulo 16.

15.2 Estados de una transacción

En ausencia de fallos, todas las transacciones se completan con éxito. Sin embargo, como se ha visto antes, una transacción puede que no siempre termine su ejecución con éxito. Una transacción de este tipo se denomina abortada. Si se pretende asegurar la propiedad de atomicidad, una transacción abortada no debe tener efecto sobre el estado de la base de datos. Así, cualquier cambio que haya hecho la transacción abortada sobre la base de datos debe deshacerse. Una vez que se han deshecho los cambios efectuados por la transacción abortada, se dice que la transacción está retrocedida. Parte de la responsabilidad del esquema de recuperaciones es gestionar las transacciones abortadas. Una transacción que termina con éxito se dice que está comprometida. Una transacción comprometida que haya hecho modificaciones transforma la base de datos llevándola a un nuevo estado consistente, que permanece incluso si hay un fallo en el sistema. Cuando una transacción se ha comprometido no se pueden deshacer sus efectos abortándola. La única forma de deshacer los cambios de una transacción comprometida es ejecutando una transacción compensadora. Por ejemplo, si una transacción añade 20 e a una cuenta, la transacción compensadora debería restar 20 e de la cuenta. Sin embargo, no siempre se puede crear dicha transacción compensadora. Por tanto, se deja al usuario la responsabilidad de crear y ejecutar transacciones compensadoras, y no la gestiona el sistema de base de datos. En el Capítulo 25 se incluye un estudio de las transacciones compensadoras. Es necesario precisar qué se entiende por terminación con éxito de una transacción. Se establece por tanto un simple modelo abstracto de transacción. Una transacción debe estar en uno de los estados siguientes: • Activa, el estado inicial; la transacción permanece en este estado durante su ejecución. • Parcialmente comprometida, después de ejecutarse la última instrucción. • Fallida, tras descubrir que no puede continuar la ejecución normal. • Abortada, después del retroceso de la transacción y de haber restablecido la base de datos la base de datos a su estado anterior al comienzo de la transacción. • Comprometida, tras completarse con éxito. El diagrama de estados correspondiente a una transacción se muestra en la Figura 15.1. Se dice que una transacción se ha comprometido sólo si ha llegado al estado comprometida. Análogamente, se dice que una transacción ha abortado sólo si ha llegado al estado abortada. Una transacción se dice que ha terminado si se ha comprometido o bien se ha abortado. Una transacción comienza en el estado activa. Cuando acaba su última instrucción pasa al estado de parcialmente comprometida. En este punto la transacción ha terminado su ejecución, pero es posible que aún tenga que ser abortada, puesto que los datos actuales pueden estar todavía en la memoria principal y puede producirse un fallo en el hardware antes de que se complete con éxito. El sistema de base de datos escribe en disco la información suficiente para que, incluso al producirse un fallo, puedan reproducirse los cambios hechos por la transacción al reiniciar el sistema tras el fallo. Cuando se termina de escribir esta información, la transacción pasa al estado comprometida.

www.detodoprogramacion.com


15.2

Estados de una transacción

parcialmente comprometida

comprometida

fallida

abortada

511

activa

Figura 15.1

Diagrama de transición de estado de una transacción.

Como se ha mencionado antes, se asume que los fallos no provocan pérdidas de datos en disco. Las técnicas para tratar las pérdidas de datos en disco se muestran en el Capítulo 17. Una transacción llega al estado fallida después de que el sistema determine que dicha transacción no puede continuar su ejecución normal (por ejemplo, a causa de errores de hardware o lógicos). Una transacción de este tipo se debe retroceder. Después pasa al estado abortada. En este punto, el sistema tiene dos opciones: • Reiniciar la transacción, pero sólo si la transacción se ha abortado a causa de algún error hardware o software que no lo haya provocado la lógica interna de la transacción. Una transacción reiniciada se considera una nueva transacción. • Cancelar la transacción. Normalmente se hace esto si hay algún error interno lógico que sólo se puede corregir escribiendo de nuevo el programa de aplicación, o debido a una entrada incorrecta o a que no se han encontrado los datos deseados en la base de datos. Hay que tener cuidado cuando se trabaja con escrituras externas observables, como en un terminal o en una impresora. Cuando una escritura así tiene lugar, no puede borrarse puesto que puede haber sido vista fuera del sistema de base de datos. Muchos sistemas permiten que tales escrituras tengan lugar sólo después de que la transacción llegue al estado comprometida. Una manera de implementar dicho esquema es hacer que el sistema de base de datos almacene temporalmente cualquier valor asociado con estas escrituras externas en memoria no volátil, y realice las escrituras actuales sólo si la transacción llega al estado comprometida. Si el sistema falla después de que la transacción llegue al estado comprometida, pero antes de que finalicen las escrituras externas, el sistema de base de datos puede llevar a cabo dichas escrituras externas (usando los datos de la memoria no volátil) cuando el sistema se reinicie. La gestión de las escrituras externas puede ser más complicada en ciertas situaciones. Por ejemplo, supóngase que la acción externa es dispensar dinero en un cajero automático y el sistema falla justo antes de que se dispense el dinero (se asume que el dinero se dispensa atómicamente). No tiene sentido dispensar el dinero cuando se reinicie el sistema, ya que el usuario probablemente no esté en el cajero. En tal caso es necesario una transacción compensadora, como devolver el dinero a la cuenta del usuario. Para algunas aplicaciones puede ser deseable permitir a las transacciones activas que muestren datos a los usuarios, particularmente para transacciones de larga duración que se ejecutan durante minutos u horas. Desafortunadamente no se puede permitir dicha salida de datos observables a no ser que se quiera arriesgar la atomicidad de la transacción. Muchos sistemas de bases de datos actuales aseguran la atomicidad y, por tanto, prohíben esta forma de interacción con el usuario. En el Capítulo 25 se describen modelos alternativos que proporcionan transacciones interactivas de larga duración.

www.detodoprogramacion.com


512

Capítulo 15

Transacciones

15.3 Implementación de la atomicidad y la durabilidad

El componente de gestión de recuperaciones de un sistema de base de datos implementa el soporte para la atomicidad y durabilidad. En primer lugar consideramos un esquema simple pero extremadamente ineficiente, denominado copia en la sombra. Este esquema, que se basa en hacer copias de la base de datos, denominadas copias sombra, asume que sólo una transacción está activa en cada momento. El esquema asume que la base de datos es simplemente un archivo en disco. En disco se mantiene un puntero llamado puntero_bd que apunta a la copia actual de la base de datos. En el esquema de copia en la sombra, una transacción que quiera actualizar una base de datos crea primero una copia completa de dicha base de datos. Todos los cambios se hacen en la nueva copia de la base de datos dejando la copia original, la copia en la sombra, inalterada. Si en cualquier punto hay que abortar la transacción, la copia nueva simplemente se borra. La copia antigua de la base de datos no se ve afectada. Si la transacción se completa, se compromete como sigue. En primer lugar se consulta al sistema operativo para asegurarse de que todas las páginas de la nueva copia de la base de datos se han escrito en disco (en los sistemas Unix se usa el comando fsync para este propósito). Después de terminar este comando se actualiza el puntero puntero_bd para que apunte a la nueva copia de la base de datos; la nueva copia se convierte entonces en la copia de la base de datos actual. La copia antigua de la base de datos se borra después. El esquema se describe en la Figura 15.2, en la cual se muestra el estado de la base de datos antes y después de la actualización. Se dice que la transacción está comprometida en el momento en que puntero_bd actualizado se escribe en disco. Considérese ahora la manera en que esta técnica trata los fallos de las transacciones y del sistema. En primer lugar, considérese un fallo en la transacción. Si la transacción falla en algún momento antes de actualizar puntero_bd, el contenido de la base de datos anterior no se ve afectado. Se puede abortar la transacción simplemente borrando la nueva copia de la base de datos. Una vez que se ha comprometido la transacción, puntero_bd apunta a todas las modificaciones que ésta ha realizado en la base de datos. De este modo, o todas las modificaciones de la transacción se ven reflejadas o ninguna de ellas, independientemente del fallo de la transacción. Considérese ahora el resultado de un fallo en el sistema. Supóngase que el sistema falla en algún momento antes de escribir en disco el puntero_bd actualizado. Entonces cuando se reinicie el sistema, leerá puntero_bd y verá el contenido original de la base de datos, y ninguno de los efectos de la transacción será visible en la base de datos. A continuación supóngase que el sistema falla después de actualizar en disco puntero_bd. Antes de que el puntero se actualice, todas las páginas actualizadas de la nueva copia de la base de datos se escriben en disco. De nuevo, se asume que una vez que un archivo se escribe en disco, su contenido no se daña incluso si hay un fallo del sistema. Por tanto, cuando el sistema se reinicie, leerá puntero_bd y verá el contenido de la base de datos después de la transacción haya realizado todas las modificaciones.

puntero_bd

copia anterior de la base de datos

(a) antes de la actualización Figura 15.2

puntero_bd

copia anterior de la base de datos (que será borrada)

nueva copia de la base de datos

(b) después de la actualización

Técnica de copia en la sombra para la atomicidad y durabilidad.

www.detodoprogramacion.com


15.4

Ejecuciones concurrentes

513

La implementación depende realmente de que escribir puntero_bd sea una operación atómica; es decir, o se escriben todos sus bytes o ninguno de ellos. Si se escribieran algunos de los bytes del puntero y otros no, el puntero no tendría sentido y al reiniciarse el sistema no se podrían encontrar ni la versión anterior ni la nueva de la base de datos. Afortunadamente los sistemas de disco proporcionan actualizaciones atómicas de bloques enteros, o al menos de un sector del disco. En otras palabras, el sistema de disco garantiza la actualización automática de puntero_bd siempre que se cumpla que puntero_bd quepa en un único sector, lo que se puede asegurar almacenándolo al comienzo de un bloque. De este modo, la implementación de la copia en la sombra del componente de gestión de recuperaciones asegura las propiedades de atomicidad y durabilidad de las transacciones. Como ejemplo simple fuera del dominio de las bases de datos, considérese una sesión de edición de texto. Una sesión completa de edición de texto puede modelar una transacción. Las acciones que ejecuta la transacción son leer y actualizar el archivo. Guardar el archivo cuando se termina de editar significa completar la transacción de edición; terminar la sesión de edición sin guardar el archivo significa abortar la transacción de edición. Muchos editores de texto usan fundamentalmente la implementación que se acaba de describir para asegurar que una sesión de edición es como una transacción. Se usa un nuevo archivo para almacenar las modificaciones. Al finalizar la sesión de edición, si el archivo modificado se va a guardar, se usa un comando para renombrar el nuevo archivo para que tenga el nombre del archivo actual. Se asume que el renombramiento está implementado como una operación atómica en el sistema de archivos, y que al mismo tiempo borra el archivo antiguo. Desafortunadamente, esta implementación es extremadamente ineficiente en el contexto de grandes bases de datos, ya que la ejecución de una simple transacción requiere copiar la base de datos completa. Además, la implementación no permite a las transacciones ejecutarse concurrentemente unas con otras. Existen formas prácticas de implementar la atomicidad y durabilidad que son mucho menos costosas y más potentes. Estas técnicas se estudian en el Capítulo 17.

15.4 Ejecuciones concurrentes

Los sistemas de procesamiento de transacciones permiten normalmente la ejecución de varias transacciones concurrentemente. Permitir varias transacciones que actualizan concurrentemente los datos provoca complicaciones en la consistencia de los mismos, como se ha visto antes. Asegurar la consistencia a pesar de la ejecución concurrente de las transacciones requiere un trabajo extra; es mucho más sencillo exigir que las transacciones se ejecuten secuencialmente —es decir, una a una, comenzado cada una sólo después de que la anterior se haya completado. Sin embargo, existen dos buenas razones para permitir la concurrencia: • Productividad y utilización de recursos mejoradas. Una transacción consiste en varios pasos. Algunos implican operaciones de E/S; otros implican operaciones de CPU. La CPU y los discos pueden trabajar en paralelo en una computadora. Por tanto, las operaciones de E/S se pueden realizar en paralelo con el procesamiento de la CPU. Se puede entonces explotar el paralelismo de la CPU y del sistema de E/S para ejecutar varias transacciones en paralelo. Mientras una transacción ejecuta una lectura o una escritura en un disco, otra puede ejecutarse en la CPU mientras una tercera transacción ejecuta una lectura o una escritura en otro disco. Todo esto incrementa la productividad (throughput) del sistema—es decir, en el número de transacciones que puede ejecutar en un tiempo dado. Análogamente, la utilización del procesador y del disco aumenta también; en otras palabras, el procesador y el disco están menos tiempo desocupados o sin hacer ningún trabajo útil. • Tiempo de espera reducido. Debe haber una mezcla de transacciones que se ejecutan en el sistema, algunas cortas y otras largas. Si las transacciones se ejecutan secuencialmente, la transacción corta debe esperar a que la transacción larga anterior se complete, lo cual puede llevar a un retardo impredecible en la ejecución de la transacción. Si las transacciones operan en partes diferentes de la base de datos es mejor hacer que se ejecuten concurrentemente, compartiendo los ciclos de la CPU y los accesos a disco entre ambas. La ejecución concurrente reduce los retardos im-

www.detodoprogramacion.com


514

Capítulo 15

Transacciones

predecibles en la ejecución de las transacciones. Además se reduce también el tiempo medio de respuesta: el tiempo medio desde que una transacción comienza hasta que se completa. La razón para usar la ejecución concurrente en una base de datos es esencialmente la misma que para usar multiprogramación en un sistema operativo. Cuando se ejecutan varias transacciones concurrentemente, la consistencia de la base de datos se puede destruir a pesar de que cada transacción individual sea correcta. En este apartado se presenta el concepto de planificaciones que ayudan a identificar aquellas ejecuciones que garantizan que se asegura la consistencia. El sistema de base de datos debe controlar la interacción entre las transacciones concurrentes para evitar que se destruya la consistencia de la base de datos. Esto se lleva a cabo a través de una serie de mecanismos denominados esquemas de control de concurrencia. En el Capítulo 16 se estudian los esquemas de control de concurrencia; por ahora nos centraremos en el concepto de ejecución concurrente correcta. Considérese de nuevo el sistema bancario simplificado del Apartado 15.1, el cual tiene varias cuentas, y un conjunto de transacciones que acceden y modifican dichas cuentas. Sean T1 y T2 dos transacciones para transferir fondos de una cuenta a otra. La transacción T1 transfiere 50 e de la cuenta A a la cuenta B y se define como sigue T1 : leer(A); A := A − 50; escribir(A); leer(B); B := B + 50; escribir(B). La transacción T2 transfiere el 10 por ciento del saldo de la cuenta A a la cuenta B, y se define T2 : leer(A); temp := A * 0.1; A := A − temp; escribir(A); leer(B); B := B + temp; escribir(B). Supóngase que los valores actuales de las cuentas A y B son 1.000 e y 2.000 e respectivamente. Supóngase que las dos transacciones se ejecutan de una en una en el orden T1 seguida de T2 . Esta secuencia de ejecución se representa en la Figura 15.3. En esta figura la secuencia de pasos o instrucciones aparece en orden cronológico de arriba abajo, con las instrucciones de T1 en la columna izquierda y las de T2 en la derecha. Los valores finales de las cuentas A y B, después de que tenga lugar la ejecución de la Figura 15.3, son de 855 e y de 2.145 e respectivamente. De este modo, la suma total de saldo de las cuentas A y B —es decir, la suma A + B —se conserva tras la ejecución de ambas transacciones. Análogamente, si las transacciones se ejecutan de una en una en el orden T2 seguida de T1 , entonces la secuencia de ejecución es la de la Figura 15.4. De nuevo, como se esperaba, se conserva la suma A + B y los valores finales de las cuentas A y B son de 850 e y de 2.150 e respectivamente. Las secuencias de ejecución que se acaban de describir se denominan planificaciones. Representan el orden cronológico en el que se ejecutan las instrucciones en el sistema. Obviamente una planificación para un conjunto de transacciones debe consistir en todas las instrucciones de dichas transacciones, y debe conservar el orden en que aparecen las instrucciones en cada transacción individual. Por ejemplo, en la transacción T1 la instrucción escribir(A) debe aparecer antes de la instrucción leer(B) en cualquier planificación válida. En los párrafos siguientes, planificación 1 se referirá a la primera secuencia de ejecución (T1 seguida de T2 ) y planificación 2 a la segunda secuencia de ejecución (T2 seguida de T1 ). Estas planificaciones son secuenciales. Cada planificación secuencial consiste en una secuencia de instrucciones de varias transacciones, en la cual las instrucciones pertenecientes a una única transac-

www.detodoprogramacion.com


15.4

T1 leer(A) A := A - 50 escribir(A) leer(B) B := B + 50 escribir(B)

Ejecuciones concurrentes

515

T2

leer(A) temp := A ∗ 0, 1 A := A - temp escribir(A) leer(B) B := B + temp escribir(B) Figura 15.3

Planificación 1 —una planificación secuencial en la que T2 sigue a T1 .

ción están juntas en dicha planificación. De este modo, para un conjunto de n transacciones existen n! planificaciones secuenciales válidas distintas. Cuando el sistema de bases de datos ejecuta concurrentemente varias transacciones, la planificación correspondiente no tiene por qué ser secuencial. Si dos transacciones se ejecutan concurrentemente, el sistema operativo puede ejecutar una transacción durante un tiempo pequeño, luego realizar un cambio de contexto, ejecutar la segunda transacción durante un tiempo, cambiar de nuevo a la primera transacción durante un tiempo y así sucesivamente. Si hay muchas transacciones, todas ellas comparten el tiempo de la CPU. Son posibles muchas secuencias de ejecución, puesto que varias instrucciones de ambas transacciones se pueden intercalar. En general no es posible predecir exactamente cuántas instrucciones se ejecutarán antes de que la CPU cambie a otra transacción. Así, el número de planificaciones posibles para un conjunto de n transacciones es mucho mayor que n!. Volviendo al ejemplo anterior supóngase que las dos transacciones se ejecutan concurrentemente. Una posible planificación se muestra en la Figura 15.5. Una vez que la ejecución tiene lugar, se llega al mismo estado que cuando las transacciones se ejecutan secuencialmente en el orden T1 seguida de T2 . La suma A + B se conserva igualmente. No todas las ejecuciones concurrentes producen un estado correcto. Como ejemplo de esto considérese la planificación de la Figura 15.6. Después de ejecutarse esta planificación se llega a un estado cuyos valores finales de las cuentas A y B son de 950 e y de 2.100 e respectivamente. Este estado final es

T1

T2 leer(A) temp := A ∗ 0, 1 A := A - temp escribir(A) leer(B) B := B + temp escribir(B)

leer(A) A := A - 50 escribir(A) leer(B) B := B + 50 escribir(B) Figura 15.4

Planificación 2 —una planificación secuencial en la cual T1 sigue a T2 .

www.detodoprogramacion.com


516

Capítulo 15

Transacciones

T1 leer(A) A := A - 50 escribir(A)

T2

leer(A) temp := A ∗ 0, 1 A := A - temp escribir(A) leer(B) B := B + 50 escribir(B) leer(B) B := B + temp escribir(B) Figura 15.5

Planificación 3—una planificación concurrente equivalente a la planificación 1.

un estado inconsistente, ya que se han ganado 50 e al procesar la ejecución concurrente. Realmente la ejecución de las dos transacciones no conserva la suma A + B. Si se deja el control de la ejecución concurrente completamente al sistema operativo son posibles muchas planificaciones, incluyendo las que dejan a la base de datos en un estado inconsistente, como la que se acaba de describir. Es una tarea del sistema de base de datos asegurar que cualquier planificación que se ejecute lleva a la base de datos a un estado consistente. El componente del sistema de base de datos que realiza esta tarea se denomina componente de control de concurrencia. Se puede asegurar la consistencia de la base de datos en una ejecución concurrente si se está seguro de que cualquier planificación que se ejecute tiene el mismo efecto que otra que se hubiese ejecutado sin concurrencia. Es decir, la planificación debe ser, en cierto modo, equivalente a una planificación secuencial. Esta idea se examina en el Apartado 15.5.

15.5 Secuencialidad

El sistema de base de datos debe controlar la ejecución concurrente de las transacciones para asegurar que el estado de la base sigue siendo consistente. Antes de examinar cómo debe realizar esta tarea el sistema de base de datos hay que entender primero las planificaciones que aseguran la consistencia y las que no.

T1 leer(A) A := A - 50

T2

leer(A) temp := A ∗ 0, 1 A := A - temp escribir(A) leer(B) escribir(A) leer(B) B := B + 50 escribir(B) B := B + temp escribir(B) Figura 15.6

Planificación 4 —una planificación concurrente.

www.detodoprogramacion.com


15.5

Secuencialidad

517

Puesto que las transacciones son programas, es difícil calcular cuáles son las operaciones exactas que realiza una transacción y cómo interaccionan las operaciones de varias transacciones. Por este motivo no se van a interpretar los tipos de operaciones que puede realizar una transacción sobre un elemento de datos. En lugar de esto se consideran sólo dos operaciones: leer y escribir. Se asume así que entre una instrucción leer(Q) y otra escribir(Q) sobre un elemento de datos Q, una transacción puede realizar una secuencia arbitraria de operaciones con la copia Q que reside en la memoria intermedia local de dicha transacción. De este modo las únicas operaciones significativas de la transacción son, desde el punto de vista de la planificación, las instrucciones leer y escribir. Por tanto, normalmente sólo se mostrarán las instrucciones leer y escribir en las planificaciones, como se muestra en la planificación 3 de la Figura 15.7. En este apartado se estudian diferentes formas de equivalencia de planificación; esto lleva a los conceptos de secuencialidad en cuanto a conflictos y secuencialidad en cuanto a vistas. 15.5.1 Secuencialidad en cuanto a con ictos

Considérese una planificación P en la cual hay dos instrucciones consecutivas Ii e Ij , pertenecientes a las transacciones Ti y Tj respectivamente (i 6= j). Si Ii e Ij se refieren a distintos elementos de datos se pueden intercambiar Ii e Ij sin afectar al resultado de cualquier instrucción de la planificación. Sin embargo, si Ii e Ij se refieren al mismo elemento Q entonces el orden de los dos pasos puede ser importante. Puesto que sólo se tienen en cuenta las instrucciones leer y escribir se deben considerar cuatro casos: 1. Ii = leer(Q), Ij = leer(Q). El orden de Ii e Ij no importa, puesto que Ti y Tj leen el mismo valor de Q, independientemente del orden. 2. Ii = leer(Q), Ij = escribir(Q). Si Ii está antes que Ij , entonces Ti no lee el valor de Q que escribe la instrucción Ij de Tj . Si Ij está antes que Ii , entonces Ti lee el valor de Q escrito por Tj . Por tanto, orden de Ii e Ij es importante. 3. Ii = escribir(Q), Ij = leer(Q). El orden de Ii e Ij es importante por razones similares a las del caso anterior. 4. Ii = escribir(Q), Ij = escribir(Q). Puesto que ambas instrucciones son operaciones escribir el orden de dichas instrucciones no afecta ni a Ti ni a Tj . Sin embargo, el valor que obtendrá la siguiente instrucción leer(Q) de P sí se ve afectado, ya que únicamente se conserva en la base de datos la última de las dos instrucciones escribir. Si no hay ninguna otra instrucción escribir(Q) después de Ii e Ij en P, entonces el orden de Ii e Ij afecta directamente al valor final de Q en el estado de la base de datos que se obtiene con la planificación P. De esta manera sólo en el caso en el cual Ii e Ij son instrucciones leer no tiene importancia el orden de ejecución de las mismas. Se dice que Ii e Ij están en conflicto si existen operaciones de diferentes transacciones sobre el mismo elemento de datos, y al menos una de esas instrucciones es una operación escribir.

T1 leer(A) escribir(A)

T2

leer(A) escribir(A) leer(B) escribir(B) leer(B) escribir(B) Figura 15.7

Planificación 3 —sólo se muestran las instrucciones leer y escribir.

www.detodoprogramacion.com


518

Capítulo 15

Transacciones

T1 leer(A) escribir(A)

T2

leer(A) leer(B) escribir(A) escribir(B) leer(B) escribir(B) Figura 15.8

Planificación 5—planificación 3 después de intercambiar un par de instrucciones.

Para ilustrar el concepto de instrucciones conflictivas considérese la planificación 3 mostrada en la Figura 15.7. La instrucción escribir(A) de T1 está en conflicto con la instrucción leer(A) de T2 . Sin embargo, la instrucción escribir(A) de T2 no está en conflicto con la instrucción leer(B) de T1 , ya que las dos instrucciones acceden a diferentes elementos de datos. Sean Ii e Ij instrucciones consecutivas de una planificación P. Si Ii e Ij son instrucciones de transacciones diferentes y además Ii e Ij no están en conflicto, entonces se puede cambiar el orden de Ii e Ij para obtener una nueva planificación P 0 . Lo esperado es que P sea equivalente a P 0 , ya que todas las instrucciones aparecen en el mismo orden en ambas planificaciones salvo Ii e Ij , cuyo orden no es importante. Puesto que la instrucción escribir(A) de T2 en la planificación 3 de la Figura 15.7 no está en conflicto con la instrucción leer(B) de T1 , se pueden intercambiar dichas instrucciones para generar una planificación equivalente, la planificación 5, que se muestra en la Figura 15.8. Independientemente de cuál sea el estado inicial del sistema, las planificaciones 3 y 5 producen el mismo estado final del sistema. Se puede continuar intercambiando instrucciones no conflictivas como sigue: • Intercambiar la instrucción leer(B) de T1 con la instrucción leer(A) de T2 . • Intercambiar la instrucción escribir(B) de T1 con la instrucción escribir(A) de T2 . • Intercambiar la instrucción escribir(B) de T1 con la instrucción leer(A) de T2 . El resultado final de estos intercambios, como se muestra en la Figura 15.9, es una planificación secuencial. Así se muestra que la planificación 3 es equivalente a una planificación secuencial. Esta equivalencia implica que independientemente del estado inicial, la planificación 3 produce el mismo estado final que una planificación secuencial. Si una planificación P se puede transformar en otra P’ por medio de una serie de intercambios de instrucciones no conflictivas, se dice que P y P’ son equivalentes en cuanto a conflictos. Volviendo a los ejemplos anteriores, se observa que la planificación 1 no es equivalente en cuanto a conflictos a la planificación 2. Sin embargo, la planificación 1 es equivalente en cuanto a conflictos a la

T1 leer(A) escribir(A) leer(B) escribir(B)

T2

leer(A) escribir(A) leer(B) escribir(B) Figura 15.9

Planificación 6—una planificación secuencial equivalente a la planificación 3.

www.detodoprogramacion.com


15.5

T3 leer(Q)

Secuencialidad

519

T4 escribir(Q)

escribir(Q) Figura 15.10

Planificación 7.

planificación 3, puesto que las instrucciones leer(B) y escribir(B) de T1 se pueden intercambiar con las instrucciones leer(A) y escribir(A) de T2 . El concepto de equivalencia en cuanto a conflictos lleva al concepto de secuencialidad en cuanto a conflictos. Se dice que una planificación P es secuenciable en cuanto a conflictos si es equivalente en cuanto a conflictos a una planificación secuencial. Así, la planificación 3 es secuenciable en cuanto a conflictos, ya que es equivalente en cuanto a conflictos a la planificación secuencial 1. Finalmente considérese la planificación 7 de la Figura 15.10; sólo consta de las operaciones significativas de las transacciones T3 y T4 (es decir, leer y escribir). Esta planificación no es secuenciable en cuanto a conflictos, ya que no es equivalente ni a la planificación secuencial <T3 ,T4 > ni a <T4 ,T3 >. Es posible encontrar dos planificaciones que produzcan el mismo resultado y que no sean equivalentes en cuanto a conflictos. Por ejemplo, considérese la transacción T5 , la cual transfiere 10 e de la cuenta B a la A. Sea la planificación 8 la que se define en la Figura 15.11. Se puede afirmar que la planificación 8 no es equivalente en cuanto a conflictos a la planificación secuencial <T1 ,T5 >, ya que en la planificación 8 la instrucción escribir(B) de T5 está en conflicto con la instrucción leer(B) de T1 . Por este motivo no se pueden colocar todas las instrucciones de T1 antes de las de T5 intercambiando instrucciones no conflictivas consecutivas. Sin embargo, los valores finales de las cuentas A y B son los mismos después de ejecutar tanto la planificación 8 como la planificación secuencial <T1 ,T5 > —esto es, 960 e y 2.040 e respectivamente. Con este ejemplo se puede observar que existen definiciones de equivalencia de planificaciones que son menos rigurosas que la de equivalencia en cuanto a conflictos. Para que el sistema pueda determinar que el resultado de la planificación sea el mismo que el de la planificación secuencial <T1 ,T5 >, debe analizar los cálculos realizados por T1 y T5 , en lugar de tener sólo en cuenta las operaciones leer y escribir. En general es difícil de implementar tal análisis y es costoso en términos de cómputo. Sin embargo, existen otras definiciones de equivalencia de planificación que se basan únicamente en las operaciones leer y escribir. En el siguiente apartado se considera una de estas definiciones.

∗∗

15.5.2 Secuencialidad en cuanto a vistas

En este apartado se va a considerar una forma de equivalencia que es menos rigurosa que la equivalencia en cuanto a conflictos pero que, al igual que ésta, se basa únicamente en las operaciones leer y escribir de las transacciones.

T1 leer(A) A := A - 50 escribir(A)

T5

leer(B) B := B - 10 escribir(B) leer(B) B := B + 50 escribir(B) leer(A) A := A + 10 escribir(A) Figura 15.11

Planificación 8.

www.detodoprogramacion.com


520

Capítulo 15

Transacciones

Considérense dos planificaciones, P y P 0 , en las cuales participa el mismo conjunto de transacciones. Se dice que las planificaciones P y P 0 son equivalentes en cuanto a vistas si se cumplen las tres condiciones siguientes: 1. Para todo elemento de datos Q, si la transacción Ti lee el valor inicial de Q en la planificación P , entonces Ti debe leer también el valor inicial de Q en la planificación P 0 . 2. Para todo elemento de datos Q, si la transacción Ti ejecuta leer(Q) en la planificación P y el valor lo ha producido la transacción Tj (si existe dicha transacción) entonces, en la planificación P 0 , la transacción Ti debe leer también el valor de Q que haya producido la transacción Tj . 3. Para todo elemento de datos Q, la transacción (si existe) que realice la última operación escribir(Q) en la planificación P , debe realizar la última operación escribir(Q) en la planificación P 0 . Las condiciones 1 y 2 aseguran que cada transacción lee los mismos valores en ambas planificaciones y por tanto realizan los mismos cálculos. La condición 3, junto con las condiciones 1 y 2, asegura que ambas planificaciones producen como resultado el mismo estado final del sistema. Volviendo a los ejemplos anteriores, obsérvese que la planificación 1 no es equivalente en cuanto a vistas a la planificación 2, ya que en la planificación 1 el valor de la cuenta A que lee la transacción T2 lo produce T1 , mientras que esto no ocurre en la planificación 2. Sin embargo, la planificación 1 es equivalente en cuanto a vistas a la planificación 3, ya que los valores de las cuentas A y B que lee la transacción T2 los produce T1 en ambas planificaciones. El concepto de equivalencia en cuanto a vistas lleva al concepto de secuencialidad en cuanto a vistas. Se dice que la planificación P es secuenciable en cuanto a vistas si es equivalente en cuanto a vistas a una planificación secuencial. Como ejemplo supóngase que se aumenta la planificación 7 con la transacción T6 y se obtiene la planificación 9, tal y como se muestra en la Figura 15.12. La planificación 9 es secuenciable en cuanto a vistas. Realmente es equivalente en cuanto a vistas a la planificación secuencial <T3 , T4 , T6 >, ya que la instrucción leer(Q) lee el valor inicial de Q en ambas planificaciones, y T6 realiza la escritura final de Q en ambas planificaciones. Toda planificación secuenciable en cuanto a conflictos es secuenciable en cuanto a vistas, pero existen planificaciones secuenciables en cuanto a vistas que no son secuenciables en cuanto a conflictos. Realmente, la planificación 9 no es secuenciable en cuanto a conflictos puesto que para todo par de instrucciones, éstas están en conflicto y por tanto no es posible ningún intercambio de instrucciones. Obsérvese que en la planificación 9, las transacciones T4 y T6 realizan operaciones escribir(Q) sin haber realizado ninguna operación leer(Q). Este tipo de escrituras se denominan escrituras a ciegas. Las escrituras a ciegas aparecen en toda planificación secuenciable en cuanto a vistas que no sea secuenciable en cuanto a conflictos. 15.6 Recuperabilidad

Antes se han estudiado las planificaciones que son aceptables desde el punto de vista de la consistencia de la base de datos asumiendo implícitamente que no había fallos en las transacciones. Ahora se va a estudiar el efecto de los fallos en una transacción durante una ejecución concurrente. Si la transacción Ti falla, por la razón que sea, es necesario deshacer el efecto de dicha transacción para asegurar la propiedad de atomicidad de la misma. En un sistema que permita la concurrencia es necesario asegurar también que toda transacción Tj que dependa de Ti (es decir, Tj lee datos que ha

T3 leer(Q)

T4

T6

escribir(Q) escribir(Q) escribir(Q) Figura 15.12

Planificación 9 —una planificación secuenciable en cuanto a vistas.

www.detodoprogramacion.com


15.6

T8 leer(A) escribir(A)

Recuperabilidad

521

T9

leer(A) leer(B) Figura 15.13

Planificación 10.

escrito Ti ) se aborta también. Para alcanzar esta garantía, es necesario poner restricciones al tipo de planificaciones permitidas en el sistema. En los dos subapartados siguientes se estudian las planificaciones que son aceptables desde el punto de vista que se ha descrito. Como ya se dijo antes, en el Capítulo 16 se describe la manera de asegurar que sólo se generan dichas planificaciones aceptables. 15.6.1 Plani caciones recuperables

Considérese la planificación 10 que se muestra en la Figura 15.13, en la cual la transacción T9 realiza sólo una instrucción: leer(A). Supóngase que el sistema permite que T9 se complete inmediatamente después de ejecutar la instrucción leer(A). Así se completa T9 antes de que lo haga T8 . Supóngase ahora que T8 falla antes de completarse. Puesto que T9 ha leído el valor del elemento de datos A escrito por T8 , se debe abortar T9 para asegurar la atomicidad de la transacción. Sin embargo, T9 ya se ha comprometido y no puede abortarse. De este modo se llega a una situación en la cual es imposible recuperarse correctamente del fallo de T8 . La planificación 10, cuyo compromiso tiene lugar inmediatamente después de ejecutar la instrucción leer(A), es un ejemplo de planificación no recuperable, la cual no debe permitirse. La mayoría de los sistemas de bases de datos requieren que todas las planificaciones sean recuperables. Una planificación recuperable es aquélla en la que para todo par de transacciones Ti y Tj tales que Tj lee elementos de datos que ha escrito previamente Ti , la operación comprometer de Ti aparece antes que la de Tj . 15.6.2 Plani caciones sin cascada

Incluso si una planificación es recuperable, hay que retroceder varias transacciones para recuperar correctamente el estado previo a un fallo en una transacción Ti . Tales situaciones ocurren si las transacciones leen datos que ha escrito Ti . Como ejemplo considérese la planificación parcial de la Figura 15.14. La transacción T10 escribe un valor de A que lee la transacción T11 . La transacción T11 escribe un valor de A que lee la transacción T12 . Supóngase que en ese momento falla T10 . Se debe retroceder T10 . Puesto que T11 depende de T10 , se debe retroceder T11 . Puesto que T12 depende de T11 , se debe retroceder T12 . Este fenómeno en el cual un fallo en una única transacción provoca una serie de retrocesos de transacciones se denomina retroceso en cascada. No es deseable el retroceso en cascada, ya que provoca un aumento significativo del trabajo necesario para deshacer cálculos. Es deseable restringir las planificaciones a aquéllas en las que no puedan ocurrir retrocesos en cascada. Tales planificaciones se denominan planificaciones sin cascada. Una planificación sin cascada es aquélla para la que todo par de transacciones Ti y Tj tales que Tj lee un elemento de

T10 leer(A) leer(B) escribir(A)

T11

T12

leer(A) escribir(A) leer(A) Figura 15.14

Planificación 11.

www.detodoprogramacion.com


522

Capítulo 15

Transacciones

datos que ha escrito previamente Ti , la operación comprometer de Ti aparece antes que la operación de lectura de Tj . Es sencillo comprobar que toda planificación sin cascada es también recuperable. 15.7 Implementación del aislamiento

Antes se han visto las propiedades que debe tener una planificación para dejar a la base de datos en un estado consistente y para permitir fallos en la transacción que se puedan manejar de una manera segura. En concreto, las planificaciones que son secuenciables en cuanto a conflictos o secuenciables en cuanto a vistas y sin cascada cumplen estos requisitos. Existen varios esquemas de control de concurrencia que se pueden utilizar para asegurar que, incluso si se ejecutan concurrentemente muchas transacciones, sólo se generen planificaciones aceptables sin tener en cuenta la forma en que el sistema operativo comparte en el tiempo los recursos (tales como el tiempo de CPU) entre las transacciones. Como ejemplo trivial de esquema de control de concurrencia considérese éste: una transacción realiza un bloqueo en la base de datos completa antes de comenzar y lo libera después de haberse comprometido. Mientras una transacción mantiene el bloqueo, no se permite que ninguna otra lo obtenga, y todas ellas deben esperar hasta que se libere el bloqueo. Como resultado de esta política de bloqueo, sólo se puede ejecutar una transacción cada vez. Por tanto, sólo se generan planificaciones secuenciales. Éstas son obviamente secuenciables y es sencillo probar que también son sin cascada. Un esquema de control de concurrencia como éste produce un rendimiento pobre, ya que fuerza a que las transacciones esperen a que finalicen las precedentes para poder comenzar. En otras palabras, produce un grado de concurrencia pobre. Como se ha explicado en el Apartado 15.4, la ejecución concurrente presenta varios beneficios para el rendimiento. El objetivo de los esquemas de control de concurrencia es proporcionar un elevado grado de concurrencia, al mismo tiempo que aseguran que todas las planificaciones que se generan son secuenciables en cuanto a conflictos o en cuanto a vistas y son sin cascada. En el Capítulo 16 se estudian gran número de esquemas de control de concurrencia. Los esquemas adoptan diferentes compromisos en función del aumento de concurrencia que permiten y del aumento de coste en el que incurren. Algunos permiten que se generen planificaciones secuenciables en cuanto a conflictos; otros permiten que se generen planificaciones secuenciables en cuanto a vistas que no son secuenciables en cuanto a conflictos.

15.8 Comprobación de la secuencialidad

Cuando se diseñan esquemas de control de concurrencia es necesario que demostrar que las planificaciones que genera el esquema son secuenciables. Para lograrlo se debe entender primero la forma de determinar si, dada una planificación concreta P , es secuenciable. A continuación se presenta un método simple y eficiente de determinar la secuencialidad en cuanto a conflictos de una planificación. Considérese una planificación P . Se construye un grafo dirigido, llamado grafo de precedencia para P . Este grafo consiste en un par G = (V,A), siendo V un conjunto de vértices y A un conjunto de arcos. El conjunto de vértices consiste en todas las transacciones que participan en la planificación. El conjunto de arcos consiste en todos los arcos Ti → Tj para los cuales se dan una de las tres condiciones siguientes: 1. Ti ejecuta escribir(Q) antes de que Tj ejecute leer(Q). 2. Ti ejecuta leer(Q) antes de que Tj ejecute escribir(Q). 3. Ti ejecuta escribir(Q) antes de que Tj ejecute escribir(Q). Si existe un arco Ti → Tj en el grafo de precedencia , entonces en toda planificación secuencial P 0 equivalente a P , Ti debe aparecer antes de Tj . Por ejemplo, en la Figura 15.15a se muestra el grafo de precedencia de la planificación 1. Sólo contiene el arco T1 → T2 , puesto que todas las instrucciones de T1 se ejecutan antes de que lo haga la primera de

www.detodoprogramacion.com


15.9

T1

T2

T2

523

T1 (b)

(a) Figura 15.15

Resumen

Grafo de precedencia para (a) la planificación 1 y (b) la planificación 2.

T2 . Análogamente, la Figura 15.15b muestra el grafo de precedencia de la planificación 2 con el único arco T2 → T1 , ya que todas las instrucciones de T2 se ejecutan antes de que lo haga la primera de T1 . El grafo de precedencia de la planificación 4 se representa en la Figura 15.16. Contiene el arco T1 → T2 debido a que T1 ejecuta leer(A) antes de que T2 ejecute escribir(A). También contiene el arco T2 → T1 debido a que T2 ejecuta leer(B) antes de que T1 ejecute escribir(B). Si el grafo de precedencia de P tiene un ciclo, entonces la planificación P no es secuenciable en cuanto a conflictos. Si el grafo no contiene ciclos, entonces la planificación P es secuenciable en cuanto a conflictos. El orden de secuencialidad se puede obtener a través de la ordenación topológica, la cual determina un orden lineal que consiste en el orden parcial del grafo de precedencia. En general se pueden obtener muchos órdenes lineales posibles a través de la ordenación topológica. Por ejemplo, el grafo de la Figura 15.17a tiene dos órdenes lineales aceptables, como se observa en las Figuras 15.17b y 15.17c. Así, para probar la secuencialidad en cuanto a conflictos es necesario construir el grafo de precedencia e invocar a un algoritmo de detección de ciclos. Los algoritmos de detección de ciclos se pueden consultar en cualquier libro de texto sobre algoritmos. Los algoritmos de detección de ciclos, tales como los que se basan en la búsqueda primero en profundidad, requieren del orden de n2 operaciones, siendo n el número de vértices del grafo (es decir, el número de transacciones). De este modo se consigue un esquema práctico para determinar la secuencialidad en cuanto a conflictos. Volviendo a los ejemplos anteriores, obsérvese que los grafos de precedencia para las planificaciones 1 y 2 (Figura 15.15) no contienen ciclos. El grafo de precedencia para la planificación 4 (Figura 15.16) sin embargo, contiene ciclos, lo que indica que esta planificación no es secuenciable en cuanto a conflictos. La comprobación de la secuencialidad en cuanto a vistas es más complicada. De hecho, se ha demostrado que el problema de determinar la secuencialidad en cuanto a vistas es NP-completo. Por tanto, seguramente no exista ningún algoritmo eficiente para comprobar la secuencialidad en cuanto a vistas. Véanse la notas bibliográficas para consultar referencias sobre ello. Sin embargo, los esquemas de control de concurrencia aún pueden utilizar condiciones suficientes para la secuencialidad en cuanto a vistas. Es decir, si se cumplen las condiciones suficientes, la planificación es secuencialidad en cuanto a vistas, pero puede haber algunas planificaciones secuencialidad en cuanto a vistas que no satisfagan las condiciones suficientes. 15.9 Resumen

• Una transacción es una unidad de la ejecución de un programa que accede y posiblemente actualiza varios elementos de datos. Es fundamental comprender el concepto de transacción para entender e implementar las actualizaciones de los datos en una base de datos, de manera que las ejecuciones concurrentes y los fallos de varios tipos no den como resultado que la base de datos se vuelva inconsistente. • Es necesario que las transacciones tengan las propiedades ACID: atomicidad, consistencia, aislamiento y durabilidad.

T1

Figura 15.16

T2

Grafo de precedencia para la planificación 4.

www.detodoprogramacion.com


524

Capítulo 15

Transacciones

Ti Tj

Tk Tm (a)

Figura 15.17

Ti

Ti

Tj

Tk

Tk

Tj

Tm

Tm

(b)

(c)

Ilustración de la ordenación topológica.

¤ La atomicidad asegura que, o bien todos los efectos de la transacción se reflejan en la base de datos, o bien ninguno de ellos; un fallo no puede dejar a la base de datos en un estado en el cual una transacción se haya ejecutado parcialmente. ¤ La consistencia asegura que si la base de datos es consistente inicialmente, la ejecución de la transacción (debido a la misma) deja la base de datos en un estado consistente. ¤ El aislamiento asegura que en la ejecución concurrente de transacciones, están aisladas entre si, de tal manera que cada una tiene la impresión de que ninguna otra transacción se ejecuta concurrentemente con ella. ¤ La durabilidad asegura que, una vez que la transacción se ha comprometido, las actualizaciones hechas por la transacción no se pierden incluso si hay un fallo del sistema. • La ejecución concurrente de transacciones mejora la productividad y la utilización del sistema, y también reduce el tiempo de espera de las transacciones. • Cuando varias transacciones se ejecutan concurrentemente en la base de datos, puede que deje de conservarse la consistencia de los datos. Es por tanto necesario que el sistema controle la interacción entre las transacciones concurrentes. ¤ Puesto que una transacción es una unidad que conserva la consistencia, una ejecución secuencial de transacciones garantiza que se conserve dicha consistencia. ¤ Una planificación captura las acciones clave de las transacciones que afectan a la ejecución concurrente, tales como las operaciones leer y escribir, a la vez que se abstraen los detalles internos de la ejecución de la transacción. ¤ Es necesario que toda planificación producida por el procesamiento concurrente de un conjunto de transacciones tenga el efecto equivalente a una planificación en la cual esas transacciones se ejecutan secuencialmente en un cierto orden. ¤ Un sistema que asegure esta propiedad se dice que asegura la secuencialidad. ¤ Existen varias nociones distintas de equivalencia que llevan a los conceptos de secuencialidad en cuanto a conflictos y secuencialidad en cuanto a vistas.

www.detodoprogramacion.com


Ejercicios prácticos

525

• Se puede asegurar la secuencialidad de las planificaciones generadas por la ejecución concurrente de transacciones por medio de una gran variedad de mecanismos llamados esquemas de control de concurrencia. • Las planificaciones deben ser recuperables para asegurar que si la transacción a observa los efectos de la transacción b y ésta aborta, entonces a también se aborte. • Las planificaciones deben ser preferentemente sin cascada para que el hecho de abortar una transacción no provoque abortos en cascada de otras transacciones. • El componente de gestión de control de concurrencia de la base de datos es el responsable de manejar los esquemas de control de concurrencia. En el Capítulo 16 se describen esquemas de control de concurrencia. • El componente de gestión de recuperaciones de la base de datos es el responsable de asegurar las propiedades de las transacciones de atomicidad y durabilidad. El esquema de copia en la sombra se usa para asegurar la atomicidad y durabilidad en los editores de texto; sin embargo, tiene sobrecargas extremadamente altas cuando se usa en los sistemas de bases de datos y, más aún, no soporta la ejecución concurrente. El Capítulo 17 trata esquemas mejores. • Se puede comprobar si una planificación es secuenciable en cuanto a conflictos construyendo el grafo de precedencia para dicha planificación y viendo que no hay ciclos en el grafo. Sin embargo, hay esquemas de control de concurrencia más eficientes para asegurar la secuencialidad.

Términos de repaso

• Transacción.

• Ejecuciones concurrentes.

• Propiedades ACID:

• Ejecución secuencial.

¤ ¤ ¤ ¤

• Planificaciones.

Atomicidad. Consistencia. Aislamiento. Durabilidad.

• Conflictos entre operaciones. • Equivalencia en cuanto a conflictos. • Secuencialidad en cuanto a conflictos.

• Estado inconsistente.

• Equivalencia en cuanto a vistas.

• Estados de una transacción: ¤ ¤ ¤ ¤ ¤ ¤

Activa. Parcialmente comprometida. Fallida. Abortada. Comprometida. Terminada.

• Transacción.

• Secuencialidad en cuanto a vistas. • Escrituras a ciegas. • Recuperabilidad. • Planificaciones recuperables. • Retroceso en cascada. • Planificaciones sin cascada. • Esquema de control de concurrencia.

¤ Reiniciar. ¤ Cancelar.

• Bloqueo. • Determinación de la secuencialidad.

• Escrituras externas observables.

• Grafo de precedencia.

• Esquema de copia en la sombra.

• Orden de secuencialidad.

Ejercicios prácticos

15.1 Supóngase que existe un sistema de base de datos que nunca falla. ¿Se necesita un gestor de recuperaciones para este sistema?

www.detodoprogramacion.com


526

Capítulo 15

Transacciones

15.2 Considérese un sistema de archivos como el de su sistema operativo preferido. a. ¿Cuáles son los pasos involucrados en la creación y borrado de archivos, y en la escritura de datos a archivos? b. Explíquese por qué son relevantes los aspectos de atomicidad y durabilidad en la creación y borrado de archivos, y en la escritura de datos a archivos. 15.3 Los implementadores de sistemas de bases de datos prestan mucha más atención a las propiedades ACID que los implementadores de sistemas de archivos. ¿Por qué tiene sentido esto? 15.4 Justifíquese lo siguiente. La ejecución concurrente de transacciones es más importante cuando los datos se deben extraer de disco (lento) o cuando las transacciones duran mucho, y es menos importante cuando hay pocos datos en memoria y las transacciones son muy cortas. 15.5 Puesto que toda planificación secuenciable en cuanto a conflictos es secuenciable en cuanto a vistas, ¿por qué se hace hincapié en la secuencialidad en cuanto a conflictos en vez de en la secuencialidad en cuanto a vistas? 15.6 Considérese el grafo de precedencia de la Figura 15.18. ¿Es secuenciable en cuanto a conflictos la planificación correspondiente? Razónese la respuesta. 15.7 ¿Qué es una planificación sin cascada? ¿Por qué es conveniente la planificación sin cascada? ¿Hay circunstancias bajo las cuales puede ser conveniente permitir planificaciones que no sean sin cascada? Razónese la respuesta. Ejercicios

15.8 Lístense las propiedades ACID. Explíquese la utilidad de cada una. 15.9 Durante su ejecución, una transacción pasa a través de varios estados hasta que se compromete o aborta. Lístense todas las secuencias posibles de estados por los que puede pasar una transacción. Explíquese por qué puede ocurrir cada una de las transiciones de estados. 15.10 Explíquese la diferencia entre los términos planificación secuencial y planificación secuenciable. 15.11 Considérense las dos transacciones siguientes: T1 : leer(A); leer(B); if A = 0 then B := B + 1; escribir(B). T2 : leer(B); leer(A); if B = 0 then A := A + 1; escribir(A). Sea el requisito de consistencia A = 0 ∨ B = 0, siendo los valores iniciales A = B = 0.

T1

T2

T4

T3 T5

Figura 15.18

Grafo de precedencia.

www.detodoprogramacion.com


Notas bibliográficas

527

a. Demuéstrese que toda ejecución secuencial en la que aparezcan estas transacciones conserva la consistencia de la base de datos. b. Muéstrese una ejecución concurrente de T1 y T2 que produzca una planificación no secuenciable. c. ¿Existe una ejecución concurrente de T1 y T2 que produzca una planificación secuenciable? 15.12 ¿Qué es una planificación recuperable? ¿Por qué es conveniente la recuperabilidad de las planificaciones? ¿Hay circunstancias bajo las cuales puede ser conveniente permitir planificaciones no recuperables? Razónese la respuesta. 15.13 ¿Por qué los sistemas de bases de datos permiten la ejecución concurrente de transacciones, a pesar del esfuerzo de programación necesario para asegurar que la ejecución concurrente no causa ningún problema? Notas bibliográ cas

Gray y Reuter [1993] proporcionan un extenso tratamiento de los conceptos y técnicas de procesamiento de transacciones, técnicas y detalles de implementación, incluyendo resultados de recuperación y control de concurrencia. Bernstein y Newcomer [1997] proporcionan varios aspectos del procesamiento de transacciones. Los primeros estudios del control de concurrencia y la recuperación se incluyen en los libros Papadimitriou [1986] y Bernstein et al. [1987]. En Gray [1978] se presenta una visión de conjunto sobre resultados de implementación de control de concurrencia y recuperación. El concepto de secuencialidad se formuló en Eswaran et al. [1976] en conexión con su trabajo sobre control de concurrencia para System R. Los resultados sobre la determinación de secuencialidad y NPcompletitud de la determinación de la secuencialidad en cuanto a vistas son de Papadimitriou et al. [1977] y Papadimitriou [1979]. Los algoritmos de detección de ciclos se pueden encontrar en libros de algoritmos estándar, como en Cormen et al. [1990]. Otras referencias que cubren aspectos específicos de procesamiento de transacciones, tales como control de concurrencia y recuperación, se citan en los Capítulos 16, 17 y 25.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

16

Control de concurrencia

En el Capítulo 15 se estudió que una de las propiedades fundamentales de las transacciones es el aislamiento. Cuando se ejecutan varias transacciones concurrentemente en la base de datos, puede que deje de conservarse la propiedad de aislamiento. Es necesario que el sistema controle la interacción entre las transacciones concurrentes; dicho control se lleva a cabo a través de uno de los muchos mecanismos existentes llamado esquema de control de concurrencia. Todos los esquemas de control de concurrencia que se describen en este capítulo se basan en la propiedad de secuencialidad. Es decir, todos los esquemas que se presentan aseguran que las planificaciones son secuenciables. En el Capítulo 25 se describen esquemas de control de concurrencia que admiten planificaciones no secuenciables. En este capítulo se trata la gestión de la ejecución concurrente de transacciones y se ignoran los fallos. En el Capítulo 17 se verá la manera en que el sistema se puede recuperar de los fallos. 16.1 Protocolos basados en el bloqueo

Una forma de asegurar la secuencialidad es exigir que el acceso a los elementos de datos se haga en exclusión mutua; es decir, mientras una transacción accede a un elemento de datos, ninguna otra transacción puede modificar dicho elemento. El método más habitual que se usa para implementar este requisito es permitir que una transacción acceda a un elemento de datos sólo si posee actualmente un bloqueo sobre dicho elemento. 16.1.1 Bloqueos

Existen muchos modos mediante los cuales se puede bloquear un elemento de datos. En este apartado se centra la atención en dos de dichos modos: 1. Compartido. Si una transacción Ti obtiene un bloqueo en modo compartido (denotado por C) sobre el elemento Q, entonces Ti puede leer Q pero no lo puede escribir. 2. Exclusivo. Si una transacción Ti obtiene un bloqueo en modo exclusivo (denotado por X) sobre el elemento Q, entonces Ti puede tanto leer como escribir Q. Es necesario que toda transacción solicite un bloqueo del modo apropiado sobre el elemento de datos Q dependiendo de los tipos de operaciones que se vayan a realizar sobre Q. La petición se hace al gestor de control de concurrencia. La transacción puede realizar la operación sólo después de que el gestor de control de concurrencia conceda el bloqueo a la transacción. Dado un conjunto de modos de bloqueo, se puede definir sobre ellos una función de compatibilidad como se explica a continuación. Se usarán A y B para representar dos modos de bloqueo arbitrarios. Supóngase que la transacción Ti solicita un bloqueo en modo A sobre el elemento Q bajo el que la 529

www.detodoprogramacion.com


530

Capítulo 16

Control de concurrencia

C X Figura 16.1

C cierto falso

X falso falso

Matriz de compatibilidad de bloqueos comp.

transacción Tj (Ti 6= Tj ) posee actualmente un bloqueo de modo B. Si a la transacción Ti se le puede conceder un bloqueo sobre Q a pesar de la presencia del bloqueo de modo B, entonces se dice que el modo A es compatible con el modo B. Tal función se puede representar convenientemente en forma de matriz. La relación de compatibilidad entre los dos modos de bloqueo que se usan en este apartado se presenta en la matriz comp de la Figura 16.1. Un elemento comp(A, B) de la matriz tiene el valor cierto si y sólo si el modo A es compatible con el modo B. Obsérvese que el modo compartido es compatible consigo mismo, pero no con el modo exclusivo. En todo momento se pueden tener varios bloqueos en modo compartido (por varias transacciones) sobre un elemento de datos en concreto. Una petición posterior de bloqueo en modo exclusivo debe esperar hasta que se liberen los bloqueos en modo compartido que se poseen actualmente. Una transacción solicita un bloqueo compartido sobre el elemento de datos Q a través de la instrucción bloquear-C(Q). De forma similar se solicita un bloqueo exclusivo a través de la instrucción bloquearX(Q). Se puede desbloquear un elemento de datos Q por medio de la instrucción desbloquear(Q). Para acceder a un elemento de datos, una transacción Ti debe en primer lugar bloquear dicho elemento. Si éste ya se encuentra bloqueado por otra transacción en un modo incompatible, el gestor de control de concurrencia no concederá el bloqueo hasta que todos los bloqueos incompatibles que posean otras transacciones hayan sido liberados. De este modo Ti debe esperar hasta que se liberen todos los bloqueos incompatibles que posean otras transacciones. La transacción Ti puede desbloquear un elemento de datos que haya bloqueado en algún momento anterior. Obsérvese que la transacción debe mantener un bloqueo sobre un elemento de datos mientras acceda a dicho elemento. Además, no siempre es aconsejable que una transacción desbloquee un elemento de datos inmediatamente después de finalizar su acceso sobre él, ya que puede dejar de asegurarse la secuencialidad. Como ejemplo, considérese de nuevo el sistema bancario simplificado que se presentó en el Capítulo 15. Sean A y B dos cuentas a las que acceden las transacciones T1 y T2 . La transacción T1 transfiere 50 e desde la cuenta B a la A (Figura 16.2). La transacción T2 visualiza la cantidad total de dinero de las cuentas A y B— es decir, la suma A + B (Figura 16.3). Supóngase que los valores de las cuentas A y B son 100 e y 200 e respectivamente. Si estas dos transacciones se ejecutan secuencialmente, tanto en el orden T1 , T2 como en el orden T2 , T1 , entonces la transacción T2 visualizará el valor 300 e. Si por el contrario estas transacciones se ejecutan concurrentemente, entonces puede darse la planificación 1, que se muestra en la Figura 16.4. En ese caso la transacción T2 visualiza 250 e, lo cual es incorrecto. El motivo por el que se produce esta incorrección es que la transacción T1 desbloquea el elemento B demasiado pronto, lo cual provoca que T2 perciba un estado inconsistente. T1 : bloquear-X(B); leer(B); B := B − 50; escribir(B); desbloquear(B); bloquear-X(A); leer(A); A := A + 50; escribir(A); desbloquear(A). Figura 16.2

Transacción T1 .

www.detodoprogramacion.com


16.1

Protocolos basados en el bloqueo

531

T2 : bloquear-C(A); leer(A); desbloquear(A); bloquear-C(B); leer(B); desbloquear(B); visualizar(A + B). Figura 16.3

Transacción T2 .

La planificación muestra las acciones que ejecuta cada transacción, así como los puntos en los que el gestor de control de concurrencia concede los bloqueos. La transacción que realiza una petición de bloqueo no puede ejecutar su siguiente acción hasta que el gestor de control de concurrencia conceda dicho bloqueo. Por tanto, el bloqueo debe concederse en el intervalo de tiempo entre la operación de petición del bloqueo y la siguiente acción de la transacción. No es importante el momento exacto del intervalo en el cual se produce la concesión del bloqueo; se puede asumir sin problemas que la concesión del bloqueo se produce justo antes de la siguiente acción de la transacción. Por tanto se va a obviar la columna que describe las acciones del gestor de control de concurrencia en todas las planificaciones que aparezcan en el resto del capítulo. Se deja al lector como ejercicio la deducción del momento en que se conceden los bloqueos. Supóngase ahora que el desbloqueo se retrasa hasta el final de la transacción. La transacción T3 corresponde a T1 con el desbloqueo retrasado (Figura 16.5). La transacción T4 corresponde a T2 con el desbloqueo retrasado (Figura 16.6). Se puede verificar que la secuencia de lecturas y escrituras de la planificación 1, que provoca que se visualice un total incorrecto de 250 e, ya no es posible con T3 y T4 . Son posibles otras planificaciones. T4 no visualiza un resultado inconsistente en ninguna de ellas; más adelante se verá por qué. Desafortunadamente, el uso de bloqueos puede conducir a una situación no deseada. Considérese la planificación parcial de la Figura 16.7 para T3 y T4 . Puesto que T3 posee en bloqueo sobre B en modo

T1 bloquear-X(B)

gestor de control de concurrencia

T2

conceder-X(B, T1 ) leer(B) B:= B - 50 escribir(B) desbloquear(B) bloquear-C(A) conceder-C(A, T2 ) leer(A) desbloquear(A) bloquear-C(B) conceder-C(B, T2 ) leer(B) desbloquear(B) visualizar(A + B) bloquear-X(A) conceder-X(A, T1 ) leer(A) A:= A + 50 escribir(A) desbloquear(A) Figura 16.4

Planificación 1.

www.detodoprogramacion.com


532

Capítulo 16

Control de concurrencia

T3 : bloquear-X(B); leer(B); B := B − 50; escribir(B); bloquear-X(A); leer(A); A := A + 50; escribir(A); desbloquear(B); desbloquear(A). Figura 16.5

Transacción T3 .

exclusivo y T4 solicita un bloqueo sobre B en modo compartido, T4 espera a que T3 desbloquee B. De forma similar, puesto que T4 posee un bloqueo sobre A en modo compartido y T3 solicita un bloqueo sobre A en modo exclusivo, T3 espera a que T4 desbloquee A. Así se llega a un estado en el cual ninguna de las transacciones puede continuar su ejecución normal. Esta situación se denomina interbloqueo. Cuando aparece un interbloqueo, el sistema debe retroceder una de las dos transacciones. Una vez que se ha provocado el retroceso de una de ellas, se desbloquean los elementos de datos que estuvieran bloqueados por la transacción. Estos elementos de datos están disponibles entonces para otra transacción, la cual puede continuar su ejecución. Se volverá al tratamiento de interbloqueos en el Apartado 16.6. Si no se usan bloqueos, o se desbloquean los elementos de datos tan pronto como sea posible después de leerlos o escribirlos, se pueden obtener estados inconsistentes. Por otro lado, si no se desbloquea un elemento de datos antes de solicitar un bloqueo sobre otro, pueden producirse interbloqueos. Existen formas de evitar los interbloqueos en algunas situaciones, como se verá en el Apartado 16.1.5. Sin embargo, en general, los interbloqueos son un mal necesario asociado a los bloqueos si se quieren evitar los estados inconsistentes. Los interbloqueos son absolutamente preferibles a los estados inconsistentes, ya que se pueden tratar haciendo retroceder las transacciones, mientras que los estados inconsistentes producen problemas en el mundo real que el sistema de base de datos no puede manejar. Se exige que toda transacción del sistema siga un conjunto de reglas llamado protocolo de bloqueo, que indica el momento en que una transacción puede bloquear y desbloquear cada uno de los elementos de datos. Los protocolos de bloqueo restringen el número de planificaciones posibles. El conjunto de T4 : bloquear-C(A); leer(A); bloquear-C(B); leer(B); visualizar(A + B); desbloquear(A); desbloquear(B). Figura 16.6

Transacción T4 .

T3 bloquear-X(B) leer(B) B:= B - 50 escribir(B)

T4

bloquear-C(A) leer(A) bloquear-C(B) bloquear-X(A) Figura 16.7

Planificación 2.

www.detodoprogramacion.com


16.1

Protocolos basados en el bloqueo

533

tales planificaciones es un subconjunto propio de todas las planificaciones secuenciables posibles. Se van a mostrar varios protocolos de bloqueo que sólo permiten planificaciones secuenciables en cuanto a conflictos. Antes de hacer esto se necesitan algunas definiciones. Sean {T0 , T1 , . . ., Tn } un conjunto de transacciones que participan en la planificación S. Se dice que Ti precede a Tj en S, denotado por Ti → Tj , si existe un elemento de datos Q tal que Ti ha obtenido un bloqueo en modo A sobre Q, y Tj ha obtenido un bloqueo en modo B sobre Q más tarde y comp(A, B) = falso. Si Ti → Tj entonces esta precedencia implica que en cualquier planificación secuencial equivalente, Ti debe aparecer antes que Tj . Obsérvese que este grafo es similar al grafo de precedencia que se usaba en el Apartado 15.8 para comprobar la secuencialidad en cuanto a conflictos. Los conflictos entre instrucciones corresponden a modos de bloqueo no compatibles. Se dice que una planificación S es legal bajo un protocolo de bloqueo dado si S es una planificación posible para un conjunto de transacciones que sigan las reglas del protocolo de bloqueo. Se dice que un protocolo asegura la secuencialidad en cuanto a conflictos si y sólo si todas las planificaciones legales son secuenciables en cuanto a conflictos; en otras palabras, para todas las planificaciones legales la relación → asociada es acíclica. 16.1.2 Concesión de bloqueos

Cuando una transacción solicita un bloqueo de un modo particular sobre un elemento de datos y ninguna otra transacción posee un bloqueo sobre el mismo elemento de datos en un modo conflictivo, se puede conceder el bloqueo. Sin embargo, hay que tener cuidado para evitar la siguiente situación. Supóngase que la transacción T2 posee un bloqueo en modo compartido sobre un elemento de datos y que la transacción T1 solicita un bloqueo en modo exclusivo sobre dicho elemento de datos. Obviamente T1 debe esperar a que T2 libere el bloqueo en modo compartido. Mientras tanto, la transacción T3 puede solicitar un bloqueo en modo compartido sobre el mismo elemento de datos. La petición de bloqueo es compatible con el bloqueo que se ha concedido a T2 , por tanto se puede conceder a T3 el bloqueo en modo compartido. En este punto T2 puede liberar el bloqueo, pero T1 debe seguir esperando hasta que T3 termine. Pero de nuevo puede haber una nueva transacción T4 que solicite un bloqueo en modo compartido sobre el mismo elemento de datos y a la cual se conceda el bloqueo antes de que T3 lo libere. De hecho, es posible que haya una secuencia de transacciones que soliciten un bloqueo en modo compartido sobre el elemento de datos, y que cada una de ellas libere el bloqueo un poco después de que sea concedido, de forma que T1 nunca obtenga el bloqueo en modo exclusivo sobre el elemento de datos. La transacción T1 nunca progresa y se dice que tiene inanición. Se puede evitar la inanición de las transacciones al conceder los bloqueos de la siguiente manera: cuando una transacción Ti solicita un bloqueo sobre un elemento de datos Q en un modo particular M , el gestor de control de concurrencia concede el bloqueo siempre que 1. No exista otra transacción que posea un bloqueo sobre Q en un modo que esté en conflicto con M. 2. No exista otra transacción que esté esperando un bloqueo sobre Q y que lo haya solicitado antes que Ti . De este modo, una petición de bloqueo nunca se quedará bloqueada por otra petición de bloqueo solicitada más tarde. 16.1.3 Protocolo de bloqueo de dos fases

Un protocolo que asegura la secuencialidad es el protocolo de bloqueo de dos fases. Este protocolo exige que cada transacción realice las peticiones de bloqueo y desbloqueo de dos fases: 1. Fase de crecimiento. Una transacción puede obtener bloqueos pero no puede liberarlos. 2. Fase de decrecimiento. Una transacción puede liberar bloqueos pero no puede obtener ninguno nuevo.

www.detodoprogramacion.com


534

Capítulo 16

Control de concurrencia

Inicialmente una transacción está en la fase de crecimiento. La transacción adquiere los bloqueos que necesite. Una vez que la transacción libera un bloqueo, entra en la fase de decrecimiento y no puede realizar más peticiones de bloqueo. Por ejemplo, las transacciones T3 y T4 son de dos fases. Por otro lado, las transacciones T1 y T2 no son de dos fases. Obsérvese que no es necesario que las instrucciones de desbloqueo aparezcan al final de la transacción. Por ejemplo, en el caso de la transacción T3 se puede trasladar la instrucción desbloquear(B) hasta justo antes de la instrucción bloquear-X(A) y se sigue cumpliendo la propiedad del bloqueo de dos fases. Se puede mostrar que el protocolo de bloqueo de dos fases asegura la secuencialidad en cuanto a conflictos. Considérese cualquier transacción. El punto de la planificación en el cual la transacción obtiene su bloqueo final (el final de la fase de crecimiento) se denomina punto de bloqueo de la transacción. Ahora se pueden ordenar las transacciones según sus puntos de bloqueo—de hecho, esta ordenación es un orden de secuencialidad para las transacciones. La demostración se deja como ejercicio para el lector (véase el Ejercicio práctico 16.1). El protocolo de bloqueo de dos fases no asegura la ausencia de interbloqueos. Obsérvese que las transacciones T3 y T4 son de dos fases pero en la planificación 2 (Figura 16.7) llegan a un interbloqueo. Recuérdese del Apartado 15.6.2 que las planificaciones, además de ser secuenciables, es aconsejable que sean sin cascada. El retroceso en cascada puede ocurrir en el bloqueo de dos fases. Como ejemplo considérese la planificación parcial de la Figura 16.8. Cada transacción sigue el protocolo de bloqueo de dos fases pero un fallo de T5 después del paso leer(A) de T7 lleva a un retroceso en cascada de T6 y T7 . Los retrocesos en cascada se pueden evitar por medio de una modificación del protocolo de bloqueo de dos fases que se denomina protocolo de bloqueo estricto de dos fases. Este protocolo exige que, además de que el bloqueo sea de dos fases, una transacción deba poseer todos los bloqueos en modo exclusivo que tome hasta que dicha transacción se complete. Este requisito asegura que todo dato que escribe una transacción no comprometida está bloqueado en modo exclusivo hasta que la transacción se completa, evitando que ninguna otra transacción lea el dato. Otra variante del bloqueo de dos fases es el protocolo de bloqueo riguroso de dos fases, el cual exige que se posean todos los bloqueos hasta que se comprometa la transacción. Se puede comprobar fácilmente que con el bloqueo riguroso de dos fases se pueden secuenciar las transacciones en el orden en que se comprometen. Muchos sistemas de bases de datos implementan tanto el bloqueo estricto como el bloqueo estricto de dos fases. Considérense las dos transacciones siguientes de las que sólo se muestran algunas de las operaciones leer y escribir significativas:

T5 bloquear-X(A) leer(A) bloquear-C(B) leer(B) escribir(A) desbloquear(A)

T6

T7

bloquear-X(A) leer(A) escribir(A) desbloquear(A) bloquear-C(A) leer(A) Figura 16.8

Planificación parcial con bloqueo de dos fases.

www.detodoprogramacion.com


16.1

Protocolos basados en el bloqueo

535

T8 : leer(a1 ); leer(a2 ); ... leer(an ); escribir(a1 ). T9 : leer(a1 ); leer(a2 ); visualizar(a1 + a2 ). Si se emplea el protocolo de bloqueo de dos fases entonces T8 debe bloquear a1 en modo exclusivo. Por tanto, toda ejecución concurrente de ambas transacciones conduce a una ejecución secuencial. Obsérvese sin embargo que T8 sólo necesita el bloqueo en modo exclusivo sobre a1 al final de su ejecución, cuando escribe a1 . Así, si T8 pudiera bloquear inicialmente a1 en modo compartido y después pudiera cambiar el bloqueo a modo exclusivo, se obtendría una mayor concurrencia, ya que T8 y T9 podrían acceder a a1 y a2 simultáneamente. Esta observación lleva a un refinamiento del protocolo de bloqueo de dos fases básico en el cual se permiten conversiones de bloqueo. Se va a proporcionar un mecanismo para cambiar un bloqueo compartido por un bloqueo exclusivo y un bloqueo exclusivo por uno compartido. Se denota la conversión del modo compartido al modo exclusivo como subir, y la conversión del modo exclusivo al modo compartido como bajar. No se puede permitir la conversión de modos arbitrariamente. Por el contrario, la subida puede tener lugar sólo en la fase de crecimiento, mientras que la bajada puede tener lugar sólo en la fase de decrecimiento. Volviendo al ejemplo, las transacciones T8 y T9 se pueden ejecutar concurrentemente bajo el protocolo de bloqueo de dos fases refinado, como muestra la planificación incompleta de la Figura 16.9, en la cual sólo se muestran algunas de las operaciones de bloqueo. Obsérvese que se puede forzar a esperar a una transacción que intente subir un bloqueo sobre un elemento Q. Esta espera forzada tiene lugar si Q está bloqueado actualmente por otra transacción en modo compartido. Del mismo modo que el protocolo de bloqueo de dos fases básico, el bloqueo de dos fases con conversión de bloqueos genera sólo planificaciones secuenciables en cuanto a conflictos y se pueden secuenciar las transacciones según sus puntos de bloqueo. Además, si se poseen los bloqueos hasta el final de la transacción, las planificaciones son sin cascada. Para un conjunto de transacciones puede haber planificaciones secuenciables en cuanto a conflictos que no se puedan obtener por medio del protocolo de bloqueo de dos fases. Sin embargo, para obtener planificaciones secuenciables en cuanto a conflictos por medio de protocolos de bloqueo que no sean de dos fases, es necesario o bien tener información adicional de las transacciones o bien imponer alguna estructura u orden en el conjunto de elementos de datos de la base de datos. A falta de esta información es necesario el bloqueo de dos fases para la secuencialidad en cuanto a conflictos—si Ti no es una

T8 bloquear-C(a1 )

T9 bloquear-C(a1 )

bloquear-C(a2 ) bloquear-C(a2 ) bloquear-C(a3 ) bloquear-C(a4 ) desbloquear(a1 ) desbloquear(a2 ) bloquear-C(an ) subir(a1 ) Figura 16.9

Planificación incompleta con conversión de bloqueos.

www.detodoprogramacion.com


536

Capítulo 16

Control de concurrencia

transacción de dos fases, siempre es posible encontrar otra transacción Tj que sea de dos fases tal que existe una planificación posible para Ti y Tj que no sea secuenciable en cuanto a conflictos. Los bloqueos estricto de dos fases y riguroso de dos fases (con conversión de bloqueos) se usan ampliamente en sistemas de bases de datos comerciales. Un esquema simple pero de uso extendido genera automáticamente las instrucciones apropiadas de bloqueo y desbloqueo para una transacción, basándose en peticiones de lectura y escritura desde la transacción: • Cuando una transacción Ti realiza una operación leer(Q), el sistema genera una instrucción bloquear-C(Q) seguida de una instrucción leer(Q). • Cuando Ti realiza una operación escribir(Q), el sistema comprueba si Ti posee ya un bloqueo en modo compartido sobre Q. Si es así, entonces el sistema genera una instrucción subir(Q) seguida de la instrucción escribir(Q). En otro caso el sistema genera una instrucción bloquear-X(Q) seguida de la instrucción escribir(Q). • Todos los bloqueos que obtenga una transacción no se desbloquean hasta que dicha transacción se comprometa o aborte.

∗∗

16.1.4 Implementación de los bloqueos

Un gestor de bloqueos se puede implementar como un proceso que recibe mensajes de transacciones y envía mensajes como respuesta. El proceso gestor de bloqueos responde a los mensajes de solicitud de bloqueo con mensajes de concesión de bloqueo, o con mensajes que solicitan un retroceso de la transacción (en caso de interbloqueos). Los mensajes de desbloqueo tan sólo requieren un reconocimiento como respuesta, pero pueden dar lugar a un mensaje de concesión para otra transacción que esté esperando. El gestor de bloqueos utiliza la siguiente estructura de datos: para cada elemento de datos que está actualmente bloqueado, mantiene una lista enlazada de registros, uno para cada solicitud, en el orden en el que llegaron las solicitudes. Utiliza una tabla de asociación, indexada por el nombre del elemento de datos, para encontrar la lista enlazada (si la hay) para cada elemento de datos; esta tabla se denomina tabla de bloqueos. Cada registro de la lista enlazada de cada elemento de datos anota qué transacción hizo la solicitud, y qué modo de bloqueo se solicitó. El registro también anota si la solicitud ya se ha concedido. La Figura 16.10 muestra un ejemplo de una tabla de bloqueos. La tabla contiene bloqueos para cinco elementos de datos distintos: E4, E7, E23, E44 y E912. La tabla de bloqueos utiliza cadenas de desbordamiento, de forma que hay una lista enlazada de elementos de datos por cada entrada de la tabla de bloqueos. También hay una lista de transacciones a las que se les han concedido bloqueos, o que están esperando para bloquear, para cada uno de los elementos de datos. Los bloqueos concedidos se han representado como rectángulos rellenos (negros), mientras que las solicitudes en espera son los rectángulos vacíos. Se ha omitido el modo de bloqueo para que la figura sea más sencilla. Por ejemplo, se puede observar que a T23 se le han concedido bloqueos sobre E912 y E7, y está esperando para bloquear E4. Aunque la figura no lo muestre, la tabla de bloqueos debería mantener también un índice de identificadores de transacciones, de forma que fuese posible determinar de manera eficiente el conjunto de bloqueos que mantiene una transacción dada. El gestor de bloqueos procesa las solicitudes de la siguiente forma: • Cuando llega un mensaje de solicitud, añade un registro al final de la lista enlazada del elemento de datos, si la lista enlazada existe. En otro caso crea una nueva lista enlazada que tan sólo contiene el registro correspondiente a la solicitud. Siempre concede la primera solicitud de bloqueo sobre el elemento de datos. Pero si la transacción solicita un bloqueo sobre un elemento sobre el cual ya se ha concedido un bloqueo, el gestor de bloqueos sólo concede la solicitud si es compatible con las solicitudes anteriores, y todas éstas ya se han concedido. En otro caso, la solicitud tiene que esperar.

www.detodoprogramacion.com


16.1

Protocolos basados en el bloqueo

537

I23

I7

T1

T23

T8

T2

I912

T23

I4

T1

T23

I44

T8 Figura 16.10

Tabla de bloqueos.

• Cuando el gestor de bloqueos recibe un mensaje de desbloqueo de una transacción, borra el registro para ese elemento de datos de la lista enlazada correspondiente a dicha transacción. Prueba el siguiente registro, si lo hay, como se describe en el párrafo anterior, para determinar si ahora se puede conceder dicha solicitud. Si se puede, el gestor de bloqueos concede la solicitud y procesa el siguiente registro, si lo hay, de forma similar, y así sucesivamente. • Si una transacción se interrumpe, el gestor de bloqueos borra cualquier solicitud en espera realizada por la transacción. Una vez que el sistema de base de datos ha realizado las acciones apropiadas para deshacer la transacción (véase el Apartado 17.3), libera todos los bloqueos que mantenía la transacción abortada. Este algoritmo garantiza que las solicitudes de bloqueo están libres de inanición, dado que una solicitud nunca se puede conceder mientras no se hayan concedido las solicitudes recibidas anteriormente. Más adelante, en el Apartado 16.6.3, se estudiará cómo detectar y manejar interbloqueos. El Apartado 20.2.1 describe una implementación alternativa—una que utiliza memoria compartida en vez de paso de mensajes para la solicitud y concesión de bloqueos. 16.1.5 Protocolos basados en grafos

Como se ha visto en el Apartado 16.1.3, a falta de información acerca de la forma en que se accede a los elementos de datos, el protocolo de bloqueo de dos fases es necesario y suficiente para asegurar la secuencialidad. Pero, si se desean desarrollar protocolos que no sean de dos fases, es necesario tener información adicional acerca de la forma en que cada transacción accede a la base de datos. Existen varios modelos que pueden ofrecer la información adicional, que difieren en la cantidad de información que proporcionan. El modelo más simple exige que se tenga un conocimiento previo acerca del orden en el cual se accede a los elementos de la base de datos. Dada esta información es posible construir protocolos de bloqueo que no sean de dos fases pero que no obstante aseguren la secuencialidad. Para adquirir tal conocimiento previo, se impone un orden parcial → sobre el conjunto D = {d1 , d2 , . . ., dh } de todos los elementos de datos. Si di → dj entonces toda transacción que acceda tanto a di como a dj debe acceder a di antes de acceder a dj . Este orden parcial puede ser el resultado de la organización tanto lógica como física de los datos, o se puede imponer únicamente con motivo del control de concurrencia.

www.detodoprogramacion.com


538

Capítulo 16

Control de concurrencia

A B

C F

E

D G

H

I

J Figura 16.11

Grafo de la base de datos con estructura de árbol.

El orden parcial implica que el conjunto D se pueda ver como un grafo dirigido acíclico denominado grafo de la base de datos. Para simplificar, este apartado centra su atención sólo en aquellos grafos que son árboles con raíz. Se va a mostrar un protocolo simple llamado protocolo de árbol, el cual está restringido a utilizar sólo bloqueos exclusivos. En las notas bibliográficas se proporcionan referencias a otros protocolos basados en grafos más complejos. En el protocolo de bloqueo de árbol sólo se permite la instrucción de bloqueo bloquear-C. Cada transacción Ti puede bloquear un elemento de datos al menos una vez y debe seguir las siguientes reglas: 1. El primer bloqueo de Ti puede ser sobre cualquier elemento de datos. 2. Posteriormente, Ti puede bloquear un elemento de datos Q sólo si Ti está bloqueando actualmente al padre de Q. 3. Los elementos de datos bloqueados se pueden desbloquear en cualquier momento. 4. Ti no puede bloquear de nuevo un elemento de datos que ya haya bloqueado y desbloqueado anteriormente. Todas las planificaciones que sean legales bajo el protocolo de árbol son secuenciables en cuanto a conflictos. Para ilustrar este protocolo considérese el grafo de la base de datos de la Figura 16.11. Las cuatro transacciones siguientes siguen el protocolo de árbol sobre dicho grafo. Sólo se muestran las instrucciones de bloqueo y desbloqueo: T10 : bloquear-X(B); bloquear-X(E); bloquear-X(D); desbloquear(B); desbloquear(E); bloquear-X(G); desbloquear(D); desbloquear(G). T11 : bloquear-X(D); bloquear-X(H); desbloquear(D); desbloquear(H). T12 : bloquear-X(B); bloquear-X(E); desbloquear(E); desbloquear(B). T13 : bloquear-X(D); bloquear-X(H); desbloquear(D); desbloquear(H). En la Figura 16.12 se describe una planificación posible en la que participan estas cuatro transacciones. Obsérvese que durante su ejecución, la transacción T10 realiza bloqueos sobre dos subárboles disjuntos. Obsérvese que la planificación de la Figura 16.12 es secuenciable en cuanto a conflictos. Se puede demostrar que el protocolo de árbol no sólo asegura la secuencialidad en cuanto a conflictos, sino que también asegura la ausencia de interbloqueos. El protocolo de árbol de la Figura 16.12 no asegura la recuperabilidad y la ausencia de cascadas. Para asegurar la recuperabilidad y la ausencia de cascadas, el protocolo se puede modificar para que no permita liberar bloqueos exclusivos hasta el final de la transacción. Mantener los bloqueos exclusivos hasta el final de la transacción reduce la concurrencia. Existe una alternativa que mejora la concurrencia, pe-

www.detodoprogramacion.com


16.2

T10 bloquear-X(B)

T11

Protocolos basados en marcas temporales

T12

539

T13

bloquear-X(D) bloquear-X(H) desbloquear(D) bloquear-X(E) bloquear-X(D) desbloquear(B) desbloquear(E) bloquear-X(B) bloquear-X(E) desbloquear(H) bloquear-X(G) desbloquear(D) bloquear-X(D) bloquear-X(H) desbloquear(D) desbloquear(H) desbloquear(E) desbloquear(B) desbloquear(G) Figura 16.12

Planificación secuenciable bajo el protocolo de árbol.

ro sólo asegura la recuperabilidad: para cada elemento de datos con una escritura no comprometida se registra qué transacción realizó la última escritura sobre el elemento de datos. Cada vez que una transacción Ti realiza una lectura de un elemento de datos no comprometido, se registra una dependencia de compromiso de Ti en la transacción que realizó la última escritura sobre el elemento de datos. Entonces, no se permite que la transacción Ti se comprometa hasta que todas las transacciones sobre las que tiene una dependencia de compromiso se comprometan. Si alguna de estas transacciones se interrumpe, también hay que interrumpir Ti . El protocolo de bloqueo de árbol tiene la ventaja sobre el protocolo de bloqueo de dos fases en que, a diferencia del bloqueo de dos fases, está libre de interbloqueos, así que no se necesitan retrocesos. El protocolo de bloqueo de árbol tiene otra ventaja sobre el protocolo de bloqueo de dos fases en que los desbloqueos se pueden producir antes. El hecho de desbloquear antes puede llevar a unos tiempos de espera menores y a un aumento de la concurrencia. Sin embargo, el protocolo tiene el inconveniente de que, en algunos casos, una transacción puede que tenga que bloquear elementos de datos a los que no accede. Por ejemplo, una transacción que tenga que acceder a los elementos de datos A y J en el grafo de la base de datos de la Figura 16.11, debe bloquear no sólo A y J sino también los elementos de datos B, D y H. Estos bloqueos adicionales producen un aumento del coste de los bloqueos, la posibilidad de tiempos de espera adicionales y un descenso potencial de la concurrencia. Además, sin un conocimiento previo de los elementos de datos que es necesario bloquear, las transacciones tienen que bloquear la raíz del árbol y esto puede reducir considerablemente la concurrencia. Para un conjunto de transacciones pueden existir planificaciones secuenciables en cuanto a conflictos que no se pueden obtener por medio del protocolo de árbol. De hecho, hay planificaciones que son posibles por medio del protocolo de bloqueo de dos fases que no son posibles por medio del protocolo de árbol, y viceversa. En los ejercicios se exponen ejemplos de tales planificaciones. 16.2 Protocolos basados en marcas temporales

En los protocolos de bloqueo que se han descrito antes se determina el orden entre dos transacciones conflictivas en tiempo de ejecución a través del primer bloqueo que soliciten ambas que traiga consigo modos incompatibles. Otro método para determinar el orden de secuencialidad es seleccionar previa-

www.detodoprogramacion.com


540

Capítulo 16

Control de concurrencia

mente un orden entre las transacciones. El método más común para hacer esto es utilizar un esquema de ordenación por marcas temporales. 16.2.1 Marcas temporales

A toda transacción Ti del sistema se le asocia una única marca temporal fijada, denotada por MT(Ti ). El sistema de base de datos asigna esta marca temporal antes de que comience la ejecución de Ti . Si a la transacción Ti se le ha asignado la marca temporal MT(Ti ) y una nueva transacción Tj entra en el sistema, entonces MT(Ti ) < MT(Tj ). Existen dos métodos simples para implementar este esquema: 1. Usar el valor del reloj del sistema como marca temporal; es decir, la marca temporal de una transacción es igual al valor del reloj en el momento en el que la transacción entra en el sistema. 2. Usar un contador lógico que se incrementa cada vez que se asigna una nueva marca temporal; es decir, la marca temporal de una transacción es igual al valor del contador en el momento en el cual la transacción entra en el sistema. Las marcas temporales de las transacciones determinan el orden de secuencia. De este modo, si MT(Ti ) < MT(Tj ) entonces el sistema debe asegurar que toda planificación que produzca sea equivalente a una planificación secuencial en la cual la transacción Ti aparezca antes que la transacción Tj . Para implementar este esquema se asocia a cada elemento de datos Q dos valores de marca temporal: • marca-temporal-E(Q) denota la mayor marca temporal de todas las transacciones que ejecutan con éxito escribir(Q). • marca-temporal-L(Q) denota la mayor marca temporal de todas las transacciones que ejecutan con éxito leer(Q). Estas marcas temporales se actualizan cada vez que se ejecuta una nueva operación leer(Q) o escribir(Q). 16.2.2 Protocolo de ordenación por marcas temporales

El protocolo de ordenación por marcas temporales asegura que todas las operaciones leer y escribir conflictivas se ejecutan en el orden de las marcas temporales. Este protocolo opera como sigue: 1. Supóngase que la transacción Ti ejecuta leer(Q). a. Si MT(Ti ) <marca-temporal-E(Q) entonces Ti necesita leer un valor de Q que ya se ha sobrescrito. Por tanto se rechaza la operación leer y Ti retrocede. b. Si MT(Ti ) ≥ marca-temporal-E(Q) entonces se ejecuta la operación leer y marca-temporalL(Q) se asigna al máximo de marca-temporal-L(Q) y de MT(Ti ). 2. Supóngase que la transacción Ti ejecuta escribir(Q). a. Si MT(Ti ) < marca-temporal-L(Q) entonces el valor de Q que produce Ti se necesita previamente y el sistema asume que dicho valor no se puede producir nunca. Por tanto, se rechaza la operación escribir y Ti retrocede. b. Si MT(Ti ) < marca-temporal-E(Q) entonces Ti está intentando escribir un valor de Q obsoleto. Por tanto, se rechaza la operación escribir y Ti retrocede. c. En otro caso se ejecuta la operación escribir y MT(Ti ) se asigna a marca-temporal-E(Q). A una transacción Ti que el esquema de control de concurrencia haya retrocedido como resultado de la ejecución de una operación leer o escribir se le asigna una nueva marca temporal y se inicia de nuevo. Para ilustrar este protocolo considérense las transacciones T14 y T15 . La transacción T14 visualiza el contenido de las cuentas A y B: T14 : leer(B); leer(A); visualizar(A + B).

www.detodoprogramacion.com


16.2

T14 leer(B)

Protocolos basados en marcas temporales

541

T15 leer(B) B:= B - 50 escribir(B)

leer(A) leer(A) visualizar(A + B) A:= A + 50 escribir(A) visualizar(A + B) Figura 16.13

Planificación 3.

La transacción T15 transfiere 50 e de la cuenta B a la A y muestra después el contenido de ambas: T15 : leer(B); B := B − 50; escribir(B); leer(A); A := A + 50; escribir(A); visualizar(A + B). En las planificaciones actuales con el protocolo de marcas temporales se asume que a una transacción se le asigna una marca temporal inmediatamente antes de su primera instrucción. Así en la planificación 3 de la Figura 16.13, MT(T14 ) < MT(T15 ) y la planificación con el protocolo de marcas temporales es posible. Obsérvese que la ejecución anterior puede obtenerse también con el protocolo de bloqueo de dos fases. Sin embargo, existen planificaciones que son posibles con el protocolo de bloqueo de dos fases que no lo son con el protocolo de marcas temporales y viceversa (véase el Ejercicio 16.25). El protocolo de ordenación por marcas temporales asegura la secuencialidad en cuanto a conflictos. Esta afirmación se deduce del hecho de que las operaciones conflictivas se procesan durante la ordenación de las marcas temporales. El protocolo asegura la ausencia de interbloqueos, ya que ninguna transacción tiene que esperar. Sin embargo, existe una posibilidad de inanición de las transacciones largas si una secuencia de transacciones cortas conflictivas provoca reinicios repetidos de la transacción larga. Si se descubre que una transacción se está reiniciando de forma repetida, es necesario bloquear las transacciones conflictivas de forma temporal para permitir que la transacción termine. El protocolo puede generar planificaciones no recuperables. Sin embargo, se puede extender para producir planificaciones recuperables de una de las siguientes formas: • La recuperabilidad y la ausencia de cascadas se pueden asegurar realizando todas las escrituras juntas al final de la transacción. Las escrituras tienen que ser atómicas en el siguiente sentido: mientras que las escrituras están en progreso, no se permite que ninguna transacción acceda a ninguno de los elementos de datos que se han escrito. • La recuperabilidad y la ausencia de cascadas también se pueden garantizar utilizando una forma limitada de bloqueo, por medio de la cual las lecturas de los elementos no comprometidos se posponen hasta que la transacción haya actualizado el elemento comprometido (véase el Ejercicio 16.26). • La recuperabilidad sola se puede asegurar realizando un seguimiento de las escrituras no comprometidas y sólo permitiendo que una transacción Ti se comprometa después de que se comprometa cualquier transacción que escribió un valor que leyó Ti . Las dependencias de compromiso, esbozadas en el Apartado 16.1.5, se pueden utilizar para este propósito.

www.detodoprogramacion.com


542

Capítulo 16

Control de concurrencia

T16 leer(Q)

T17 escribir(Q)

escribir(Q) Figura 16.14

Planificación 4.

16.2.3 Regla de escritura de Thomas

Ahora se presenta una modificación del protocolo de ordenación por marcas temporales que permite una mayor concurrencia potencial que la que tiene el protocolo del Apartado 16.2.2. Considérese la planificación 4 de la Figura 16.14 y aplíquese el protocolo de ordenación por marcas temporales. Puesto que T16 comienza antes que T17 se asume que MT(T16 ) < MT(T17 ). La operación leer(Q) de T16 tiene éxito, así como la operación escribir(Q) de T17 . Cuando T16 intenta hacer su operación escribir(Q) se encuentra con que MT(T16 ) < marca-temporal-E(Q), ya que marca-temporal-E(Q) = MT(T17 ). De este modo se rechaza la operación escribir(Q) de T16 y se debe retroceder la transacción. A pesar de que el protocolo de ordenación por marcas temporales exige el retroceso de la transacción T16 , esto no es necesario. Como T17 ya ha escrito Q, el valor que intenta escribir T16 nunca se va leer. Toda transacción Ti con MT(Ti ) < MT(T17 ) que intente una operación leer(Q) retrocederá, ya que MT(Ti ) < marca-temporal-E(Q). Toda transacción Tj con MT(Tj ) >MT(T17 ) debe leer el valor de Q que ha escrito T17 en lugar del valor que ha escrito T16 . Esta observación lleva a la versión modificada del protocolo de ordenación por marcas temporales en el cual se pueden ignorar las operaciones escribir obsoletas bajo ciertas circunstancias. Las reglas del protocolo para las operaciones leer no sufren cambios. Sin embargo, las reglas del protocolo para las operaciones escribir son algo diferentes de las del protocolo de ordenación por marcas temporales del Apartado 16.2.2. La modificación al protocolo de ordenación por marcas temporales, denominada regla de escritura de Thomas, es la siguiente. Supóngase que la transacción Ti ejecuta escribir(Q). 1. Si MT(Ti ) < marca-temporal-L(Q) entonces el valor de Q que produce Ti se necesita previamente y el sistema asume que dicho valor no se puede producir nunca. Por tanto, se rechaza la operación escribir y Ti retrocede. 2. Si MT(Ti ) < marca-temporal-E(Q) entonces Ti está intentando escribir un valor de Q obsoleto. Por tanto se puede ignorar dicha operación escribir. 3. En otro caso se ejecuta la operación escribir y MT(Ti ) se asigna a marca-temporal-E(Q). La diferencia entre las reglas anteriores y las del Apartado 16.2.2 está en la segunda regla. El protocolo de ordenación por marcas temporales exige que Ti retroceda si ejecuta escribir(Q) y MT(Ti ) < marcatemporal-E(Q). Sin embargo, ahora se ignora la instrucción escribir obsoleta en aquellos casos en los que MT(Ti ) ≥ marca-temporal-L(Q). La regla de escritura de Thomas emplea la secuencialidad en cuanto a vistas borrando las operaciones escribir obsoletas de las transacciones que las ejecutan. Esta modificación de las transacciones hace posible generar planificaciones que no serían posibles con otros protocolos que se han presentado en este capítulo. Por ejemplo, la planificación 4 de la Figura 16.14 no es secuenciable en cuanto a conflictos y, por tanto, no es posible con el protocolo de bloqueo de dos fases, con el protocolo de árbol o con el protocolo de ordenación por marcas temporales. Con la regla de escritura de Thomas se ignoraría la operación escribir(Q) de T16 . El resultado es una planificación que es equivalente en cuanto a vistas a la planificación secuencial < T16 , T17 >. 16.3 Protocolos basados en validación

En aquellos casos en que la mayoría de las transacciones son de sólo lectura, la tasa de conflictos entre las transacciones puede ser baja. Así, muchas de esas transacciones, si se ejecutasen sin la supervisión de un esquema de control de concurrencia, llevarían no obstante al sistema a un estado consistente.

www.detodoprogramacion.com


16.3

Protocolos basados en validación

543

Un esquema de control de concurrencia impone una sobrecarga en la ejecución de código y un posible retardo en las transacciones. Sería aconsejable utilizar otro esquema alternativo que impusiera menos sobrecarga. La dificultad de reducir la sobrecarga está en que no se conocen de antemano las transacciones que estarán involucradas en un conflicto. Para obtener dicho conocimiento se necesita un esquema para supervisar el sistema. Se asume que cada transacción Ti se ejecuta en dos o tres fases diferentes durante su tiempo de vida dependiendo de si es una transacción de sólo lectura o una de actualización. Las fases son, en orden, 1. Fase de lectura. Durante esta fase tiene lugar la ejecución de la transacción Ti . Se leen los valores de varios elementos de datos y se almacenan en variables locales de Ti . Todas las operaciones escribir se realizan sobre las variables locales temporales sin actualizar la base de datos actual. 2. Fase de validación. La transacción Ti realiza una prueba de validación para determinar si puede copiar a la base de datos las variables locales temporales que tienen los resultados de las operaciones escribir sin causar una violación de la secuencialidad. 3. Fase de escritura. Si la transacción Ti tiene éxito en la validación (paso 2) entonces las actualizaciones reales se aplican a la base de datos. En otro caso, Ti retrocede. Cada transacción debe pasar por las tres fases y en el orden que se muestra. Sin embargo, se pueden entrelazar las tres fases de la ejecución concurrente de las transacciones. Para realizar la prueba de validación se necesita conocer el momento en que tienen lugar las distintas fases de las transacciones Ti . Se asociarán por tanto tres marcas temporales distintas a la transacción Ti : 1. Inicio(Ti ). Momento en el cual Ti comienza su ejecución. 2. Validación(Ti ). Momento en el cual Ti termina su fase de lectura y comienza su fase de validación. 3. Fin(Ti ). Momento en el cual Ti termina su fase de escritura. Se determina el orden de secuencialidad a través de la técnica de la ordenación por marcas temporales utilizando el valor de la marca temporal Validación(Ti ). De este modo, el valor MT(Ti ) = Validación(Ti ) y, si MT(Tj ) < MT(Tk ), entonces toda planificación que se produzca debe ser equivalente a una planificación secuencial en la cual la transacción Tj aparezca antes que la transacción Tk . La razón por la que se ha elegido Validación(Ti ) como marca temporal de la transacción Ti , en lugar de Inicio(Ti ), es porque resulta posible esperar un tiempo de respuesta más rápido dado que la tasa de conflictos entre transacciones es realmente bajo. La comprobación de validación para la transacción Tj exige que, para toda transacción Ti con MT(Ti ) < MT(Tj ), se cumplan una de las dos condiciones siguientes: 1. Fin(Ti ) < Inicio(Tj ). Puesto que Ti completa su ejecución antes de que comience Tj , el orden de secuencialidad se mantiene realmente. 2. El conjunto de todos los elementos de datos que escribe Ti tiene intersección vacía con el conjunto de elementos de datos que lee Tj , y Ti completa su fase de escritura antes de que Tj comience su fase de validación (Inicio(Tj ) < Fin(Ti ) < Validación(Tj )). Esta condición asegura que las escrituras de Ti y Tj no se superpongan. Puesto que las escrituras de Ti no afectan a la lectura de Tj , y puesto que Tj no puede afectar a la lectura de Ti , el orden de secuencialidad se mantiene realmente. Como ejemplo considérense de nuevo las transacciones T14 y T15 . Supóngase que MT(T14 ) < MT(T15 ). Entonces la fase de validación tiene éxito y produce la planificación 5, la cual se describe en la Figura 16.15. Obsérvese que las escrituras a las variables actuales se realizan sólo después de la fase de validación de T15 . Así, T14 lee los valores anteriores de B y A y la planificación es secuenciable. El esquema de validación evita automáticamente los retrocesos en cascada, ya que las escrituras reales tienen lugar sólo después de que la transacción que ejecuta la escritura se haya comprometido. Sin embargo, existe una posibilidad de inanición de las transacciones largas debido a una secuencia de

www.detodoprogramacion.com


544

Capítulo 16

Control de concurrencia

T14 leer(B)

T15 leer(B) B := B - 50 leer(A) A := A + 50

leer(A) h validar i visualizar(A + B) h validar i escribir(B) escribir(A) Figura 16.15

Planificación 5 producida usando validación.

transacciones cortas conflictivas que provoca reinicios repetidos de la transacción larga. Para evitar la inanición es necesario bloquear las transacciones conflictivas de forma temporal para permitir que la transacción larga termine. Este esquema de validación se denomina esquema control de concurrencia optimista dado que las transacciones se ejecutan de forma optimista, asumiendo que serán capaces de finalizar la ejecución y validar al final. En cambio, los bloqueos y la ordenación por marcas temporales son pesimistas en cuanto que fuerzan una espera o un retroceso cada vez que se detecta un conflicto, aun cuando existe una posibilidad de que la planificación sea secuenciable en cuanto a conflictos. 16.4 Granularidad múltiple

En los esquemas de control de concurrencia que se han descrito antes se ha tomado cada elemento de datos individual como la unidad sobre la cual se producía la sincronización. Sin embargo, hay circunstancias en las que puede ser conveniente agrupar varios elementos de datos y tratarlos como una unidad individual de sincronización. Por ejemplo, si la transacción Ti tiene que acceder a toda la base de datos y se usa un protocolo de bloqueo, entonces Ti debe bloquear cada elemento de la base de datos. Ejecutar estos bloqueos produce claramente un consumo de tiempo. Sería mejor que Ti pudiera realizar una única petición de bloqueo para bloquear toda la base de datos. Por otro lado, si la transacción Tj necesita acceder sólo a unos cuantos datos no sería necesario bloquear toda la base de datos, ya que en ese caso se perdería la concurrencia. Lo que se necesita es un mecanismo que permita al sistema definir múltiples niveles de granularidad. Se puede hacer uno permitiendo que los elementos de datos sean de varios tamaños y definiendo una jerarquía de granularidades de los datos, en la cual las granularidades pequeñas están anidadas en otras más grandes. Una jerarquía tal se puede representar gráficamente como un árbol. Obsérvese que el árbol que se usa aquí es significativamente distinto del que se usaba en el protocolo de árbol (Apartado 16.1.5). Un nodo interno del árbol de granularidad múltiple representa los datos que se asocian con sus descendientes. En el protocolo de árbol cada nodo es un elemento de datos independiente. Como ejemplo considérese el árbol de la Figura 16.16, el cual consiste en cuatro niveles de nodos. El nivel superior representa toda la base de datos. Después de éste están los nodos de tipo zona; la base de datos consiste en estas zonas exactamente. Cada zona tiene nodos de tipo archivo como hijos. Cada zona contiene exactamente aquellos archivos que sean sus nodos hijos. Ningún archivo está en más de una zona. Finalmente, cada archivo tiene nodos de tipo registro. Como antes, un archivo consiste exactamente en aquellos registros que sean sus nodos hijos y ningún registro puede estar presente en más de un archivo. Se puede bloquear individualmente cada nodo del árbol. Como ya se hizo en el protocolo de bloqueo de dos fases, se van a usar los modos de bloqueo compartido y exclusivo. Cuando una transacción bloquea un nodo, tanto en modo compartido como exclusivo, también bloquea todos los descendientes de ese nodo con el mismo modo de bloqueo. Por ejemplo, si la transacción Ti bloquea explícitamente el archivo Ac de la Figura 16.16 en modo exclusivo, entonces bloquea implícitamente en modo exclusivo

www.detodoprogramacion.com


16.4

Granularidad múltiple

545

BD

Fa

ra1

ra2

ran

Figura 16.16

rb1

A1

A2

Fb

Fc

rbk

rc 1

rcm

Jerarquía de granularidad.

todos los registros que pertenecen a dicho archivo. No es necesario que bloquee explícitamente cada registro individual de Fc . Supóngase que la transacción Tj quiere bloquear el registro rb6 del archivo Ab . Puesto que Ti ha bloqueado Ab explícitamente, se entiende que también se bloquea rb6 (implícitamente). Pero cuando Tj realiza una petición de bloqueo sobre rb6 , ¡ rb6 no está bloqueado explícitamente! ¿Cómo puede determinar el sistema si Tj puede bloquear rb6 ? Tj debe recorrer el árbol desde la raíz hasta el nodo rb6 . Si cualquier nodo del camino está bloqueado en un modo incompatible entonces hay que retrasar Tj . Supóngase ahora que la transacción Tk quiere bloquear toda la base de datos. Para hacer esto debe bloquear simplemente la raíz de la jerarquía. Obsérvese, sin embargo, que Tk no tendrá éxito al bloquear el nodo raíz, ya que Ti posee un bloqueo sobre parte del árbol (en concreto sobre el archivo Ab ). ¿Pero cómo determina el sistema si se puede bloquear el nodo raíz? Una posibilidad es buscar en todo el árbol. Sin embargo, esta solución anula el propósito del esquema de bloqueo de granularidad múltiple. Un modo más eficiente de obtener este conocimiento es introducir una nueva clase de modo de bloqueo que se denomina modo de bloqueo intencional. Si un nodo se bloquea en modo intencional se está haciendo un bloqueo explícito en un nivel inferior del árbol (es decir, en una granularidad más fina). Los bloqueos intencionales se colocan en todos los ascendientes de un nodo antes de bloquearlo explícitamente. Así, no es necesario que una transacción busque en todo el árbol para determinar si puede bloquear un nodo con éxito. Una transacción que quiera bloquear un nodo— por ejemplo Q—debe recorrer el camino en el árbol desde la raíz hasta Q. Durante el recorrido del árbol la transacción bloquea los distintos nodos en un modo intencional. Hay un modo intencional asociado al modo compartido y hay otro asociado al modo exclusivo. Si un nodo se bloquea en modo intencional-compartido (IC) se realiza un bloqueo explícito en un nivel inferior del árbol, pero sólo con bloqueos en modo compartido. De forma similar, si se bloquea un nodo en modo intencional-exclusivo (IX) entonces el bloqueo explícito se hace en un nivel inferior con bloqueos en modo exclusivo o en modo compartido. Finalmente, si se bloquea un nodo en modo intencional-exclusivo y compartido (IXC) el subárbol cuya raíz es ese nodo se bloquea explícitamente en modo exclusivo, y dicho bloqueo explícito se produce en un nivel inferior con bloqueos en modo exclusivo. La función de compatibilidad para estos modos de bloqueo se presenta en la Figura 16.17.

IC IX C IXC X

IC cierto cierto cierto cierto falso

Figura 16.17

IX cierto cierto falso falso falso

C cierto falso cierto falso falso

IXC cierto falso falso falso falso

X falso falso falso falso falso

Matriz de compatibilidad.

www.detodoprogramacion.com


546

Capítulo 16

Control de concurrencia

El protocolo de bloqueo de granularidad múltiple siguiente asegura la secuencialidad. Cada transacción Ti puede bloquear un nodo Q usando las reglas siguientes: 1. Debe observar la función de compatibilidad de bloqueos de la Figura 16.17. 2. Debe bloquear la raíz del árbol en primer lugar y puede bloquearla en cualquier modo. 3. Puede bloquear un nodo Q en modo C o IC sólo si está bloqueando actualmente al padre de Q en modo IX o IC. 4. Puede bloquear un nodo Q en modo X, IXC o IX sólo si está bloqueando actualmente al padre de Q en modo IX o IXC. 5. Puede bloquear un nodo sólo si no ha desbloqueado previamente ningún nodo (es decir, Ti es de dos fases). 6. Puede desbloquear un nodo Q sólo si no ha bloqueado a ninguno de los hijos de Q. Obsérvese que en el protocolo de granularidad múltiple es necesario que se adquieran los bloqueos en orden descendente (de la raíz a las hojas), y que se liberen en orden ascendente (de las hojas a la raíz). Para ilustrar este protocolo considérese el árbol de la Figura 16.16 y las transacciones siguientes: • Supóngase que la transacción T18 lee el registro ra2 del archivo Aa . Entonces T18 necesita bloquear la base de datos, la zona Z1 y Aa en modo IC (y en este orden) y finalmente debe bloquear ra2 en modo C. • Supóngase que la transacción T19 modifica el registro ra9 del archivo Aa . Entonces T19 necesita bloquear la base de datos, la zona Z1 y el archivo Aa en modo IX y finalmente debe bloquear ra9 en modo X. • Supóngase que la transacción T20 lee todos los registros del archivo Aa . Entonces, T20 necesita bloquear la base de datos y la zona Z1 (en este orden) en modo IC y finalmente debe bloquear Aa en modo C. • Supóngase que la transacción T21 lee toda la base de datos. Puede hacer esto una vez que bloquee la base de datos en modo C. Se observa que las transacciones T18 , T20 y T21 pueden acceder concurrentemente a la base de datos. La transacción T19 se puede ejecutar concurrentemente con T18 , pero no con T20 ni con T21 . Este protocolo permite la concurrencia y reduce la sobrecarga de bloqueos. Es particularmente útil en las aplicaciones con una mezcla de: • Transacciones cortas que sólo acceden a algunos elementos de datos. • Transacciones largas que producen informes a partir de un archivo completo o un conjunto de archivos. Existe un protocolo de bloqueo similar que es aplicable a sistemas de bases de datos en los cuales las granularidades de los datos se organizan en forma de grafo dirigido acíclico. Véanse las notas bibliográficas para obtener referencias adicionales. En este protocolo son posibles los interbloqueos, al igual que en los protocolos de bloqueo de dos fases. Existen técnicas para reducir la frecuencia de interbloqueos en el protocolo de granularidad múltiple y también para eliminar los interbloqueos completamente. Se hace referencia a estas técnicas en las notas bibliográficas. 16.5 Esquemas multiversión

Los esquemas de control de concurrencia que se han descrito anteriormente aseguran la secuencialidad o bien retrasando una operación o bien abortando la transacción que realiza la operación. Por ejemplo, una operación leer se puede retrasar porque todavía no se haya escrito el valor apropiado; o se puede rechazar (es decir, la transacción que la realiza debe abortarse) porque se haya sobrescrito el valor que

www.detodoprogramacion.com


16.5

Esquemas multiversión

547

supuestamente se iba a leer. Se podrían evitar estos problemas si se mantuvieran en el sistema copias anteriores de cada elemento de datos. En los esquemas de control de concurrencia multiversión, cada operación escribir(Q) crea una nueva versión de Q. Cuando se realiza una operación leer(Q) el gestor de control de concurrencia elige una de las versiones de Q que se va a leer. El esquema de control de concurrencia debe asegurar que la elección de la versión que se va a leer se haga de tal manera que asegure la secuencialidad. Así mismo es crucial, por motivos de rendimiento, que una transacción sea capaz de determinar rápida y fácilmente la versión del elemento de datos que se va a leer. 16.5.1 Ordenación por marcas temporales multiversión

La técnica más frecuentemente utilizada en los esquemas multiversión es la de las marcas temporales. A cada transacción Ti del sistema se le asocia una única marca temporal estática que se denota MT(Ti ). El sistema de bases de dates asigna dicha marca temporal antes de que la transacción comience su ejecución, como se ha descrito en el Apartado 16.2. A cada elemento de datos Q se el asocia una secuencia de versiones <Q1 , Q2 , . . ., Qm >. Cada versión Qk contiene tres campos: • contenido es el valor de la versión Qk . • marca-temporal-E(Qk ) es la marca temporal de la transacción que haya creado la versión Qk . • marca-temporal-L(Qk ) es la mayor marca temporal de todas las transacciones que hayan leído con éxito la versión Qk . Una transacción — por ejemplo, Ti —crea una nueva versión Qk del elemento de datos Q realizando la operación escribir(Q). El campo contenido de la versión tiene el valor que ha escrito Ti . El sistema inicializa la marca-temporal-E y marca-temporal-L con MT(Ti ). El valor marca-temporal-L se actualiza cada vez que una transacción Tj lee el contenido de Qk y marca-temporal-L(Qk ) < MT(Tj ). El esquema de marcas temporales multiversión que se muestra a continuación asegura la secuencialidad. El esquema opera como sigue. Supóngase que la transacción Ti realiza una operación leer(Q) o escribir(Q). Sea Qk la versión de Q cuya marca temporal de escritura es la mayor marca temporal menor o igual que MT(Ti ). 1. Si la transacción Ti ejecuta leer(Q) entonces el valor que se devuelve es el contenido de la versión Qk . 2. Si la transacción Ti ejecuta escribir(Q) y si MT(Ti ) < marca-temporal-L(Qk ) entonces la transacción Ti retrocede. Si no, si MT(Ti ) = marca-temporal-E(Qk ) se sobrescribe el contenido de Qk , y en otro caso se crea una nueva versión de Q. La justificación de la regla 1 es clara. Una transacción lee la versión más reciente que viene antes de ella en el tiempo. La segunda regla fuerza a que se aborte una transacción que realice una escritura “demasiado tarde”. Con más precisión, si Ti intenta escribir una versión que alguna otra transacción haya leído, entonces no se puede permitir que dicha escritura tenga éxito. La versiones que ya no se necesitan se borran basándose en la regla siguiente. Supóngase que hay dos versiones, Qk y Qj , de un elemento de datos y que ambas tienen marca-temporal-E menor que la marca temporal de la transacción más antigua en el sistema. Entonces no se volverá a usar la versión más antigua de Qk y Qj y se puede borrar. El esquema de ordenación por marcas temporales multiversión tiene la propiedad deseable de que nunca falla una petición de lectura y nunca tiene que esperar. En sistemas de bases de datos típicos, en los cuales la lectura es una operación mucho más frecuente que la escritura, esta ventaja puede tener un mayor significado práctico. Este esquema, sin embargo, tiene dos propiedades no deseables. En primer lugar, la lectura de un elemento de datos necesita también la actualización del campo marca-temporal-L, lo que tiene como resultado dos accesos potenciales al disco en lugar de uno. En segundo lugar, los conflictos entre las

www.detodoprogramacion.com


548

Capítulo 16

Control de concurrencia

transacciones se resuelven por medio de retrocesos en lugar de esperas. Esta alternativa puede ser costosa. En el Apartado 16.5.2 se describe un algoritmo que evita este problema. Este esquema de ordenación por marcas temporales multiversión no asegura la recuperabilidad y la ausencia de cascadas. Se puede extender de la misma forma que el esquema de ordenación por marcas temporales básico, para hacerlo recuperable y sin cascadas.

16.5.2 Bloqueo de dos fases multiversión

El protocolo de bloqueo de dos fases multiversión intenta combinar las ventajas del control de concurrencia multiversión con las ventajas del bloqueo de dos fases. Este protocolo distingue entre transacciones de sólo lectura y transacciones de actualización. Las transacciones de actualización realizan un bloqueo de dos fases riguroso; es decir, mantienen todos los bloqueos hasta el final de la transacción. Así, se pueden secuenciar según su orden de terminación. Cada elemento de datos tiene una única marca temporal. La marca temporal no es en este caso una marca temporal basada en un reloj real, sino que es un contador, que se denomina contador-mt, que se incrementa durante el procesamiento del compromiso. A las transacciones de sólo lectura se les asigna una marca temporal leyendo el valor actual de contador-mt antes de que comiencen su ejecución; para realizar las lecturas siguen el protocolo de ordenación por marcas temporales multiversión. Así, cuando una transacción de sólo lectura Ti ejecuta leer(Q), el valor que se devuelve es el contenido de la versión con la mayor marca temporal menor o igual que MT(Ti ). Cuando una transacción de actualización lee un elemento obtiene un bloqueo compartido sobre él y lee la versión más reciente de dicho elemento de datos. Cuando una transacción de actualización quiere escribir un elemento, obtiene primero un bloqueo exclusivo sobre el elemento, y luego crea una nueva versión del elemento de datos. La escritura se realiza sobre la nueva versión y la marca temporal de la nueva versión tiene inicialmente el valor ∞, el cual es mayor que el de cualquier marca temporal posible. Una vez que la transacción Ti ha completado sus acciones realiza el procesamiento del compromiso como sigue: en primer lugar, Ti asigna la marca temporal de todas las versiones que ha creado al valor de contador-mt más 1; después Ti incrementa contador-mt en 1. Sólo se permite que realice el procesamiento del compromiso a una transacción de actualización a la vez. Como resultado, las transacciones que comiencen después de que Ti incremente contador-mt observarán los valores que Ti ha actualizado, mientras que aquéllas que comiencen antes de que Ti incremente contador-mt observarán los valores anteriores a la actualización de Ti . En ambos casos las transacciones de sólo lectura no tienen que esperar nunca por los bloqueos. El bloqueo de dos fases multiversión también asegura que las planificaciones recuperables y sin cascadas. Las versiones se borran de forma similar a la utilizada en la ordenación por marcas temporales multiversión. Supóngase que hay dos versiones, Qk y Qj , de un elemento de datos y que ambas versiones tienen una marca temporal menor o igual que la de la transacción de sólo lectura más antigua del sistema. Entonces la versión más antigua de Qk y Qj no se volverá a utilizar y se puede borrar. El bloqueo de dos fases multiversión o variaciones de éste se usan en algunos sistemas de bases de datos comerciales.

16.6 Tratamiento de interbloqueos

Un sistema está en estado de interbloqueo si existe un conjunto de transacciones tal que toda transacción del conjunto está esperando a otra transacción del conjunto. Con mayor precisión, existe un conjunto de transacciones en espera {T0 , T1 , . . ., Tn } tal que T0 está esperando a un elemento de datos que posee T1 , y T2 está esperando a un elemento de datos que posee T2 , y . . ., y Tn−1 está esperando a un elemento de datos que posee Tn , y Tn está esperando a un elemento que posee T0 . En tal situación ninguna de las transacciones puede progresar. El único remedio a esta situación no deseada es que el sistema invoque alguna acción drástica, como hacer retroceder alguna de las transacciones involucradas en el interbloqueo. El retroceso de una transac-

www.detodoprogramacion.com


16.6

Tratamiento de interbloqueos

549

ción puede ser parcial: esto es, se puede retroceder una transacción hasta el punto donde obtuvo un bloqueo cuya liberación resuelve el interbloqueo. Existen dos métodos principales para tratar el problema de los interbloqueos. Se puede utilizar un protocolo de prevención de interbloqueos para asegurar que el sistema nunca llega a un estado de interbloqueo. De forma alternativa se puede permitir que el sistema llegue a un estado de interbloqueo, y tratar de recuperarse después a través de un esquema de detección y recuperación de interbloqueos. Como se verá a continuación, ambos pueden provocar retroceso de las transacciones. La prevención se usa normalmente cuando la probabilidad de que el sistema llegue a un estado de interbloqueo es relativamente alta; en otro caso es más eficiente usar la detección y recuperación. Obsérvese que el esquema de detección y recuperación necesita una sobrecarga que incluye no sólo el coste en tiempo de ejecución para mantener la información necesaria para ejecutar el algoritmo de detección, sino también las pérdidas potenciales inherentes a la recuperación de un interbloqueo. 16.6.1 Prevención de interbloqueos

Existen dos enfoques a la prevención de interbloqueos. Un enfoque asegura que no puede haber esperas cíclicas ordenando las peticiones de bloqueo o exigiendo que todos los bloqueos se adquieran juntos. El otro enfoque es más cercano a la recuperación de interbloqueos y realiza retrocesos de las transacciones en lugar de esperar un bloqueo, siempre que el bloqueo pueda llevar potencialmente a un interbloqueo. El esquema más simple para la primera aproximación exige que cada transacción bloquee todos sus elementos de datos antes de comenzar su ejecución. Además, o bien se bloquean todos en un paso o ninguno de ellos se bloquea. Este protocolo tiene dos inconvenientes principales: (1) a menudo es difícil predecir, antes de que comience la transacción, cuáles son los elementos de datos que es necesario bloquear; (2) la utilización de elementos de datos puede ser muy baja, ya que muchos de los elementos de datos pueden estar bloqueados pero sin usar durante mucho tiempo. Otro esquema para prevenir interbloqueos consiste en imponer un orden parcial a todos los elementos de datos y exigir que una transacción bloquee un elemento de datos sólo en el orden que especifica dicho orden parcial. Se ha visto un esquema así en el protocolo de árbol, que usa una ordenación parcial de los elementos de datos. Una variante a esta aproximación es utilizar un orden total de los elementos de datos, en conjunción con el bloqueo de dos fases. Una vez que una transacción ha bloqueado un elemento en particular, no puede solicitar bloqueos sobre elementos que preceden a dicho elemento en la ordenación. Este esquema es fácil de implementar siempre que el conjunto de los elementos de datos a los que accede una transacción se conozca cuando la transacción comienza la ejecución. No hay necesidad de cambiar el sistema de control de concurrencia subyacente si se utiliza bloqueo de dos fases: todo lo que hace falta es asegurar que los bloqueos se solicitan en el orden adecuado. La segunda aproximación para prevenir interbloqueos consiste en utilizar expropiación y retrocesos de transacciones. En la expropiación, cuando la transacción T2 solicita un bloqueo que la transacción T1 posee, el bloqueo concedido a T1 debe expropiarse retrocediendo T1 y concediéndolo a continuación a T2 . Para controlar la expropiación se asigna una marca temporal única a cada transacción. El sistema usa estas marcas temporales sólo para decidir si una transacción debe esperar o retroceder. Para el control de concurrencia se sigue usando el bloqueo. Si una transacción retrocede mantiene su marca temporal antigua cuando vuelva a comenzar. Se han propuesto dos esquemas de prevención de interbloqueos que usan marcas temporales: 1. El esquema esperar–morir está basado en una técnica sin expropiación. Cuando la transacción Ti solicita un elemento de datos que posee actualmente Tj , Ti puede esperar sólo si tiene una marca temporal más pequeña que la de Tj (es decir, Ti es anterior a Tj ). En caso contrario Ti retrocede (muere). Por ejemplo, supóngase que las transacciones T22 , T23 y T24 tienen marcas temporales 5, 10 y 15 respectivamente. Si T22 solicita un elemento de datos que posee T23 entonces T22 tiene que esperar. Si T24 solicita un elemento de datos que posee T23 entonces T24 retrocede. 2. El esquema herir–esperar está basado en una técnica de expropiación. Es el opuesto del esquema esperar–morir. Cuando la transacción Ti solicita un elemento de datos que posee actualmente Tj ,

www.detodoprogramacion.com


550

Capítulo 16

Control de concurrencia

Ti puede esperar sólo si tiene una marca temporal mayor que la de Tj (es decir, Ti es más reciente que Tj ). En caso contrario Tj retrocede (Ti hiere a Tj ). Volviendo al ejemplo anterior con las transacciones T22 , T23 y T24 , si T22 solicita un elemento de datos que posee T23 entonces se expropia este elemento de datos y T23 retrocede. Si T24 solicita el elemento de datos que posee T23 entonces T24 debe esperar. Siempre que retrocedan las transacciones, es importante asegurarse de que no exista inanición—es decir, ninguna transacción retrocede repetidamente y nunca se le permite progresar. Tanto el esquema herir–esperar como el esperar–morir impiden la inanición: en todo momento hay una transacción con la menor marca temporal. Dicha transacción no puede retroceder en ninguno de los dos esquemas. Puesto que las marcas temporales siempre se incrementan, y puesto que no se asignan a las transacciones nuevas marcas temporales cuando retroceden, una transacción que retrocede tendrá finalmente la menor marca temporal. De este modo no retrocederá de nuevo. Sin embargo, existen algunas diferencias en el modo en que operan estos dos esquemas. • En el esquema esperar–morir una transacción más antigua debe esperar a que una más reciente libere sus elementos de datos. Así, cuanto más antigua se vuelve una transacción más tiende a esperar. Por el contrario, en el esquema herir–esperar, una transacción más antigua nunca espera a una más reciente. • En el esquema esperar–morir, si la transacción Ti muere y retrocede a causa de que ha solicitado un elemento de datos que posee la transacción Tj , entonces Ti puede volver a realizar la misma secuencia de peticiones cuando vuelva a comenzar. Si Tj posee todavía el elemento de datos, entonces Ti morirá de nuevo. De este modo Ti morirá varias veces hasta que adquiera el elemento de datos que necesita. Compárese esta secuencia de sucesos con la que ocurre en el esquema herir–esperar. La transacción Ti está herida y retrocede porque Tj solicita un elemento de datos que posee. Cuando vuelve a comenzar Ti y solicita el elemento de datos que ahora posee Tj , Ti espera. De este modo puede haber menos retrocesos en el esquema herir–esperar. El principal problema de cualquiera de estos dos esquemas es que se pueden dar retrocesos innecesarios. 16.6.2 Esquemas basados en límite de tiempo

Otro enfoque simple al tratamiento de interbloqueos se basa en bloqueos con límite de tiempo. En este enfoque una transacción que haya solicitado un bloqueo espera por lo menos durante un intervalo de tiempo especificado. Si no se concede el bloqueo en ese tiempo, se dice que la transacción está fuera de tiempo y ella misma retrocede y vuelve a comenzar. Si de hecho había un interbloqueo, una o varias de las transacciones involucradas en dicho interbloqueo estarán fuera de tiempo y retrocederán, lo que permitirá continuar a las demás. Este esquema se encuentra en un lugar entre la prevención de interbloqueos, donde nunca puede haber un interbloqueo, y la detección y recuperación, las cuales se describen en el Apartado 16.6.3. El esquema de límite de tiempo es particularmente fácil de implementar y funciona bien si las transacciones son cortas y, si son largas, las esperas deben de ser a causa de los interbloqueos. Sin embargo, es difícil en general decidir cuánto debe esperar una transacción para que esté fuera de tiempo. Esperas demasiado largas provocan retardos innecesarios una vez que se ha producido un interbloqueo. Esperas demasiado cortas producen el retroceso de la transacción incluso si no hay interbloqueo, provocando un gasto de recursos. La inanición es también posible con este esquema. Por tanto el esquema basado en límite de tiempo tiene una aplicación limitada. 16.6.3 Detección y recuperación de interbloqueos

Si el sistema no utiliza algún protocolo que asegure la ausencia de interbloqueos, entonces se debe usar un esquema de detección y recuperación. Periódicamente se invoca a un algoritmo que examina el estado del sistema para determinar si hay un interbloqueo. Si lo hay, entonces el sistema debe intentar recuperarse del interbloqueo. Para ello, el sistema debe:

www.detodoprogramacion.com


16.6

T26

Tratamiento de interbloqueos

551

T28

T25 T27

Figura 16.18

Grafo de espera sin ciclos.

• Mantener información sobre la asignación de los elementos de datos a las transacciones, así como de toda petición de elemento de datos pendiente. • Proporcionar un algoritmo que use esta información para determinar si el sistema ha entrado en un estado de interbloqueo. • Recuperarse del interbloqueo cuando el algoritmo de detección determine que existe un interbloqueo. En este apartado se van a desarrollar estos puntos. 16.6.3.1 Detección de interbloqueos

Los interbloqueos se pueden describir con precisión por medio de un grafo dirigido llamado grafo de espera. Este grafo consiste en un par G = (V,A), siendo V el conjunto de vértices y A el conjunto de arcos. El conjunto de vértices consiste en todas las transacciones del sistema. Cada elemento del conjunto E de arcos es un par ordenado Ti → Tj . Si Ti → Tj pertenece a A entonces hay un arco dirigido de la transacción Ti a Tj , lo cual implica que la transacción Ti está esperando a que la transacción Tj libere un elemento de datos que necesita. Cuando la transacción Ti solicita un elemento de datos que posee actualmente la transacción Tj , entonces se inserta el arco Ti → Tj en el grafo de espera. Este arco sólo se borra cuando la transacción Tj deja de poseer un elemento de datos que necesite la transacción Ti . Existe un interbloqueo en el sistema si y sólo si el grafo de espera contiene un ciclo. Se dice que toda transacción involucrada en el ciclo está interbloqueada. Para detectar los interbloqueos el sistema debe mantener el grafo de espera y debe invocar periódicamente a un algoritmo que busque un ciclo en el grafo. Para ilustrar estos conceptos considérese el grafo de espera de la Figura 16.18, el cual describe la situación siguiente: • La transacción T25 está esperando a las transacciones T26 y T27 . • La transacción T27 está esperando a la transacción T26 . • La transacción T26 está esperando a la transacción T28 . Puesto que el grafo no tiene ciclos, el sistema no está en un estado de interbloqueo. Supóngase ahora que la transacción T28 solicita un elemento que posee T27 . Se añade el arco T28 → T27 al grafo de espera, lo que resulta en el nuevo estado que se ilustra en la Figura 16.19. Ahora el grafo tiene el ciclo T26 → T28 → T27 → T26 lo que implica que las transacciones T26 , T27 y T28 están interbloqueadas. Por consiguiente surge la pregunta: ¿cuándo se debe invocar al algoritmo de detección? La respuesta depende de dos factores: 1. ¿Cada cuánto tiempo tiene lugar un interbloqueo? 2. ¿Cuántas transacciones se verán afectadas por el interbloqueo?

www.detodoprogramacion.com


552

Capítulo 16

Control de concurrencia

T26

T28

T25 T27

Figura 16.19

Grafo de espera con un ciclo.

Si los interbloqueos ocurren con frecuencia, entonces se debe invocar al algoritmo de detección con mayor frecuencia de la usual. Los elementos de datos asignados a las transacciones interbloqueadas no estarán disponibles para otras transacciones hasta que pueda romperse el interbloqueo. Adicionalmente puede también aumentar el número de ciclos en el grafo. En el peor caso se invoca al algoritmo de detección cada vez que una petición de asignación no se pueda conceder inmediatamente.

16.6.3.2 Recuperación de interbloqueos

Cuando un algoritmo de detección de interbloqueos determina que existe un interbloqueo, el sistema debe recuperarse del mismo. La solución más común es retroceder una o más transacciones para romper el interbloqueo. Se deben realizar tres acciones: 1. Selección de una víctima. Dado un conjunto de transacciones interbloqueadas se debe determinar la transacción (o transacciones) que se van a retroceder para romper el interbloqueo. Se deben retroceder aquellas transacciones que incurran en un coste mínimo. Desafortunadamente, el término coste mínimo no es preciso. Hay muchos factores que determinan el coste de un retroceso, como a. b. c. d.

Lo que la transacción ha calculado y lo que se calculará hasta completar su tarea designada. El número de elementos de datos que ha usado la transacción. La cantidad de elementos de datos que necesita la transacción para que se complete. El número de transacciones que se verán involucradas en el retroceso.

2. Retroceso. Una vez que se ha decidido que retrocederá una transacción en particular, se debe determinar hasta dónde retrocederá dicha transacción. La solución más simple consiste en un retroceso total: se aborta la transacción y luego vuelve a comenzar. Sin embargo, es más efectivo hacer retroceder la transacción sólo lo necesario para romper el interbloqueo. Dicho retroceso parcial requiere que el sistema mantenga información adicional sobre el estado de todas las transacciones que están en ejecución. Concretamente, es necesario registrar la secuencia de solicitudes/concesiones de bloqueos y de actualizaciones realizadas por la transacción. El mecanismo de detección de interbloqueos debería decidir qué bloqueos necesita liberar la transacción seleccionada para romper el interbloqueo. Hay que hacer retroceder la transacción seleccionada hasta el punto donde obtuvo el primero de esos bloqueos, deshaciendo todas las acciones que realizó desde ese punto. El mecanismo de recuperación debe ser capaz de realizar tales retrocesos parciales. Además, las transacciones deben ser capaces de reanudar la ejecución después de un retroceso parcial. Véase el apartado de notas bibliográficas para obtener las referencias pertinentes. 3. Inanición. En un sistema en el cual la selección de víctimas esté basada principalmente en factores de coste, puede ocurrir que siempre se elija a la misma transacción como víctima. El resultado es que esta transacción no completa nunca su tarea designada. Dicha situación se denomina inanición. Se debe asegurar que una transacción pueda elegirse como víctima sólo un número finito (y pequeño) de veces. La solución más común consiste en incluir en el factor de coste el número de retrocesos.

www.detodoprogramacion.com


16.7

Operaciones para insertar y borrar

553

16.7 Operaciones para insertar y borrar

Hasta ahora se ha centrado la atención en las operaciones leer y escribir. Esta ligadura limita a las transacciones a los elementos de datos que ya están en la base de datos. Algunas transacciones necesitan no sólo acceder a los elementos de datos existentes, sino también poder crear nuevos elementos de datos. Otras necesitan tener la posibilidad de borrar elementos de datos. Para examinar la forma en que tales transacciones afectan al control de concurrencia se introducen las operaciones adicionales siguientes: • borrar(Q) borra de la base de datos el elemento de datos Q. • insertar(Q) inserta en la base de datos el nuevo elemento de datos Q y le asigna un valor inicial. Si la transacción Ti intenta ejecutar una operación leer(Q) después de haberse borrado Q se produce un error lógico en Ti . Igualmente, si la transacción Ti intenta ejecutar una operación leer(Q) antes de que Q se haya insertado produce un error lógico en Ti . También es un error lógico intentar borrar un dato inexistente. 16.7.1 Borrado

Para comprender la manera en que puede afectar la presencia de las instrucciones borrar al control de concurrencia, se debe decidir en qué casos una instrucción borrar está en conflicto con otra instrucción. Sean Ii e Ij instrucciones de Ti y Tj , respectivamente, que están consecutivas en la planificación S. Sea Ii = borrar(Q). Se consideran distintas instrucciones Ij : • Ij = leer(Q). Ii e Ij están en conflicto. Si Ii está antes de Ij , Tj tendrá un error lógico. Si Ij está antes de Ii , Tj puede ejecutar con éxito su operación leer. • Ij = escribir(Q). Ii e Ij están en conflicto. Si Ii está antes de Ij , Tj tendrá un error lógico. Si Ij está antes de Ii , Tj puede ejecutar con éxito su operación escribir. • Ij = borrar(Q). Ii e Ij están en conflicto. Si Ii está antes de Ij , Tj tendrá un error lógico. Si Ij está antes de Ii , Ti tendrá un error lógico. • Ij = insertar(Q). Ii e Ij están en conflicto. Supóngase que no existe el elemento de datos Q antes de la ejecución de Ii e Ij . Entonces si Ii está antes de Ij , hay un error lógico en Ti . Si Ij está antes de Ii , entonces no hay ningún error lógico. Igualmente si Q existía antes de la ejecución de Ii e Ij , entonces hay un error lógico si Ij está antes de Ii , pero no en otro caso. Se puede concluir lo siguiente: • En el protocolo de dos fases se necesita un bloqueo exclusivo en un elemento de datos antes de que se borre dicho elemento. • En el protocolo de ordenación por marcas temporales se debe hacer una prueba similar que la que se hacía con escribir. Supóngase que la transacción Ti ejecuta borrar(Q). ¤ Si MT(Ti ) < marca-temporal-L(Q), entonces el valor de Q que va a borrar Ti lo ha leído ya otra transacción Tj con MT(Tj ) >MT(Ti ). Por tanto se rechaza la operación borrar y Ti retrocede. ¤ Si MT(Ti ) < marca-temporal-E(Q), entonces la transacción Tj con MT(Tj ) >MT(Ti ) ha escrito Q. Por tanto se rechaza esta operación borrar y Ti retrocede. ¤ En otro caso se ejecuta la operación borrar. 16.7.2 Inserción

Ya se ha visto que una operación insertar(Q) está en conflicto con una operación borrar(Q). De forma similar insertar(Q) está en conflicto con las operaciones leer(Q) y escribir(Q). No se pueden realizar operaciones leer o escribir sobre un elemento de datos hasta que este último exista. Puesto que insertar(Q) asigna un valor al elemento de datos Q, se trata insertar de forma similar a escribir desde el punto de vista del control de concurrencia:

www.detodoprogramacion.com


554

Capítulo 16

Control de concurrencia

• En el protocolo de bloqueo de dos fases, si Ti realiza un operación insertar(Q), se da a Ti un bloqueo exclusivo sobre el elemento de datos Q recientemente creado. • En el protocolo de ordenación por marcas temporales, si Ti realiza una operación insertar(Q), se fijan los valores marca-temporal-L(Q) y marca-temporal-E(Q) a MT(Ti ). 16.7.3 El fenómeno fantasma

Considérese una transacción T29 que ejecuta la siguiente pregunta SQL a la base de datos bancaria: select sum(saldo) from cuenta where nombre_sucursal = ’Pamplona’ La transacción T29 necesita acceder a todas las tuplas de la relación cuenta que pertenezcan a la sucursal Pamplona. Sea T30 una transacción que ejecuta la siguiente inserción SQL: insert into cuenta values (C-201, ’Pamplona’, 900) Sea P una planificación que involucra a T29 y T30 . Se espera que haya un conflicto potencial debido a las razones siguientes: • Si T29 utiliza la tupla que ha insertado recientemente T30 al calcular sum(saldo), entonces T29 lee el valor que ha escrito T30 . Así, en una planificación secuencial equivalente a S, T30 debe ir antes de T29 . • Si T29 no utiliza la tupla que ha insertado recientemente T30 al calcular sum(saldo), entonces en una planificación secuencial equivalente a S, T29 debe ir antes de T30 . El segundo caso de los dos es curioso. T29 y T30 no acceden a ninguna tupla común, ¡y sin embargo están en conflicto! En efecto, T29 y T30 están en conflicto en una tupla fantasma. Si se realiza el control de concurrencia con granularidad de tupla, no se detecta dicho conflicto. Como resultado, el sistema podría no impedir una planificación no secuenciable. Este problema recibe el nombre de fenómeno fantasma. Para evitar el fenómeno fantasma se permite que la transacción T29 impida a otras transacciones crear nuevas tuplas en la relación cuenta con nombre_sucursal = “Pamplona”. Para encontrar todas las tuplas de cuenta con nombre_sucursal = “Pamplona”, T29 debe buscar o bien en toda la relación cuenta, o al menos en un índice de la relación. Hasta ahora se ha asumido implícitamente que los únicos elementos de datos a los que accede una transacción son tuplas. Sin embargo T29 es un ejemplo de transacción que lee información acerca de qué tuplas pertenecen a una relación, y T30 es un ejemplo de transacción que actualiza dicha información. Claramente no es suficiente bloquear las tuplas a las que se accede; se necesita también bloquear la información acerca de qué tuplas pertenecen a la relación. La solución más simple a este problema consiste en asociar un elemento de datos con la propia relación; el elemento de datos representa la información utilizada para encontrar las tuplas en la relación. Las transacciones como T29 , que lean la información acerca de qué tuplas pertenecen a la relación, tendrían que bloquear el elemento de datos correspondientes a la relación en modo compartido. Las transacciones como T30 , que actualicen la información acerca de qué tuplas pertenecen a la relación, tendrían que bloquear el elemento de datos en modo exclusivo. De este modo T29 y T30 tendrían un conflicto en un elemento de datos real, en lugar de tenerlo en uno fantasma. No se debe confundir el bloqueo de una relación completa, como en el bloqueo de granularidad múltiple, con el bloqueo del elemento de datos correspondiente a la relación. Al bloquear el elemento de datos la transacción sólo evita que otras transacciones actualicen la información acerca de qué tuplas pertenecen a la relación. Sigue siendo necesario un bloqueo de tuplas. Una transacción que acceda directamente a una tupla puede obtener un bloqueo sobre las tuplas incluso si otra transacción posee un bloqueo exclusivo sobre el elemento de datos correspondiente a la propia relación.

www.detodoprogramacion.com


16.8

Niveles débiles de consistencia

555

El inconveniente principal de bloquear un elemento de datos correspondiente a la relación es el bajo grado de concurrencia— se impide que dos transacciones que inserten distintas tuplas en la relación se ejecuten concurrentemente. Una solución mejor es la técnica de bloqueo del índice. Toda transacción que inserte una tupla en una relación debe insertar información en cada uno de los índices que se mantengan en la relación. Se elimina el fenómeno fantasma al imponer un protocolo para los índices. Para simplificar, sólo se van a considerar los índices del árbol B+ . Como se vio en el Capítulo 12, todo valor de la clave de búsqueda se asocia a un nodo hoja índice. Una consulta usará normalmente uno o más índices para acceder a la relación. Una inserción debe insertar una nueva tupla en todos los índices de la relación. En el ejemplo se asume que hay un índice para cuenta en nombre_sucursal. Entonces T30 debe modificar la hoja que contiene la clave Pamplona. Si T29 lee el mismo nodo hoja para localizar todas las tuplas que pertenecen a la sucursal Pamplona, entonces T29 y T30 tienen un conflicto en dicho nodo hoja. El protocolo de bloqueo del índice toma las ventajas de la disponibilidad de índices en una relación convirtiendo las apariciones del fenómeno fantasma en conflictos en los bloqueos sobre los nodos hoja índice. El protocolo opera de la siguiente manera: • Toda relación debe tener al menos un índice. • Una transacción Ti puede acceder a las tuplas de una relación únicamente después de haberlas encontrado primero a través de uno o más índices de la relación. • Una transacción Ti que realiza una búsqueda (o bien una búsqueda de rango o una búsqueda concreta) debe bloquear en modo compartido todos los nodos hoja índice a los que accede. • Una transacción Ti no puede insertar, borrar o actualizar una tupla ti en una relación r sin actualizar todos los índices de r. La transacción debe obtener bloqueos en modo exclusivo sobre todos los nodos hoja índice que están afectados por la inserción, el borrado o la actualización. Para la inserción y el borrado, los nodos hoja afectados son aquellos que contienen (después de la inserción) o han contenido (antes de la modificación) el valor de la clave de búsqueda en la tupla. Para las actualizaciones, los nodos hoja afectados son los que (antes de la modificación) contienen el valor antiguo de la clave de búsqueda y los nodos que (después de la modificación) contienen el nuevo valor de la clave de búsqueda. • Hay que cumplir las reglas del protocolo de bloqueo de dos fases. Existen variantes de la técnica de bloqueo del índice para eliminar el fenómeno fantasma con otros protocolos de control de concurrencia que se han presentado en este capítulo. 16.8 Niveles débiles de consistencia

La secuencialidad es un concepto útil porque permite a los programadores ignorar los problemas relacionados con la concurrencia cuando codifican las transacciones. Si todas las transacciones tienen la propiedad de mantener la consistencia de la base de datos si se ejecutan por separado, la secuencialidad asegura que las ejecuciones concurrentes mantienen la consistencia. Sin embargo, puede que los protocolos necesarios para asegurar la secuencialidad permitan muy poca concurrencia para algunas aplicaciones. En estos casos se utilizan los niveles más débiles de consistencia. El uso de niveles más débiles de consistencia añade una nueva carga a los programadores para asegurar la corrección de las bases de datos. 16.8.1 Consistencia de grado dos

El objetivo de la consistencia de grado dos es evitar abortar en cascada sin asegurar necesariamente la secuencialidad. El protocolo de bloqueo para la consistencia de grado dos utiliza los mismos dos modos de bloqueo que se utilizan para el protocolo de bloqueo de dos fases: compartido (C) y exclusivo (X). Las transacciones deben mantener el modo de bloqueo adecuado cuando tengan acceso a un elemento de datos.

www.detodoprogramacion.com


556

Capítulo 16

Control de concurrencia

T3 bloquear-C(Q) leer(Q) desbloquear(Q)

T4

bloquear-X(Q) leer(Q) escribir(Q) desbloquear(Q) bloquear-C(Q) leer(Q) desbloquear(Q) Figura 16.20

Planificación no secuenciable con consistencia de grado dos.

A diferencia de la situación en los bloqueos de dos fases, los bloqueos C pueden liberarse en cualquier momento y también se pueden establecer bloqueos en cualquier momento. Los bloqueos exclusivos no se pueden liberar hasta que la transacción se comprometa o se aborte. La secuencialidad no queda asegurada por este protocolo. En realidad, una transacción puede leer dos veces el mismo elemento de datos y obtener resultados diferentes. En la Figura 16.20, T3 lee el valor de Q antes y después de que T4 escriba su valor. La posibilidad de que se produzca inconsistencia con la consistencia de grado dos hace que este enfoque no sea conveniente para muchas aplicaciones. 16.8.2 Estabilidad del cursor

La estabilidad del cursor es una forma de consistencia de grado dos diseñada para programas escritos en lenguajes de propósito general, los cuales iteran sobre las tuplas de una relación utilizando cursores. En vez de bloquear toda la relación, la estabilidad del cursor asegura que: • La tupla que está procesando la iteración esté bloqueada en modo compartido. • Todas las tuplas modificadas estén bloqueadas en modo exclusivo hasta que se comprometa la transacción. Estas reglas aseguran que se obtiene consistencia de grado dos. No se requiere bloqueo de dos fases. No se garantiza la secuencialidad. La estabilidad del cursor se utiliza en la práctica sobre relaciones a las que se accede muchas veces como una forma de incrementar la concurrencia y mejorar el rendimiento del sistema. Las aplicaciones que utilizan estabilidad del cursor deben ser desarrolladas de forma que aseguren la consistencia de la base de datos a pesar de la posibilidad de planificaciones no secuenciables. Por tanto, el uso de estabilidad del cursor está limitado a determinadas situaciones con restricciones simples de consistencia. 16.8.3 Niveles débiles de consistencia en SQL

La norma SQL también permite que una transacción especifique si puede ser ejecutada de tal forma que se convierta en no secuenciable con respecto a otras transacciones. Por ejemplo, una transacción puede operar en el nivel sin compromiso de lectura, lo que permite que la transacción lea registros incluso si éstos no se han comprometido. SQL proporciona tales características para transacciones largas cuyos resultados no necesitan ser precisos. Por ejemplo, una información aproximada suele ser suficiente para las estadísticas utilizadas en la optimización de consultas. Si estas transacciones se ejecutaran en modo secuencial, podrían interferir con otras transacciones, provocando que la ejecución de las otras se retrasara. Los niveles de consistencia especificados por SQL-92son los siguientes: • Secuenciable. Es el predeterminado.

www.detodoprogramacion.com


16.9

Concurrencia en los índices∗∗

557

• Lectura repetible. Sólo permite leer registros comprometidos, y además requiere que, entre dos lecturas de un registro realizadas por una transacción, no se permita que ninguna otra transacción actualice el registro. Sin embargo, la transacción puede no ser secuenciable con respecto a otras transacciones. Por ejemplo, cuando está buscando registros que satisfagan algunas condiciones, una transacción podría encontrar algunos de los registros que ha insertado una transacción comprometida, pero podría no encontrar otros. • Compromiso de lectura. Sólo permite leer registros comprometidos, pero ni siquiera requiere lecturas repetibles. Por ejemplo, entre dos lecturas de un registro realizadas por una transacción, los registros deben ser actualizados por otras transacciones comprometidas. Esto es básicamente lo mismo que la consistencia de grado dos; la mayoría de los sistemas que soportan este nivel de consistencia debería implementar en realidad estabilidad del cursor, que es un caso especial de consistencia de grado dos. • Sin compromiso de lectura. Permite incluso leer registros no comprometidos. Éste es el nivel de consistencia más bajo que permite SQL-92. 16.9 Concurrencia en los índices

∗∗

Es posible tratar el acceso a los índice como el de otras estructuras de base de datos y aplicar las técnicas de control de concurrencia que se han descrito anteriormente. Sin embargo, puesto que se accede frecuentemente a los índices, se pueden convertir en un punto con mucho bloqueo, lo que produce un bajo grado de concurrencia. Por suerte, no es necesario tratar los índices como a las demás estructuras de base de datos. Es perfectamente aceptable que una transacción busque en un índice dos veces y se encuentre con que la estructura del índice ha cambiado entre ambas búsquedas, mientras la búsqueda devuelva el conjunto correcto de tuplas. De este modo se acepta tener un acceso no secuenciable a un índice mientras siga siendo correcto dicho índice. A continuación se mostrarán dos técnicas para tratar los accesos concurrentes a árboles B+ . En las notas bibliográficas se hace referencia a otras técnicas para árboles B+ , así como a técnicas para otras estructuras de índice. Las técnicas que se presentan para el control de concurrencia en los árboles B+ se basan en el bloqueo, pero no se emplean ni el bloqueo de dos fases ni el protocolo de árbol. Los algoritmos de búsqueda, inserción y borrado son los mismos que se usan en el Capítulo 12 con sólo algunas pequeñas modificaciones. La primera técnica se denomina protocolo del cangrejo: • Cuando se busca un valor clave, el protocolo del cangrejo bloquea primero el nodo raíz en modo compartido. Cuando se recorre el árbol hacia abajo, adquiere un bloqueo compartido sobre el siguiente nodo hijo. Después de adquirir el bloqueo sobre el nodo hijo, libera el bloqueo sobre el nodo padre. Repite este proceso hasta que alcanza un nodo hoja. • Cuando se inserta o se borra un valor clave, el protocolo del cangrejo realiza estas acciones: ¤ Sigue el mismo protocolo que para la búsqueda hasta que alcanza el nodo hoja deseado. Hasta este punto, tan sólo obtiene (y libera) bloqueos compartidos. ¤ Bloquea el nodo hoja en modo exclusivo e inserta o borra el valor clave. ¤ Si necesita dividir un nodo o fusionarlo con sus hermanos, o redistribuir los valores claves entre hermanos, el protocolo del cangrejo bloquea al padre del nodo en modo exclusivo. Después de realizar estas acciones, libera los bloqueos sobre el nodo y los hermanos. Si el padre requiere división, fusión o redistribución de valores clave, el protocolo mantiene el bloqueo sobre el padre, y la división, la fusión o la redistribución se sigue propagando de la misma manera. En otro caso, libera el bloqueo sobre el padre. El protocolo obtiene su nombre de la forma en que los cangrejos avanzan moviéndose de lado, moviendo las patas de un lado, después las patas del otro, y así alternando sucesivamente. El avance de los bloqueos mientras el protocolo baja por el árbol o sube de nuevo (en el caso de divisiones, fusiones o redistribuciones) actúa de forma similar a la del cangrejo.

www.detodoprogramacion.com


558

Capítulo 16

Control de concurrencia

Una vez que una operación particular libera un bloqueo sobre un nodo, otras operaciones pueden acceder a ese nodo. Existe una posibilidad de interbloqueos entre las operaciones de búsqueda que bajan por el árbol, y las divisiones, fusiones y redistribuciones que se propagan hacia arriba por el árbol. El sistema puede manejar con facilidad tales interbloqueos reiniciando la operación de búsqueda desde la raíz, después de liberar los bloqueos mantenidos por la operación. La segunda técnica consigue incluso más concurrencia, impidiendo incluso que se mantenga un bloqueo sobre un nodo mientras se está adquiriendo el bloqueo sobre otro nodo, utilizando una versión modificada de los árboles B+ llamados árboles B enlazados; los árboles B enlazados requieren que todo nodo (incluyendo los nodos internos, no sólo las hojas) mantenga un puntero a su hermano derecho. Se necesita este puntero porque una búsqueda que tenga lugar mientras se divide un nodo puede que tenga que buscar no sólo ese nodo sino también el hermano derecho de ese nodo (si existe alguno). Esta técnica se va a ilustrar con un ejemplo después de presentar los procedimientos modificados del protocolo de bloqueo con árboles B enlazados. • Búsqueda. Se debe bloquear en modo compartido cada nodo del árbol B+ antes de que se acceda a él. Dicho bloqueo se libera antes de que se solicite algún otro bloqueo sobre algún nodo del árbol B+ . Si tiene lugar una división de forma concurrente con una búsqueda, el valor de la clave de búsqueda deseado puede dejar de aparecer dentro del rango de valores que representa un nodo que se ha accedido en la búsqueda. En tal caso se representa el valor de la clave de búsqueda por medio de un nodo hermano, el cual coloca el sistema siguiendo el puntero al hermano derecho. Sin embargo, el sistema bloquea los nodos hoja siguiendo el protocolo de bloqueo de dos fases, como se describe en el Apartado 16.7.3, para evitar el fenómeno fantasma. • Inserción y borrado. El sistema sigue las reglas de la búsqueda para localizar el nodo sobre el cual se va a realizar la inserción o el borrado. Se modifica el bloqueo en modo compartido sobre ese nodo a modo exclusivo y se realiza la inserción o el borrado. Se bloquean los nodos hoja afectados por la inserción o el borrado siguiendo el protocolo de bloqueo de dos fases, como se describe en el Apartado 16.7.3, para evitar el fenómeno fantasma. • División. Si se divide un nodo se crea otro nuevo siguiendo el algoritmo del Apartado 12.3 y se convierte en el hermano derecho del nodo original. Se fijan los punteros al hermano derecho del nodo original y del nuevo nodo. Seguidamente se libera el bloqueo en modo exclusivo sobre el nodo original (dado que es un nodo interno, los nodos hoja están bloqueados en dos fases) y se solicita un bloqueo sobre el padre para que se pueda insertar un nuevo nodo (no es necesario bloquear o desbloquear el nuevo nodo). • Fusión. Si un nodo tiene muy pocos valores de clave de búsqueda después de un borrado, se debe bloquear en modo exclusivo el nodo con el que se debe fusionar. Una vez que se fusionen estos nodos se solicita un bloqueo en modo exclusivo sobre el padre para que se pueda eliminar el nodo borrado. En ese momento se libera el bloqueo sobre los nodos fusionados. Se libera el bloqueo sobre el nodo padre a no ser que también se tenga que fusionar. Es importante observar que: una inserción o un borrado pueden bloquear un nodo, desbloquearlo y posteriormente volverlo a bloquear. Además, una búsqueda que se ejecute concurrentemente con operaciones de división o de fusión puede observar que la clave de búsqueda deseada se ha trasladado al nodo hermano derecho debido a la división o a la fusión. Como ejemplo considérese el árbol B+ de la Figura 16.21. Supóngase que hay dos operaciones concurrentes sobre dicho árbol B+ : 1. Insertar “Cádiz”. 2. Buscar “Daimiel”. Considérese que la operación inserción comienza en primer lugar. Realiza una búsqueda de “Cádiz” y encuentra que el nodo en el cual se debe insertar “Cádiz” está vacío. Por tanto convierte el bloqueo compartido sobre el nodo en un bloqueo exclusivo y crea un nuevo nodo. El nodo original contiene

www.detodoprogramacion.com


16.9

Concurrencia en los índices∗∗

559

Pamplona

Madrid

Barcelona

Reus

Madrid

Daimiel

Figura 16.21

Pamplona

Reus

Ronda

Árbol B+ para el archivo cuenta con n = 3.

ahora los valores de clave de búsqueda “Barcelona” y “Cádiz”. El nuevo nodo contiene el valor de clave de búsqueda “Daimiel”. Supóngase ahora que se produce un cambio de contexto que le pasa el control a la operación búsqueda. Dicha operación búsqueda accede a la raíz y sigue el puntero al hijo izquierdo de la raíz. Accede entonces a ese nodo y obtiene el puntero al hijo izquierdo. El hijo izquierdo contenía originalmente los valores de clave de búsqueda “Barcelona” y “Daimiel”. Puesto que la operación inserción está bloqueando actualmente en modo exclusivo dicho nodo, la operación búsqueda debe esperar. Obsérvese que, en este punto, ¡la operación búsqueda no posee ningún bloqueo! Ahora la operación inserción desbloquea el nodo hoja y vuelve a bloquear a su padre en esta ocasión en modo exclusivo. Se completa la inserción, lo que deja al árbol B+ como se muestra en la Figura 16.22. Continúa la operación de búsqueda. Sin embargo tiene un puntero a un nodo hoja incorrecto. Sigue por tanto el puntero al hermano derecho para encontrar el nodo siguiente. Si este nodo es también incorrecto, se sigue también el puntero al hermano derecho. Se puede demostrar que, si una búsqueda tiene un puntero a un nodo incorrecto entonces, al seguir los punteros al hermano derecho, la búsqueda llega finalmente al nodo correcto. Las operaciones de búsqueda y de inserción no pueden llevar a un interbloqueo. La fusión de nodos durante el borrado puede provocar inconsistencias, dado que una búsqueda puede tener que leer un puntero a un nodo borrado desde su padre, antes de que el nodo padre sea actualizado y, entonces, puede intentar acceder al nodo borrado. La búsqueda se tendría que reiniciar entonces desde la raíz. Dejar los nodos sin fusionar evita tales inconsistencias. Esta solución genera nodos que contienen muy pocos valores clave de búsqueda y que violan algunas propiedades de los árboles B+ . Sin embargo, en la mayoría de las bases de datos las inserciones son más frecuentes que los borrados, por lo que es probable que los nodos que tienen muy pocos valores claves de búsqueda ganen valores adicionales de forma relativamente rápida. En lugar de bloquear nodos hoja índice en dos fases, algunos esquemas de control de concurrencia de índices utilizan bloqueo de valores clave sobre valores claves individuales, permitiendo que se inserten o se borren otros valores clave de la misma hoja. Por lo tanto, el bloqueo de valores clave proporciona una concurrencia mejorada. Sin embargo, utilizar el bloqueo de valores clave ingenuamente, podría permitir que se produjera el fenómeno fantasma; para prevenir el fenómeno fantasma se utiliza la técnica bloqueo de la siguiente clave. En esta técnica, cada búsqueda por índice debe bloquear no sólo las claves encontradas dentro del rango (o la única clave, en caso de una búsqueda concreta) sino también el siguiente valor clave — esto es, el valor clave que es justo mayor que el último valor clave que estaba

Pamplona

Daimiel

Barcelona

Cádiz

Figura 16.22

Daimiel

Madrid

Reus

Madrid

Pamplona

Reus

Ronda

Inserción de “Cádiz” en el árbol B+ de la Figura 16.21.

www.detodoprogramacion.com


560

Capítulo 16

Control de concurrencia

dentro del rango. Además, cada inserción no sólo debe bloquear el valor que se inserta, sino también el siguiente valor clave. Así, si una transacción intenta insertar un valor que estaba dentro del rango de la búsqueda por índice de otra transacción, las dos transacciones entrarán en conflicto en el valor clave que sigue al valor clave insertado. De forma similar, los borrados también deben bloquear el siguiente valor clave al valor que se ha borrado, para asegurar que se detecten los conflictos con las subsiguientes búsquedas de rango de otras consultas. 16.10 Resumen

• Cuando se ejecutan concurrentemente varias transacciones en la base de datos, puede dejar de conservarse la consistencia de los datos. Es necesario que el sistema controle la interacción entre las transacciones concurrentes, y dicho control se lleva a cabo mediante uno de los muchos mecanismos llamados esquemas de control de concurrencia. • Se pueden usar varios esquemas de control de concurrencia para asegurar la secuencialidad. Todos estos esquemas o bien retrasan una operación o bien abortan la transacción que ha realizado la operación. Los más comunes son los protocolos de bloqueo, los esquemas de ordenación por marcas temporales, las técnicas de validación y los esquemas multiversión. • Un protocolo de bloqueo es un conjunto de reglas, las cuales indican el momento en el que una transacción puede bloquear o desbloquear un elemento de datos de la base de datos. • El protocolo de bloqueo de dos fases permite que una transacción bloquee un nuevo elemento de datos sólo si todavía no ha desbloqueado ningún otro elemento de datos. Este protocolo asegura la secuencialidad pero no la ausencia de interbloqueos. A falta de información acerca de la forma en que se accede a los elementos de datos, el protocolo de bloqueo de dos fases es necesario y suficiente para asegurar la secuencialidad. • El protocolo de bloqueo estricto de dos fases permite liberar bloqueos exclusivos sólo al final de la transacción, para asegurar la recuperabilidad y la ausencia de cascadas en las planificaciones resultantes. El protocolo de bloqueo riguroso de dos fases libera todos los bloqueos sólo al final de la transacción. • Los protocolos de bloqueo basados en grafos imponen restricciones sobre el orden de acceso a los elementos, y pueden por tanto asegurar la secuencialidad sin requerir el bloqueo de dos fases, y pueden además asegurar la ausencia de interbloqueos. • El esquema de ordenación por marcas temporales asegura la secuencialidad seleccionando previamente un orden entre todo par de transacciones. Se asocia una única marca temporal fija a cada transacción del sistema. Las marcas temporales de las transacciones determinan el orden de secuencialidad. De este modo, si la marca temporal de la transacción Ti es más pequeña que la de la transacción Tj , entonces el esquema asegura que la planificación que ha producido es equivalente a una planificación secuencial en la cual la transacción Ti aparece antes de la transacción Tj . Lo asegura retrocediendo una transacción siempre que se viole dicho orden. • Un esquema de validación es un método de control de concurrencia adecuado en aquellos casos en los que la mayoría de las transacciones son de sólo lectura, y por tanto la tasa de conflictos entre dichas transacciones es baja. Se asocia una única marca temporal fija a cada transacción del sistema. Se determina el orden de secuencialidad por medio de la marca temporal. Nunca se retrasa una transacción en dicho esquema. Debe pasar, sin embargo, una comprobación de validación para poder completarse. Si no pasa la comprobación de validación retrocede a su estado inicial. • Hay circunstancias bajo las cuales puede ser conveniente agrupar varios elementos de datos y tratarlos como un conjunto de elementos de datos por motivos del trabajo, lo que da lugar a varios niveles de granularidad. Se permiten elementos de datos de varios tamaños y se define una jerarquía de elementos de datos en la cual los elementos más pequeños están anidados dentro de otros más grandes. Dicha jerarquía se puede representar de forma gráfica como un árbol. El orden de obtención de los bloqueos es desde la raíz hasta la hojas; se liberan desde las hojas hasta la raíz. Este protocolo asegura la secuencialidad pero no la ausencia de interbloqueos.

www.detodoprogramacion.com


Términos de repaso

561

• Un esquema de control de concurrencia multiversión se basa en crear una nueva versión de un elemento de datos cada vez que una transacción va a escribir dicho elemento. Cuando se realiza una operación de lectura, el sistema elige una de las versiones para que se lea. El esquema de control de concurrencia asegura que la versión que se va a leer se elige de forma que asegure la secuencialidad usando las marcas temporales. Una operación de lectura tiene éxito siempre. ¤ En la ordenación por marcas temporales multiversión, una operación de escritura puede provocar el retroceso de una transacción. ¤ En el bloqueo de dos fases multiversión las operaciones de escritura pueden provocar una espera con bloqueo o posiblemente un interbloqueo. • Algunos de los protocolos de bloqueo no evitan los interbloqueos. Una forma de prevenir los interbloqueos es utilizar una ordenación de los elementos de datos, y solicitar los bloqueos en una secuencia consistente con la ordenación. • Otra forma de prevenir los interbloqueos es utilizar expropiación y retroceso de transacciones. Para controlar la expropiación se asigna una única marca temporal a cada transacción. El sistema utiliza estas marcas temporales para decidir si una transacción debe esperar o retroceder. Si una transacción retrocede conserva su marca temporal anterior cuando vuelve a comenzar. El esquema herir–esperar es un esquema de expropiación. • Si no se pueden prevenir los interbloqueos, el sistema debe ocuparse de ellos utilizando el esquema de detección y recuperación de interbloqueos. Para hacer esto, el sistema construye un grafo de espera. Un sistema está en estado de interbloqueo si y sólo si contiene un ciclo en el grafo de espera. Cuando el algoritmo de detección de interbloqueos determina que existe un interbloqueo, el sistema debe recuperarse del interbloqueo. Esto se lleva a cabo retrocediendo una o más transacciones para romper el interbloqueo. • Se puede realizar una operación borrar sólo si la transacción que borra la tupla tiene un bloqueo en modo exclusivo sobre dicha tupla. A la transacción que inserta una nueva tupla se le concede un bloqueo en modo exclusivo sobre dicha tupla. • Las inserciones pueden provocar el fenómeno fantasma, en el cual hay un conflicto entre una inserción y una pregunta incluso si las dos transacciones no acceden a tuplas comunes. Tales conflictos no se pueden detectar si el bloqueo se ha hecho sólo sobre tuplas a las que han accedido transacciones. Es necesario bloquear los datos utilizados para encontrar las tuplas en la relación. La técnica del bloqueo del índice resuelve este problema al exigir bloqueos sobre ciertos cajones de índices. Estos bloqueos aseguran que todas las transacciones conflictivas están en conflicto por un elemento de datos real en lugar de por uno fantasma. • Los niveles débiles de consistencia se utilizan en algunas aplicaciones cuando la consistencia de los resultados de la consulta no es crítica y, utilizar secuencialidad podría dar lugar a consultas que afectaran desfavorablemente al procesamiento de transacciones. La consistencia de grado dos es uno de los niveles de consistencia débiles; la estabilidad de cursor es un caso especial de consistencia de grado dos y se utiliza bastante. SQL:1999 permite a las consultas especificar el nivel de consistencia requerido. • Se pueden desarrollar técnicas de control de concurrencia para estructuras especiales. A menudo se aplican técnicas especiales en los árboles B+ para permitir una mayor concurrencia. Estas técnicas permiten accesos no secuenciables al árbol B+ , pero aseguran que la estructura del árbol B+ es correcta y que los accesos a la base de datos son secuenciables. Términos de repaso

• Control de concurrencia.

¤ ¤ ¤ ¤

• Tipos de bloqueo: ¤ Bloqueo en modo compartido (C). ¤ Bloqueo en modo exclusivo (X). • Bloqueo

Compatibilidad. Solicitud. Espera. Concesión.

• Interbloqueo.

www.detodoprogramacion.com


562

Capítulo 16

Control de concurrencia

• Inanición. • Protocolo de bloqueo. • Planificación legal. • Protocolo de bloqueo de dos fases. ¤ ¤ ¤ ¤ ¤

Fase de crecimiento. Fase de decrecimiento. Punto de bloqueo. Bloqueo estricto de dos fases. Bloqueo riguroso de dos fases.

• Conversión de bloqueos.

• Protocolo de bloqueo de granularidad múltiple. • Control de concurrencia multiversión. • Versiones. • Ordenación por marcas temporales multiversión. • Bloqueo de dos fases multiversión. ¤ Transacciones de sólo lectura. ¤ Transacciones de actualización. • Tratamiento de interbloqueos.

¤ Subir. ¤ Bajar. • Protocolos basados en grafos. ¤ Protocolo de árbol. ¤ Dependencia de compromiso.

• Protocolos basados en marcas temporales. • Marca temporal. ¤ ¤ ¤ ¤

Reloj del sistema. Contador lógico. marca-temporal-E(Q). marca-temporal-L(Q).

• •

• Protocolo de ordenación por marcas temporales. ¤ Regla de escritura de Thomas. • Protocolos basados en validación. ¤ ¤ ¤ ¤

Fase de lectura. Fase de validación. Fase de escritura. Comprobación de validación.

• • •

• Granularidad múltiple. ¤ Bloqueos explícitos. ¤ Bloqueos implícitos. ¤ Bloqueos intencionales. • Modos de bloqueo intencionales: ¤ Intencional-compartido (IC). ¤ Intencional-exclusivo (IX). ¤ Intencional-exclusivo y compartido (IXC).

¤ Prevención. ¤ Detección. ¤ Recuperación. Prevención de interbloqueos. ¤ Bloqueos ordenados. ¤ Expropiación de bloqueos. ¤ Esquema esperar–morir. ¤ Esquema herir–esperar. ¤ Esquemas basados en tiempo límite. Detección de interbloqueos. ¤ Grafo de espera. Recuperación de interbloqueos. ¤ Retroceso total. ¤ Retroceso parcial. Operaciones para insertar y borrar. Fenómeno fantasma. ¤ Protocolo de bloqueo del índice. Niveles débiles de consistencia: ¤ Consistencia de grado dos. ¤ Estabilidad del cursor. ¤ Lectura repetible. ¤ Compromiso de lectura. ¤ Sin compromiso de lectura.

• Concurrencia en índices. ¤ Cangrejo. ¤ Árboles B enlazados. ¤ Protocolo de bloqueo con árboles B enlazados. ¤ Bloqueo de la siguiente clave.

Ejercicios prácticos

16.1 Demuéstrese que el protocolo de bloqueo de dos fases asegura la secuencialidad en cuanto a conflictos y que se pueden secuenciar las transacciones a través de sus puntos de bloqueo. 16.2 Considérense las dos transacciones siguientes:

www.detodoprogramacion.com


Ejercicios prácticos

563

T31 : leer(A); leer(B); si A = 0 entonces B := B + 1; escribir(B). T32 : leer(B); leer(A); si B = 0 entonces A := A + 1; escribir(A). Añádanse a las transacciones T31 y T32 las instrucciones de bloqueo y desbloqueo para que sigan el protocolo de dos fases. ¿Puede producir la ejecución de estas transacciones un interbloqueo? 16.3 ¿Qué beneficio proporciona el bloqueo riguroso de dos fases? Compárese con otras formas de bloqueo de dos fases. 16.4 Considérese una base de datos organizada como un árbol con raíz. Supóngase que se inserta un nodo ficticio entre cada par de nodos. Demuéstrese que, si se sigue el protocolo de árbol con este nuevo árbol, se obtiene mayor concurrencia que con el árbol original. 16.5 Demuéstrese con un ejemplo que hay planificaciones que son posibles con el protocolo de árbol que no lo son con otros protocolos de bloqueo de dos fases y viceversa. 16.6 Considérese la siguiente extensión del protocolo de bloqueo de árbol que permite bloqueos compartidos y exclusivos: • Una transacción puede ser de sólo lectura, en cuyo caso sólo puede solicitar bloqueos compartidos, o bien puede ser de actualización, en cuyo caso sólo puede solicitar bloqueos exclusivos. • Cada transacción debe seguir las reglas del protocolo de árbol. Las transacciones de sólo lectura deben bloquear primero cualquier elemento de datos, mientras que las transacciones de actualización deben bloquear primero la raíz. Demuéstrese que este protocolo asegura la secuencialidad y la ausencia de interbloqueos. 16.7 Considérese el siguiente protocolo de bloqueo basado en grafo, el cual sólo permite bloqueos exclusivos y que funciona con grafos de datos con forma de grafo dirigido acíclico con raíz. • Una transacción puede bloquear en primer lugar cualquier nodo. • Para bloquear cualquier otro nodo, la transacción debe poseer un bloqueo sobre la mayoría de los padres de dicho nodo. Demuéstrese que este protocolo asegura la secuencialidad y la ausencia de interbloqueos. 16.8 Considérese el siguiente protocolo de bloqueo basado en grafos que sólo permite bloqueos exclusivos y que funciona con grafos de datos con forma de grafo dirigido acíclico con raíz. • Una transacción puede bloquear en primer lugar cualquier nodo. • Para bloquear cualquier otro nodo, la transacción debe haber visitado a todos los padres de dicho nodo y debe poseer un bloqueo sobre uno de los padres del vértice. Demuéstrese que este protocolo asegura la secuencialidad y la ausencia de interbloqueos. 16.9 El bloqueo no se hace explícitamente en lenguajes de programación persistentes. En vez de esto se deben bloquear los objetos (o sus páginas correspondientes) cuando se accede a dichos objetos. Muchos de los sistemas operativos más modernos permiten al usuario definir protecciones de acceso (sin acceso, lectura, escritura) para las páginas, y aquellos accesos a memoria que violen las protecciones de acceso dan como resultado una violación de protección (véase la orden mprotect de Unix, por ejemplo). Descríbase la forma en que se puede usar el mecanismo de protección de acceso para bloqueos a nivel de página en lenguajes de programación persistentes. 16.10 Considérese una base de datos que tiene la operación atómica incrementar además de las operaciones leer y escribir. Sea V el valor del elemento de datos X.

www.detodoprogramacion.com


564

Capítulo 16

Control de concurrencia

C X I Figura 16.23

C cierto falso falso

X falso falso falso

I falso falso cierto

Matriz de compatibilidad de bloqueos.

La operación incrementar(X) en C asigna el valor V + C a X en un paso atómico. El valor de X no está disponible hasta que no se ejecute posteriormente una operación leer(X). En la Figura 16.23 se muestra una matriz de compatibilidad de bloqueos para tres tipos de bloqueo: modo compartido, exclusivo y de incremento. a. Demuéstrese que, si todas las transacciones bloquean el dato al que acceden en el modo correspondiente, entonces el bloqueo de dos fases asegura la secuencialidad. b. Demuéstrese que la inclusión del bloqueo en modo incrementar permite una mayor concurrencia. Sugerencia: considérense las transacciones de transferencia de fondos del ejemplo bancario. 16.11 En la ordenación por marcas temporales, marca-temporal-E(Q) indica la mayor marca temporal de todas las transacciones que hayan ejecutado escribir(Q) con éxito. Supóngase que en lugar de ello, marca-temporal-E(Q) se define como la marca temporal de la transacción más reciente que haya ejecutado escribir(Q) con éxito. ¿Hay alguna diferencia al cambiar esta definición? Razónese la respuesta. 16.12 La utilización de un bloqueo de granularidad múltiple puede necesitar más o menos bloqueos que en un sistema equivalente con una granularidad simple de bloqueo. Proporciónense ejemplos de ambas situaciones y compárese el aumento relativo de la concurrencia que se permite. 16.13 Considérese el esquema de control de concurrencia basado en la validación del Apartado 16.3. Demuéstrese que si se elige Validación(Ti ) en lugar de Inicio(Ti ) como marca temporal de la transacción Ti , se puede esperar una mejor respuesta en tiempo debido a que la tasa de conflictos entre las transacciones es realmente baja. 16.14 Para cada uno de los protocolos siguientes, descríbanse los aspectos de aplicación práctica que sugieran utilizar el protocolo y aspectos que sugieran no usarlo: • • • • • • •

Bloqueo de dos fases. Bloqueo de dos fases con granularidad múltiple. Protocolo de árbol. Ordenación por marcas temporales. Validación. Ordenación por marcas temporales multiversión. Bloqueo de dos fases multiversión.

16.15 Explíquese por qué la siguiente técnica de ejecución de transacciones puede proporcionar mayor rendimiento que la utilización del bloqueo estricto de dos fases: primero se ejecuta la transacción sin adquirir ningún bloqueo y sin realizar ninguna escritura en la base de datos como en las técnicas basadas en validación, pero a diferencia de las técnicas de validación no se realiza otra validación o escritura en la base de datos. En cambio, se vuelve a ejecutar la transacción utilizando bloqueo estricto de dos fases. Sugerencia: considérense esperas para la E/S de disco. 16.16 Considérese el protocolo de ordenación por marcas temporales, y dos transacciones, una que escribe dos elementos de datos p y q, y otra que lee los mismos dos elementos de datos. Obténgase una planificación por medio de la cual la comprobación por marcas temporales para una operación escribir falle y provoque el reinicio de la primera transacción, provocando a su vez una cancelación en cascada de la otra transacción. Muéstrese cómo esto podría acabar en inanición

www.detodoprogramacion.com


Ejercicios

565

de las dos transacciones. (Tal situación, donde dos o más procesos realizan acciones, pero no se puede completar la tarea porque se interacciona con otros procesos, se denomina interbloqueo). 16.17 Diséñese un protocolo basado en marcas temporales que evite el fenómeno fantasma. 16.18 Supóngase que se utiliza el protocolo de árbol del Apartado 16.1.5 para administrar el acceso concurrente a un árbol B+ . Puesto que puede haber una división en una inserción que afecte a la raíz, se deduce que una operación inserción no puede liberar ningún bloqueo hasta que no se complete la operación entera. ¿Bajo qué circunstancias es posible liberar antes un bloqueo?

Ejercicios

16.19 ¿Qué beneficio proporciona el bloqueo estricto de dos fases? ¿Qué inconvenientes tiene? 16.20 Muchas implementaciones de sistemas de bases de datos utilizan el bloqueo estricto de dos fases. Indíquense tres razones que expliquen la popularidad de este protocolo. 16.21 Considérese una variante del protocolo de árbol llamada protocolo de bosque. La base de datos está organizada como un bosque de árboles con raíz. Cada transacción Ti debe seguir las reglas siguientes: • El primer bloqueo en un árbol puede hacerse sobre cualquier elemento de datos. • Se pueden solicitar el segundo y posteriores bloqueos sólo si el padre del nodo solicitado está bloqueado actualmente. • Se pueden desbloquear los elementos de datos en cualquier momento. • Ti no puede volver a bloquear un elemento de datos después de haberlo desbloqueado. Demuéstrese que el protocolo de bosque no asegura la secuencialidad. 16.22 Cuando una transacción retrocede en el protocolo de ordenación por marcas temporales se le asigna una nueva marca temporal. ¿Por qué no puede conservar simplemente su antigua marca temporal? 16.23 En el protocolo de granularidad múltiple, ¿qué diferencia hay entre bloqueo implícito y explícito? 16.24 Aunque el modo IXC es útil para el bloqueo de granularidad múltiple, no se usa un modo exclusivo e intencional-compartido (ICX). ¿Por qué no es útil? 16.25 Demuéstrese que hay planificaciones que son posibles con el protocolo de bloqueo de dos fases que no lo son con el protocolo de marcas temporales y viceversa. 16.26 En una versión modificada del protocolo de marcas temporales se necesita comprobar un bit de compromiso para saber si una petición de lectura debe esperar o no. Explíquese cómo puede evitar el bit de compromiso que aborten en cascada. ¿Por qué no se necesita hacer esta comprobación con las peticiones de escritura? 16.27 ¿Bajo qué condiciones es menos costoso evitar los interbloqueos que permitirlos y luego detectarlos? 16.28 Si se evitan los interbloqueos, ¿sigue siendo posible que haya inanición? Razónese la respuesta. 16.29 Explíquese el fenómeno fantasma. ¿Por qué produce este fenómeno una ejecución concurrente incorrecta a pesar de utilizar el protocolo de bloqueo de dos fases? 16.30 Explíquese la razón por la cual se utiliza la consistencia de grado dos. ¿Qué inconvenientes tiene esta técnica? 16.31 Dense ejemplos de planificaciones para mostrar que si, con el bloqueo de valores clave, cualquier búsqueda, inserción o borrado no bloquea el siguiente valor clave, el fenómeno fantasma podría ser indetectable.

www.detodoprogramacion.com


566

Capítulo 16

Control de concurrencia

16.32 Si varias transacciones modifican un elemento común (por ejemplo, el saldo de una sucursal) y elementos privados (por ejemplo, saldos de cuentas en concreto), explíquese cómo se puede aumentar el grado de concurrencia (y, por tanto, de la productividad) ordenando las operaciones de la transacción. 16.33 Considérese el siguiente protocolo de bloqueo: todos los elementos se numeran y, cada vez que un elemento se desbloquea, sólo se pueden bloquear elementos con un número mayor. Los bloqueos se pueden liberar en cualquier momento. Sólo se usan bloqueos X. Muéstrese mediante un ejemplo que este bloqueo no garantiza la secuencialidad. Notas bibliográ cas

Gray y Reuter [1993] proporcionan un libro de texto detallado que cubre conceptos de procesamiento de transacciones, incluyendo conceptos de control de concurrencia y detalles de implementación. Bernstein y Newcomer [1997] proporcionan un libro de texto que trata varios aspectos del procesamiento de transacciones incluyendo el control de concurrencia. Entre los primeros libros de texto que incluyen estudios sobre el control de concurrencia y la recuperación se incluyen los de Papadimitriou [1986] y Bernstein et al. [1987]. Gray [1978] presenta uno de los primeros estudios sobre aspectos de la implementación del control de concurrencia y la recuperación. Eswaran et al. [1976] introdujo el protocolo de bloqueo de dos fases. El protocolo de bloqueo de árbol es de Silberschatz y Kedem [1980]. Yannakakis et al. [1979], Kedem y Silberschatz [1983] y Buckley y Silberschatz [1985] desarrollaron otros protocolos de bloqueo que no son de dos fases y que operan con grafos más generales. Korth [1983] explora varios modos de bloqueo que se pueden obtener a partir de los modos básicos, compartido y exclusivo. El Ejercicio práctico 16.4 es de Buckley y Silberschatz [1984]. El Ejercicio 16.8 es de Kedem y Silberschatz [1983]. El Ejercicio 16.7 es de Kedem y Silberschatz [1979]. El Ejercicio práctico 16.8 es de Yannakakis et al. [1979]]. El Ejercicio práctico 16.10 es de Korth [1983]. El esquema de control de concurrencia basado en marcas temporales es de Reed [1983]. Bernstein y Goodman [1980] presentan una exposición de varios algoritmos de control de concurrencia basados en marcas temporales. Buckley y Silberschatz [1983] presentan un algoritmo de marcas temporales que no necesita retroceso para asegurar la secuencialidad. El esquema de control de concurrencia basado en validación es de Kung y Robinson [1981]. El protocolo de bloqueo para elementos de datos de granularidad múltiple es de Gray et al. [1975]. Gray et al. [1976] presentan una descripción detallada. Korth [1983] formaliza el bloqueo con granularidad múltiple para una colección arbitraria de modos de bloqueo (que permite más funcionalidades además de simplemente leer y escribir). Esta aproximación incluye una clase de modos de bloqueo llamados modos de actualización para permitir conversión de bloqueos. Carey [1983] extiende la idea de granularidad múltiple a la de control de concurrencia basado en marcas temporales. Korth [1982] presenta una extensión del protocolo que asegura la ausencia de interbloqueos. Bernstein et al. [1983] ofrecen estudios acerca del control de concurrencia multiversión. En Silberschatz [1982] aparece un algoritmo de bloqueo de árbol multiversión. Reed [1978] y Reed [1983] introdujeron la ordenación por marcas temporales multiversión. Lai y Wilkinson [1984] describen un certificador de bloqueo de dos fases multiversión. En Gray et al. [1975] se introduce la consistencia de grado dos. Los niveles de consistencia—o aislamiento— que ofrece SQL se explican y comentan en Berenson et al. [1995]. Muchos sistemas comerciales de bases de datos usan enfoques basados en versiones en combinación con el bloqueo. Oracle usa una forma de aislamiento basada en instantáneas basada en el protocolo descrito en el Apartado 16.5.2. Los detalles se encuentran en el Capítulo 27 y en Fekete et al. [2005]. El enfoque multiversión de PostgreSQL se trata en el Capítulo 26 y el de SQL Server (instantáneas) en el 29. Bayer y Schkolnick [1977] y Johnson y Shasha [1993] estudiaron la concurrencia en árboles B+ . La técnica que se ha presentado en el Apartado 16.9 está basada en Kung y Lehman [1980], y en Lehman y Yao [1981]. En Mohan [1990a] y Mohan y Levine [1992] se describe la técnica del bloqueo del valor clave utilizada en ARIES que proporciona una gran concurrencia en el acceso a los árboles B+ . Ellis [1987] presenta una técnica de control de concurrencia para asociación lineal.

www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

17

Sistema de recuperación

Las computadoras, al igual que cualquier otro dispositivo eléctrico o mecánico, están sujetas a fallos. Éstos se producen por diferentes motivos como: fallos de disco, cortes de corriente, errores en el software, un incendio en la habitación de la computadora o incluso sabotaje. En cada uno de estos casos puede perderse información. Por tanto, el sistema de bases de datos debe realizar con anticipación acciones que garanticen que las propiedades de atomicidad y durabilidad de las transacciones, presentadas en el Capítulo 15, se preservan a pesar de tales fallos. Una parte integral de un sistema de bases de datos es un esquema de recuperación, el cual es responsable de la restauración de la base de datos al estado consistente previo al fallo. El esquema de recuperación también debe proporcionar alta disponibilidad; esto es, debe minimizar el tiempo durante el que la base de datos no se puede usar después de un fallo. 17.1 Clasi cación de los fallos

En un sistema pueden producirse varios tipos de fallos, cada uno de los cuales requiere un tratamiento diferente. El tipo de fallo más fácil de tratar es el que no conduce a una pérdida de información en el sistema. Los fallos más difíciles de tratar son aquellos que provocan una pérdida de información. En este capítulo consideraremos sólo los siguientes tipos de fallos: • Fallo en la transacción. Hay dos tipos de errores que pueden hacer que una transacción falle: ¤ Error lógico. La transacción no puede continuar con su ejecución normal a causa de alguna condición interna, como una entrada incorrecta, datos no encontrados, desbordamiento o exceso del límite de recursos. ¤ Error del sistema. El sistema se encuentra en un estado no deseado (por ejemplo, de interbloqueo) como consecuencia del cual una transacción no puede continuar con su ejecución normal. La transacción, sin embargo, se puede volver a ejecutar más tarde. • Caída del sistema. Un mal funcionamiento del hardware o un error en el software de la base de datos o del sistema operativo causa la pérdida del contenido de la memoria volátil y aborta el procesamiento de una transacción. El contenido de la memoria no volátil permanece intacto y no se corrompe. La suposición de que los errores de hardware o software fuercen una parada del sistema, pero no corrompan el contenido de la memoria no volátil, se conoce como supuesto de fallo-parada. Los sistemas bien diseñados tienen numerosas comprobaciones internas, al nivel de hardware y de software, que abortan el sistema cuando existe un error. De aquí que el supuesto de falloparada sea razonable. • Fallo de disco. Un bloque del disco pierde su contenido como resultado de una colisión de la cabeza lectora, o de un fallo durante una operación de transferencia de datos. Las copias de los 567

www.detodoprogramacion.com


568

Capítulo 17

Sistema de recuperación

datos que se encuentran en otros discos o en archivos de seguridad en medios de almacenamiento secundarios, como cintas, se utilizan para recuperarse del fallo. Para determinar el medio por el que el sistema debe recuperarse de los fallos, es necesario identificar los modos de fallo de los dispositivos de almacenamiento. A continuación se verá cómo afectan estos modos de fallo al contenido de la base de datos. Por tanto, se pueden proponer algoritmos para garantizar la consistencia de la base de datos y la atomicidad de las transacciones a pesar de los fallos. Estos algoritmos, conocidos como algoritmos de recuperación, constan de dos partes: 1. Acciones llevadas a cabo durante el procesamiento normal de transacciones para asegurar que existe información suficiente para permitir la recuperación frente a fallos. 2. Acciones llevadas a cabo después de ocurrir un fallo para restablecer el contenido de la base de datos a un estado que asegure la consistencia de la base de datos, la atomicidad de la transacción y la durabilidad. 17.2 Estructura del almacenamiento

Como vimos en el Capítulo 10, los diferentes elementos que componen una base de datos pueden ser almacenados y se puede acceder a ellos en diferentes medios de almacenamiento. Para entender cómo se pueden garantizar las propiedades de atomicidad y durabilidad de una transacción, se deben comprender mejor estos medios de almacenamiento y sus métodos de acceso. 17.2.1 Tipos de almacenamiento

En el Capítulo 11 se vio que los medios de almacenamiento se pueden distinguir según su velocidad relativa, capacidad y resistencia a fallos, y se pueden clasificar como almacenamiento volátil o no volátil. Se repasarán estos términos y se introducirá otra clase de almacenamiento, denominada almacenamiento estable. • Almacenamiento volátil. La información que reside en almacenamiento volátil no suele sobrevivir a las caídas del sistema. La memoria principal y la memoria caché son ejemplos de este almacenamiento. El acceso al almacenamiento volátil es muy rápido, tanto por la propia velocidad de acceso a la memoria, como porque es posible acceder directamente a cualquier elemento de datos. • Almacenamiento no volátil. La información que reside en almacenamiento no volátil sobrevive a las caídas del sistema. Los discos y las cintas magnéticas son ejemplos de este almacenamiento. Los discos se utilizan para almacenamiento en conexión, mientras que las cintas se usan para almacenamiento permanente. Ambos, sin embargo, pueden fallar (por ejemplo, colisión de la cabeza lectora) lo que puede conducir a una pérdida de información. En el estado actual de la tecnología, el almacenamiento no volátil es más lento en varios órdenes de magnitud que el almacenamiento volátil. Esta diferencia de velocidad es consecuencia de que los dispositivos de disco y de cinta sean electromecánicos, mientras que el almacenamiento volátil se basa por completo en circuitos integrados, como el almacenamiento volátil. En los sistemas de bases de datos los discos se utilizan fundamentalmente para el almacenamiento no volátil. Otros medios de almacenamiento no volátil sólo se usan normalmente para copias de seguridad de los datos. El almacenamiento flash (véase el Apartado 11.1), aunque no volátil, tiene capacidad insuficiente para la mayoría de los sistemas de bases de datos. • Almacenamiento estable. La información que reside en almacenamiento estable nunca se pierde (bueno, nunca digas nunca jamás porque, teóricamente el nunca no puede garantizarse—por ejemplo, es posible, aunque extremadamente improbable, que un agujero negro se trague la tierra y destruya para siempre todos los datos). A pesar de que el almacenamiento estable es teóricamente imposible de conseguir, puede obtenerse una buena aproximación usando técnicas que hagan que la pérdida de información sea una posibilidad muy remota. La implementación del almacenamiento estable se estudia en el Apartado 17.2.2.

www.detodoprogramacion.com


17.2

Estructura del almacenamiento

569

Las diferencias entre los distintos tipos de almacenamiento son, con frecuencia, menos claras en la práctica que en la presentación anterior. Ciertos sistemas están provistos de una fuente de alimentación de seguridad, por lo que determinada memoria principal puede sobrevivir a las caídas del sistema y a cortes de corriente. Otras formas alternativas de almacenamiento no volátil, como los medios ópticos, ofrecen un grado de confianza incluso más alto que el de los discos. 17.2.2 Implementación del almacenamiento estable

Para implementar almacenamiento estable se debe replicar la información necesaria en varios medios de almacenamiento no volátil (normalmente discos) con modos de fallo independientes, y actualizar esa información de manera controlada para asegurar que un fallo durante una transferencia de datos no dañará la información necesaria. Recuérdese (del Capítulo 10) que los sistemas RAID (disposición redundante de discos independientes) garantizan que el fallo de un solo disco (incluso durante una transferencia de datos) no conduce a la pérdida de los datos. La variante más sencilla y rápida de RAID es el disco con imagen, que guarda dos copias de cada bloque en distintos discos. Otras formas de RAID ofrecen menores costes a expensas de un rendimiento inferior. Los sistemas RAID, sin embargo, no pueden proteger contra las pérdidas de datos debidas a desastres tales como un incendio o una inundación. Muchos sistemas de almacenamiento guardan copias de seguridad de las cintas en otro lugar como protección frente a tales desastres. No obstante, como las cintas no pueden ser trasladadas a otro lugar continuamente, los cambios que se hayan realizado después del último traslado de las cintas se perderán en caso de un desastre tal. Los sistemas más seguros guardan una copia de cada bloque de almacenamiento estable en un lugar remoto, escribiéndola a través de una red de computadoras, además de almacenar el bloque en un sistema de discos locales. Como los bloques se envían al sistema remoto al mismo tiempo y de la misma forma que se guardan en almacenamiento local, una vez que una operación de este tipo se completa los bloques copiados no pueden perderse, incluso en el caso de que ocurriese un desastre como un incendio o una inundación. En el Apartado 17.8 se estudian estos sistemas de copia de seguridad remota. En el resto de este apartado se estudia la manera de proteger los medios de almacenamiento de los errores durante una transferencia de datos. Las transferencias de bloques entre la memoria y el disco pueden acabar de diferentes formas: • Éxito. La información transferida llega a su destino con seguridad. • Fallo parcial. Ocurre un fallo en medio de la transferencia y el bloque de destino contiene información incorrecta. • Fallo total. El fallo ocurre tan al principio de la transferencia que el bloque de destino permanece intacto. Es necesario que, si se produce un fallo durante una transferencia de datos, el sistema lo detecte e invoque a un procedimiento de recuperación para restaurar el bloque a un estado estable. Para hacer esto, el sistema debe mantener dos bloques físicos por cada bloque lógico de la base de datos; en el caso de los discos con imagen, ambos bloques están en el mismo lugar; en el caso de copia de seguridad remota, uno de los bloques es local mientras que el otro está en un lugar remoto. Una operación de salida se ejecuta de la siguiente manera: 1. Se escribe la información en el primer bloque físico. 2. Cuando la primera escritura se completa con éxito, se escribe la misma información en el segundo bloque físico. 3. La salida está completada sólo después de que la segunda escritura finalice con éxito. Durante la recuperación se examina cada par de bloques físicos. Si ambos coinciden y no existe ningún error detectable, entonces no son necesarias más acciones (recuérdese que los errores de los bloques del disco, como puede ser una escritura parcial del bloque, se detectan mediante el almacenamiento de

www.detodoprogramacion.com


570

CapĂ­tulo 17

Sistema de recuperaciĂłn

Figura 17.1

Operaciones de almacenamiento de bloques.

una suma de control en cada bloque). Si un bloque contiene un error detectable, se reemplaza su contenido por el del segundo bloque. Si ninguno de los dos bloques contiene errores detectables, pero su contenido es diferente, el sistema sustituye el contenido del primer bloque por el valor del segundo. Este procedimiento de recuperaciĂłn garantiza que la escritura en almacenamiento estable o bien se completa con ĂŠxito (esto es, se actualizan todas las copias) o bien no produce ningĂşn cambio. El requisito de comparar cada par correspondiente de bloques durante la recuperaciĂłn es bastante costoso. Puede reducirse considerablemente ese coste si se registran las escrituras de bloques que estĂĄn en progreso utilizando una pequeĂąa cantidad de RAM no volĂĄtil. En la recuperaciĂłn solamente es necesario comparar aquellos bloques en los que se estuviera escribiendo. Los protocolos para escribir un bloque en un lugar remoto son similares a los utilizados para escribir bloques en un sistema de disco con imagen, que fueron examinados en el CapĂ­tulo 11 y, en particular, en el Ejercicio prĂĄctico 11.2. Este procedimiento puede extenderse fĂĄcilmente para permitir el uso de un nĂşmero arbitrariamente alto de copias de cada bloque de almacenamiento estable. Aunque un elevado nĂşmero de copias reduce la probabilidad de fallo incluso por debajo de la conseguida con dos copias, habitualmente es razonable la simulaciĂłn de almacenamiento estable con sĂłlo dos copias. 17.2.3 Acceso a los datos

Como se vio en el CapĂ­tulo 11, el sistema de bases de datos reside permanentemente en almacenamiento no volĂĄtil (normalmente discos) y se divide en unidades de almacenamiento de longitud fija denominadas bloques. Los bloques son las unidades de datos que se transfieren desde y hacia el disco y pueden contener varios elementos de datos. Supondremos que ningĂşn elemento de datos mide dos o mĂĄs bloques. Esta suposiciĂłn es realista para la mayorĂ­a de las aplicaciones de procesamiento de datos tales como el ejemplo bancario. Las transacciones llevan informaciĂłn del disco hacia la memoria principal y luego devuelven la informaciĂłn al disco. Las operaciones de entrada y salida se realizan en unidades de bloque. Nos referiremos a los bloques que residen en el disco como bloques fĂ­sicos, y a los que residen temporalmente en la memoria principal como bloques de memoria intermedia. El ĂĄrea de memoria en donde los bloques residen temporalmente se denomina memoria intermedia de disco. Las transferencias de un bloque entre disco y memoria principal se comienzan a travĂŠs de las dos operaciones siguientes: 1. entrada(B) transfiere el bloque fĂ­sico B a la memoria principal. 2. salida(B) transfiere el bloque de memoria intermedia B al disco y reemplaza allĂ­ al correspondiente bloque fĂ­sico. Este esquema se ilustra en la Figura 17.1.

www.detodoprogramacion.com


17.3

Recuperación y atomicidad

571

Cada transacción Ti posee un área de trabajo privada en la cual se guardan copias de todos los elementos de datos a los que ha accedido y actualizado. Este área de trabajo se crea cuando se comienza una transacción y se elimina cuando la transacción o bien se compromete o bien aborta. Cada elemento de datos X almacenado en el área de trabajo de la transacción Ti se denotará como xi . La transacción Ti interactúa con el sistema de bases de datos por medio de transferencias de datos desde su área de trabajo hacia la memoria intermedia del sistema y viceversa. Nosotros realizaremos transferencias de datos utilizando las dos operaciones siguientes: 1. leer(X) asigna el valor del elemento de datos X a la variable local xi . Esta operación se ejecuta como sigue: a. Si el bloque BX en el que reside X no está en la memoria principal, entonces se ejecuta entrada(BX ). b. Asigna a xi el valor de X en el bloque de memoria intermedia. 2. escribir(X) asigna el valor de la variable local xi al elemento de datos X en el bloque de memoria intermedia. Esta operación se ejecuta como sigue: a. Si el bloque BX en el que reside X no está en la memoria principal, entonces se ejecuta entrada(BX ). b. Asigna el valor de xi a X en la memoria intermedia BX . Obsérvese que ambas operaciones pueden requerir la transferencia de un bloque desde disco a la memoria principal. En cambio, ninguna de ellas requiere específicamente la transferencia de un bloque desde la memoria principal al disco. El bloque de memoria intermedia B se escribe finalmente en el disco bien porque el gestor de la memoria intermedia necesita espacio en memoria para otros propósitos, o bien porque el sistema de base de datos desea reflejar en el disco los cambios sufridos por B. Se dice que el sistema de bases de datos fuerza la salida de la memoria intermedia B si ejecuta el comando salida(B). Cuando una transacción necesita acceder a un elemento de datos X por primera vez, debe ejecutar leer(X). Todas las actualizaciones de X se llevan a cabo sobre xi . Después de que la transacción acceda a X por última vez, se debe ejecutar escribir(X) para reflejar en la propia base de datos los cambios sufridos por X. La operación salida(BX ) sobre el bloque de memoria intermedia BX en el que reside X no tiene por qué tener efecto inmediatamente después de ejecutar escribir(X), ya que el bloque BX puede contener otros elementos de datos que a los que aún se esté accediendo. Así, la salida real tiene lugar más tarde. Obsérvese que, si el sistema se bloquea después de ejecutar la operación escribir(X), pero antes de ejecutar salida(BX ), no se escribe nunca en el disco el nuevo valor de X y, por tanto, se pierde. 17.3 Recuperación y atomicidad

Considérese de nuevo el sistema bancario simplificado y una transacción Ti que transfiere 50 e desde la cuenta A a la cuenta B, siendo los saldos iniciales de A y de B de 1.000 e y de 2.000 e, respectivamente. Supóngase que el sistema cae durante la ejecución de Ti después de haberse ejecutado salida(BA ), pero antes de la ejecución de salida(BB ), donde BA y BB denotan los bloques de memoria intermedia en los que residen BA y BB . Al perderse el contenido de la memoria no se sabe la suerte de la transacción; así, podríamos invocar uno de los dos procedimientos posibles de recuperación. • Volver a ejecutar Ti . Este procedimiento hará que el saldo de A se quede en 900 e en vez de en 950 e. De este modo el sistema entra en un estado inconsistente. • No volver a ejecutar Ti . El estado actual del sistema otorga los valores de 950 e y 2.000 e para A y B respectivamente. Por tanto, el sistema entra en un estado inconsistente. En cualquier caso se deja a la base de datos en un estado inconsistente y, por tanto, este esquema simple de recuperación de datos no funciona. El motivo de este mal funcionamiento es que se ha modificado la base de datos sin tener la seguridad de que la transacción se comprometa realmente. El objetivo es realizar todos los cambios inducidos por Ti o no llevar a cabo ninguno. Sin embargo, si Ti realiza varias

www.detodoprogramacion.com


572

Capítulo 17

Sistema de recuperación

modificaciones en la base de datos, pueden necesitarse varias operaciones de salida y puede ocurrir un fallo después de haberse concluido alguna de estas modificaciones, pero antes de haber terminado todas. Para conseguir el objetivo de la atomicidad se debe efectuar primero la operación de salida de la información que describe las modificaciones en el almacenamiento estable sin modificar todavía la base de datos. Como se verá, este procedimiento permitirá realizar la salida de todas las modificaciones realizadas por una transacción comprometida aunque se produzcan fallos. Supondremos que las transacciones se ejecutan secuencialmente; es decir, sólo una transacción está activa en cada momento. Se describirá la forma de manejar la ejecución concurrente de transacciones más adelante, en el Apartado 17.5.

17.4 Recuperación basada en el registro histórico

La estructura más ampliamente utilizada para guardar las modificaciones de una base de datos es el registro histórico. El registro histórico es una secuencia de registros que almacena todas las actividades de actualización de la base de datos. Existen varios tipos de registros del registro histórico. Un registro de actualización del registro histórico describe una única escritura en la base de datos y tiene los siguientes campos: • El identificador de la transacción es un identificador único de la transacción que realiza la operación escribir. • El identificador del elemento de datos es un identificador único del elemento de datos que se escribe. Normalmente suele coincidir con la ubicación del elemento de datos en el disco. • El valor anterior es el valor que tenía el elemento de datos antes de la escritura. • El valor nuevo es el valor que tendrá el elemento de datos después de la escritura. Existen otros registros del registro histórico especiales para registrar sucesos significativos durante el procesamiento de una transacción, tales como el comienzo de una transacción y el éxito o aborto de la misma. Denotaremos como sigue los diferentes tipos de registros del registro histórico: • <Ti iniciada>. La transacción Ti ha comenzado. • <Ti , Xj , V1 , V2 >. La transacción Ti ha realizado una escritura sobre el elemento de datos Xj . Xj tenía el valor V1 antes de la escritura y tendrá el valor V2 después de la escritura. • <Ti comprometida>. La transacción Ti se ha comprometido. • <Ti abortada>. La transacción Ti ha sido abortada. Cuando una transacción realiza una escritura es fundamental que se cree el registro del registro histórico correspondiente a esa escritura antes de modificar la base de datos. Una vez que el registro del registro histórico existe, se puede realizar la salida de la modificación a la base de datos si se desea. Además, es posible deshacer una modificación que ya haya salido a la base de datos. Se deshará utilizando el campo valor-anterior de los registros del registro histórico. Para que los registros del registro histórico sean útiles para recuperarse frente a errores del disco o del sistema, el registro histórico debe residir en almacenamiento estable. Por ahora supóngase que cada registro del registro histórico se escribe, tan pronto como se crea, al final del registro histórico en almacenamiento estable. En el Apartado 17.7 se verán las condiciones necesarias para poder relajar este requisito de forma segura de modo que se reduzca la sobrecarga impuesta por el registro histórico. En los Apartados 17.4.1 y 17.4.2 se presentarán dos técnicas de utilización del registro histórico para garantizar la atomicidad frente a fallos. Obsérvese que en el registro histórico se tiene constancia de todas las actividades de la base de datos. Como consecuencia, el tamaño de los datos almacenados en el registro histórico puede llegar a ser extremadamente grande. En el Apartado 17.4.3 se mostrará bajo qué condiciones se puede borrar información del registro histórico de manera segura.

www.detodoprogramacion.com


Recuperaciรณn basada en el registro histรณrico

17.4

iniciada

573

comprometida iniciada

Figura 17.2

comprometida

Fragmento del registro histรณrico de la base de datos correspondiente a T0 y T1 .

17.4.1 Modi caciรณn diferida de la base de datos

La tรฉcnica de modificaciรณn diferida garantiza la atomicidad de las transacciones mediante el almacenamiento de todas las modificaciones de la base de datos en el registro histรณrico, pero retardando la ejecuciรณn de todas las operaciones escribir de una transacciรณn hasta que la transacciรณn se compromete parcialmente. Recuรฉrdese que se dice que una transacciรณn se compromete parcialmente una vez que se ejecuta la acciรณn final de la transacciรณn. En la versiรณn de la tรฉcnica de modificaciรณn diferida que se describe en este apartado se supone que las transacciones se ejecutan secuencialmente. Cuando una transacciรณn se compromete parcialmente, la informaciรณn del registro histรณrico asociada a esa transacciรณn se utiliza para la ejecuciรณn de las escrituras diferidas. Si el sistema cae antes de que la transacciรณn complete su ejecuciรณn o si la transacciรณn aborta, la informaciรณn del registro histรณrico simplemente se ignora. La ejecuciรณn de una transacciรณn Ti opera de esta manera: antes de que Ti comience su ejecuciรณn se escribe en el registro histรณrico un registro <Ti iniciada>. La operaciรณn escribir(X) realizada por Ti se traduce en la escritura de un nuevo registro en el registro histรณrico. Finalmente, cuando Ti se ha comprometido parcialmente, se escribe en el registro histรณrico un registro <Ti comprometida>. Cuando Ti se compromete parcialmente, los registros asociados a ella en el registro histรณrico se utilizan para la ejecuciรณn de las escrituras diferidas. Como puede ocurrir un fallo mientras se lleva a cabo esta actualizaciรณn, hay que asegurarse de que, antes del comienzo de estas actualizaciones, todos los registros del registro histรณrico se guardan en almacenamiento estable. Una vez que se ha hecho esto, la actualizaciรณn real tiene lugar y la transacciรณn pasa al estado comprometido. Obsรฉrvese que la tรฉcnica de modificaciรณn diferida sรณlo requiere el nuevo valor de los elementos de datos. Asรญ, se puede simplificar la estructura general de los registros de actualizaciรณn del registro histรณrico que se vieron en el apartado anterior omitiendo el campo para el valor anterior. Para ilustrar esto reconsidรฉrese el sistema bancario simplificado. Sea T0 una transacciรณn que transfiere 50 e desde la cuenta A a la cuenta B: T0 : leer(A); A := A โ 50; escribir(A); leer(B); B := B + 50; escribir(B). Sea T1 una transacciรณn que retira 100 e de la cuenta C: T1 : leer(C); C := C โ 100; escribir(C). Supรณngase que estas transacciones se ejecutan secuencialmente, primero T0 y despuรฉs T1 , y que los saldos de las cuentas A, B y C antes de producirse la ejecuciรณn eran 1.000, 2.000 y 700 e respectivamente. El fragmento del registro histรณrico que contiene la informaciรณn relevante sobre estas dos transacciones se muestra en la Figura 17.2.

www.detodoprogramacion.com


574

CapĂ­tulo 17

Sistema de recuperaciĂłn

iniciada

comprometida

iniciada

comprometida

Figura 17.3

Estado del registro histĂłrico y de la base de datos correspondiente a T0 y T1 .

Las salidas reales que se producen en el sistema de bases de datos y en el registro histórico como consecuencia de la ejecución de T0 y T1 pueden seguir distintas ordenaciones. Una ordenación posible se presenta en la Figura 17.3. ObsÊrvese que el valor de A se cambia en la base de datos sólo despuÊs de que el registro <T0 , A, 950> se haya introducido en el registro histórico. Mediante la utilización del registro histórico, el sistema puede manejar cualquier fallo que conduzca a la pÊrdida de información en el almacenamiento volåtil. El esquema de recuperación usa el siguiente procedimiento de recuperación: • rehacer(Ti ) define el valor de todos los elementos de datos actualizados por la transacción Ti como los valores nuevos. El conjunto de elementos de datos actualizados por Ti y sus respectivos nuevos valores se encuentran en el registro histórico. La operación rehacer debe ser idempotente, esto es, el resultado de ejecutarla varias veces debe ser equivalente al resultado de ejecutarla una sola vez. Esta característica es fundamental para garantizar un correcto comportamiento incluso si el fallo se produce durante el proceso de recuperación. DespuÊs de ocurrir un fallo, el subsistema de recuperación consulta el registro histórico para determinar las transacciones que deben rehacerse. Una transacción Ti debe rehacerse si y sólo si el registro histórico contiene los registros <Ti iniciada> y <Ti comprometida>. Así, si el sistema cae despuÊs de que la transacción complete su ejecución, la información en el registro histórico se utiliza para restituir el sistema a un estado consistente anterior. Para ilustrar esto volvamos a considerar el ejemplo bancario con la ejecución ordenada de las transacciones T0 y T1 , primero T0 y despuÊs T1 . En la Figura 17.2 se muestra el registro histórico que resulta de la ejecución completa de T0 y T1 . Supóngase que el sistema cae antes de completarse las transacciones para poder ver el modo en que la tÊcnica de recuperación lleva a la base de datos a un estado consistente. Supóngase que la caída ocurre justo despuÊs de haber escrito en almacenamiento estable el registro del registro histórico para el paso escribir(B) de la transacción T0 . El contenido del registro histórico en el momento de la caída puede verse en la Figura 17.4a. Cuando el sistema vuelve a funcionar no es necesario llevar a cabo ninguna acción rehacer ya que no aparece ningún registro de compromiso en el registro histórico. Los saldos de las cuentas A y B siguen siendo de 1.000 y 2.000 e respectivamente. Pueden borrarse del registro histórico los registros de la transacción incompleta T0 . Supóngase ahora que la caída sucede justo despuÊs de haber escrito en almacenamiento estable el registro del registro histórico para el paso escribir(C)

www.detodoprogramacion.com


17.4

<T0 iniciada> <T0 , A, 950> <T0 , B, 2050>

(a) Figura 17.4

Recuperación basada en el registro histórico

<T0 iniciada> <T0 , A, 950> <T0 , B, 2050> <T0 comprometida> <T1 iniciada> <T1 , C, 600>

<T0 iniciada> <T0 , A, 950> <T0 , B, 2050> <T0 comprometida> <T1 iniciada> <T1 , C, 600> <T1 comprometida>

(b)

(c)

575

El mismo registro histórico que el de la Figura 17.3 en tres momentos distintos.

de la transacción T1 . En este caso, el contenido del registro histórico en el momento de la caída puede verse en la Figura 17.4b. Cuando el sistema vuelve a funcionar se realiza la operación rehacer(T0 ) ya que el registro <T0 comprometida> aparece en el registro histórico en el disco. Después de la ejecución de esta operación, los saldos de las cuentas A y B son de 950 y 2.050 e respectivamente. El saldo de la cuenta C se mantiene en 700 e. Igual que antes, pueden borrarse del registro histórico los registros de la transacción incompleta T1 . Por último, supóngase que la caída ocurre justo después de haber escrito en almacenamiento estable el registro del registro histórico <T1 comprometida> El contenido del registro histórico en el momento de la caída se muestra en la Figura 17.4c. Cuando el sistema vuelve a funcionar, hay dos registros comprometida en el registro: uno para T0 y otro para T1 . Así pues, deben realizarse las operaciones rehacer(T0 ) y rehacer(T1 ). Después de la ejecución de estas operaciones, los saldos de las cuentas A, B y C son de 950, 2.050 y 600 e, respectivamente. Considérese, finalmente, un caso en el que tiene lugar una segunda caída del sistema durante la recuperación de la primera. Deben hacerse algunos cambios en la base de datos como consecuencia de la ejecución de las operaciones rehacer, pero no se han realizado todos los cambios. Cuando el sistema vuelve a funcionar después de la segunda caída, la recuperación procede exactamente igual que en los ejemplos anteriores. Para cada registro <Ti comprometida> que se encuentre en el registro histórico, se ejecuta la operación rehacer(Ti ). En otras palabras, las acciones de recuperación se vuelven a reanudar desde el principio. Como rehacer escribe los valores en la base de datos independientemente de los datos que haya actualmente en la base de datos, el resultado de un segundo intento acabado con éxito en la ejecución de rehacer es el mismo que si rehacer hubiera acabado con éxito la primera vez. 17.4.2 Modi cación inmediata de la base de datos

La técnica de modificación inmediata permite realizar la salida de las modificaciones de la base de datos a la propia base de datos mientras que la transacción está todavía en estado activo. Las modificaciones de datos escritas por transacciones activas se denominan modificaciones no comprometidas. En caso de una caída o de un fallo en la transacción, el sistema debe utilizar el campo para el valor anterior de los registros del registro histórico descritos en el Apartado 17.4 para restaurar los elementos de datos modificados a los valores que tuvieran antes de comenzar la transacción. Esta restauración se lleva a cabo mediante la operación deshacer descrita a continuación. Antes de comenzar la ejecución de una transacción Ti , se escribe en el registro histórico el registro <Ti iniciada>. Durante su ejecución, cualquier operación escribir(X) realizada por Ti , es precedida por la escritura en el registro histórico de un registro actualizado apropiado. Cuando Ti se compromete parcialmente se escribe en el registro histórico el registro <Ti comprometida>.

www.detodoprogramacion.com


576

CapĂ­tulo 17

Sistema de recuperaciĂłn

iniciada

comprometida iniciada

Figura 17.5

comprometida

Fragmento del registro histĂłrico del sistema correspondiente a T0 y a T1 .

Como la información del registro histórico se utiliza para reconstruir el estado de la base de datos, la actualización real de la base de datos no puede permitirse antes de que el registro del registro histórico correspondiente se haya escrito en almacenamiento estable. Por lo tanto, es necesario que antes de la ejecución de una salida(B), se escriban en almacenamiento estable los registros del registro histórico correspondientes a B. Esto volverå a tratarse en el Apartado 17.7. Para ilustrarlo considÊrese de nuevo el sistema bancario simplificado con la ejecución ordenada de las transacciones T0 y T1 , primero T0 y despuÊs T1 . Las líneas del registro histórico que contienen la información relevante concerniente a estas dos transacciones se muestran en la Figura 17.5. En la Figura 17.6 se describe una posible ordenación de las salidas reales que se producen en el sistema de bases de datos y en el registro histórico como consecuencia de la ejecución de T0 y T1 . ObsÊrvese que esta ordenación no podría obtenerse con la tÊcnica de modificación diferida que se vio en el Apartado 17.4.1. Mediante la utilización del registro histórico, el sistema puede manejar cualquier fallo que no genere una pÊrdida de información en el almacenamiento no volåtil. El esquema de recuperación usa dos procedimientos de recuperación: • deshacer(Ti ) restaura el valor de todos los elementos de datos actualizados por la transacción Ti a los valores anteriores. • rehacer(Ti ) cambia el valor de todos los elementos de datos actualizados por la transacción Ti a los nuevos valores. El conjunto de elementos de datos actualizados por Ti y sus respectivos anteriores y nuevos valores se encuentran en el registro histórico. Las operaciones deshacer y rehacer deben ser idempotentes para garantizar un comportamiento correcto incluso en el caso de que el fallo se produzca durante el proceso de recuperación. DespuÊs de haberse producido un fallo, el esquema de recuperación consulta el registro histórico para determinar las transacciones que deben rehacerse y las que deben deshacerse.

Registro histĂłrico

Base de datos

<T0 iniciada> <T0 , A, 1000, 950> <T0 , B, 2000, 2050> <T0 comprometida> <T1 iniciada> <T1 , C, 700, 600>

A = 950 B = 2050 C = 600

<T1 comprometida> Figura 17.6

Estado del registro histĂłrico y de la base de datos correspondientes a T0 y a T1 .

www.detodoprogramacion.com


17.4

<T0 iniciada> <T0 , A, 1000, 950> <T0 , B, 2000, 2050>

(a) Figura 17.7

Recuperación basada en el registro histórico

<T0 iniciada> <T0 , A, 1000, 950> <T0 , B, 2000, 2050> <T0 comprometida> <T1 iniciada> <T1 , C, 700, 600> (b)

577

<T0 iniciada> <T0 , A, 1000, 950> <T0 , B, 2000, 2050> <T0 comprometida> <T1 iniciada> <T1 , C, 700, 600> <T1 comprometida> (c)

El mismo registro histórico mostrado en tres momentos distintos.

• Una transacción Ti debe deshacerse si el registro histórico contiene el registro <Ti iniciada>, pero no contiene el registro <Ti comprometida>. • Una transacción Ti debe rehacerse si el registro histórico contiene los registros <Ti iniciada> y <Ti comprometida>. Para ilustrarlo, considérese de nuevo el sistema bancario con la ejecución ordenada de las transacciones T0 y T1 , primero T0 y después T1 . Supóngase que el sistema cae antes de completarse las transacciones. Se considerarán tres casos. El estado del registro histórico para cada uno de ellos se muestra en la Figura 17.7. En primer lugar supóngase que la caída ocurre justo después de haber escrito en almacenamiento estable el registro del registro histórico para el paso escribir(B) de la transacción T0 (Figura 17.7a). Cuando el sistema vuelve a funcionar encuentra en el registro histórico el registro <T0 iniciada>, pero no su correspondiente <T0 comprometida>. Por lo tanto, la transacción T0 debe deshacerse y se ejecutaría deshacer(T0 ). Como resultado de esta operación, los saldos de las cuentas A y B (en el disco) se restituirían a 1.000 y 2.000 e respectivamente. Supóngase ahora que la caída sucede justo después de haber escrito en almacenamiento estable el registro del registro histórico para el paso escribir(C) de la transacción T1 (Figura 17.7b). Cuando el sistema vuelve a funcionar, es necesario llevar a cabo dos acciones de recuperación. La operación deshacer(T1 ) debe ejecutarse porque en el registro histórico aparece el registro <T1 iniciada>, pero no aparece <T1 comprometida>. La operación rehacer(T0 ) debe ejecutarse porque el registro histórico contiene los registros <T0 iniciada> y <T0 comprometida>. Al final del procedimiento de recuperación, los saldos de las cuentas A, B y C son de 950, 2.050 y 700 e respectivamente. Obsérvese que la operación deshacer(T1 ) se ejecuta antes que rehacer(T0 ). En este ejemplo, el resultado sería el mismo si se cambiara el orden. Sin embargo, el hecho de realizar primero las operaciones deshacer y luego las operaciones rehacer es importante para el algoritmo de recuperación que se describe en el Apartado 17.5. Por último, supóngase que la caída tiene lugar justo después de haber escrito en almacenamiento estable el registro del registro histórico <T1 comprometida> (Figura 17.7c). Cuando el sistema vuelve a funcionar, deben rehacerse tanto T0 como T1 ya que se encuentran en el registro histórico los registros <T0 iniciada> y <T0 comprometida>, así como los registros <T1 iniciada> y <T1 comprometida>. Los saldos de las cuentas A, B y C después de la ejecución de los procedimientos de recuperación rehacer(T0 ) y rehacer(T1 ) se sitúan en 950, 2.050 y 600 e respectivamente.

www.detodoprogramacion.com


578

Capítulo 17

Sistema de recuperación

17.4.3 Puntos de revisión

Cuando ocurre un fallo en el sistema se debe consultar el registro histórico para determinar las transacciones que deben rehacerse y las que deben deshacerse. En principio es necesario recorrer completamente el registro histórico para hallar esta información. En este enfoque hay dos inconvenientes principales: 1. El proceso de búsqueda consume tiempo. 2. La mayoría de las transacciones que deben rehacerse de acuerdo con el algoritmo ya tienen escritas sus actualizaciones en la base de datos. Aunque el hecho de volver a ejecutar estas transacciones no produzca resultados erróneos, sí repercutirá en un aumento del tiempo de ejecución del proceso de recuperación. Para reducir este tipo de sobrecarga se introducen los puntos de revisión. Durante la ejecución, el sistema actualiza el registro histórico utilizando una de las dos técnicas que se describen en los Apartados 17.4.1 y 17.4.2. Además, el sistema realiza periódicamente puntos de revisión, en los cuales tiene lugar la siguiente secuencia de acciones: 1. Escritura en almacenamiento estable de todos los registros del registro histórico que residan en ese momento en memoria principal. 2. Escritura en disco de todos los bloques de memoria intermedia que se hayan modificado. 3. Escritura en almacenamiento estable de un registro del registro histórico <revisión>. Mientras se lleva a cabo un punto de revisión no se permite que ninguna transacción realice acciones de actualización, tales como escribir en un bloque de memoria intermedia o escribir un registro del registro histórico. La presencia de un registro <revisión> en el registro histórico permite que el sistema pueda hacer más eficiente su procedimiento de recuperación. Considérese una transacción Ti que se comprometió antes del punto de revisión. Para esa transacción el registro <Ti comprometida> aparece en el registro histórico antes que el registro <revisión>. Todas las modificaciones sobre la base de datos hechas por Ti se deben haber escrito en la base de datos antes del punto de revisión o formando parte del propio punto de revisión. Así, en el momento de la recuperación, no es necesario ejecutar una operación rehacer sobre Ti . Esta observación permite perfeccionar los esquemas anteriores de recuperación (sigue siendo válido el supuesto de que las transacciones se ejecutan secuencialmente). Cuando se produce un fallo, el esquema de recuperación examina el registro histórico para determinar la última transacción Ti que comenzó su ejecución antes de que tuviera lugar el último punto de revisión. Para encontrar una transacción de este tipo se recorre el registro histórico hacia atrás, esto es, se empieza a buscar por el final del registro histórico hasta que se encuentra el primer registro <revisión> (como se va recorriendo el registro histórico hacia atrás, el registro encontrado corresponde al último registro <revisión> del registro histórico); después se continúa la búsqueda hacia atrás hasta que se encuentra el siguiente registro <Ti iniciada>. Este registro identifica a la transacción Ti . Una vez que ha sido identificada la transacción Ti sólo es necesario aplicar las operaciones rehacer y deshacer a la transacción Ti y a las transacciones Tj que comenzaron su ejecución después que Ti . Sea T este conjunto de transacciones. Puede ignorarse el resto del registro histórico (la parte del principio) y puede borrarse cuando se desee. El conjunto exacto de operaciones de recuperación que han de llevarse a cabo depende de si se está usando la técnica de modificación inmediata o la de modificación diferida. Si se emplea la técnica de modificación inmediata, las operaciones de recuperación deben ser las siguientes: • Ejecutar deshacer(Tk ) para todas las transacciones Tk de T para las que no exista un registro <Tk comprometida> en el registro histórico. • Ejecutar execute rehacer(Tk ) para todas las transacciones Tk de T para las que aparece un registro <Tk comprometida> en el registro histórico.

www.detodoprogramacion.com


17.5

Transacciones concurrentes y recuperación

579

Obviamente no es necesario aplicar la operación deshacer cuando se está utilizando la técnica de modificación diferida. A modo de ejemplo, considérese el conjunto de transacciones {T0 , T1 , . . ., T100 } de modo que su ejecución se produce en el orden determinado por los subíndices. Supóngase que el último punto de revisión tiene lugar durante la ejecución de la transacción T67 . Así, durante el esquema de recuperación, sólo deben considerarse las transacciones T67 , T68 , . . ., T100 . Será necesario rehacer cada una de ellas si éstas se comprometieron y será necesario deshacerlas en caso contrario. En el Apartado 17.5.3 se estudia una extensión de la técnica de puntos de revisión para el procesamiento concurrente de transacciones. 17.5 Transacciones concurrentes y recuperación

Hasta ahora se ha tratado la recuperación en un entorno en el que se ejecutaba una sola transacción en cada instante. Ahora se verá cómo modificar y extender el esquema de recuperación basado en registro histórico para permitir la ejecución concurrente de múltiples transacciones. El sistema sigue teniendo una única memoria intermedia de disco y un único registro histórico independientemente del número de transacciones concurrentes. Todas las transacciones comparten los bloques de la memoria intermedia. Se permiten actualizaciones inmediatas y que un bloque de la memoria intermedia tenga elementos de datos que hayan sido modificados por una o más transacciones. 17.5.1 Interacción con el control de concurrencia

El esquema recuperación depende en gran medida del esquema de control de concurrencia que se use. Para hacer retroceder los efectos de una transacción fallida deben deshacerse las modificaciones realizadas por esa transacción. Supóngase que se debe retroceder una transacción T0 y que un dato Q, que fue modificado por T0 , tiene que recuperar su antiguo valor. Si se está usando un esquema basado en registro histórico para la recuperación, es posible restablecer el valor de Q utilizando la información contenida en el registro histórico. Supóngase ahora que una segunda transacción T1 realiza una nueva modificación sobre Q antes de retroceder T0 . En este caso, al retroceder T0 , se perdería la modificación realizada por T1 . Es necesario, por tanto, que si una transacción T modifica el valor de un elemento de datos Q, ninguna otra transacción pueda modificar el mismo elemento de datos hasta que T se haya comprometido o haya sido retrocedida. Este requisito puede satisfacerse fácilmente utilizando bloqueo estricto de dos fases— esto es, bloqueo de dos fases que mantiene los bloqueos exclusivos hasta el final de la transacción. 17.5.2 Retroceso de transacciones

Se utiliza el registro histórico para retroceder una transacción Ti fallida. El registro histórico se explora hacia atrás; para cada registro del registro histórico de la forma <Ti , Xj , V1 , V2 >, se restablece el valor del elemento de datos Xj con su valor anterior: V1 . La exploración del registro histórico termina cuando se encuentra el registro <Ti , iniciada>. Es importante el hecho de recorrer el registro histórico empezando por el final, ya que una transacción puede haber actualizado más de una vez el valor de un elemento de datos. Como ejemplo, considérese este par de registros: <Ti , A, 10, 20> <Ti , A, 20, 30> Estos registros del registro histórico representan una modificación del elemento de datos A por parte de la transacción Ti , seguida de otra modificación de A hecha también por Ti . Al recorrer el registro histórico al revés se establece correctamente el valor de A como 10. Si el registro histórico se recorriera hacia delante, A tomaría como valor 20, lo cual es incorrecto. Si para el control de concurrencia se utiliza el bloqueo estricto de dos fases, los bloqueos llevados a cabo por una transacción T sólo pueden ser desbloqueados después de que la transacción haya retrocedido según se acaba de describir. Una vez que T (que está retrocediendo) haya actualizado un elemento

www.detodoprogramacion.com


580

Capítulo 17

Sistema de recuperación

de datos, ninguna otra transacción podría haber actualizado el mismo elemento de datos debido a los requisitos del control de concurrencia que se mencionaron en el Apartado 17.5.1. Así pues, la restitución del valor anterior de un elemento de datos no borrará los efectos de otra transacción. 17.5.3 Puntos de revisión

En el Apartado 17.4.3 se usaban los puntos de revisión para reducir el número de registros del registro histórico que debían ser examinados cuando el sistema se recuperaba de una caída. Como se asumía que no existía la concurrencia, durante la recuperación era necesario considerar solamente las siguientes transacciones: • Las transacciones que comenzaron después del último punto de revisión. • La única transacción, si la había, que estaba activa en el momento de grabarse el último punto de revisión. Cuando las transacciones pueden ejecutarse concurrentemente, la situación se torna más complicada ya que varias transacciones pueden estar activas en el momento en que se produce el último punto de revisión. En un sistema de procesamiento de transacciones concurrente es necesario que el registro del registro histórico correspondiente a un punto de revisión sea de la forma <revisión L>, donde L es una lista con las transacciones activas en el momento del punto de revisión. De nuevo se supone que, mientras que se realiza el punto de revisión, las transacciones no efectúan modificaciones ni sobre los bloques de la memoria intermedia ni sobre el registro histórico. El requisito de que las transacciones no puedan realizar modificaciones sobre los bloques de la memoria intermedia ni sobre el registro histórico durante un punto de revisión puede resultar molesto ya que el procesamiento de transacciones tendrá que parar durante la ejecución de un punto de revisión. Un punto de revisión durante el cual se permite que las transacciones realicen modificaciones incluso mientras los bloques de memoria intermedia se están guardando en disco, se denomina punto de revisión difuso. En el Apartado 17.8.5 se describen esquemas de revisión difusa. 17.5.4 Recuperación al reiniciar

El sistema construye dos listas cuando se recupera de una caída: la lista-deshacer, que consta de las transacciones que han de deshacerse, y la lista-rehacer, que está formada por las transacciones que deben rehacerse. Estas dos listas se construyen durante la recuperación de la siguiente manera. Al principio ambas están vacías. Luego se recorre el registro histórico hacia atrás examinando cada registro hasta que se encuentra el primer registro <revisión>: • Para cada registro encontrado de la forma <Ti comprometida>, se añade Ti a la lista-rehacer. • Para cada registro encontrado de la forma <Ti iniciada>, si Ti no está en la lista-rehacer, entonces se añade Ti a la lista-deshacer. Una vez que se han examinado los registros apropiados del registro histórico, se atiende al contenido de la lista L en el registro punto de revisión. Para cada transacción Ti en L, si Ti no está en la lista-rehacer, entonces se añade Ti a la lista-deshacer. Cuando se terminan la lista-rehacer y la lista-deshacer, el proceso de recuperación procede de la siguiente manera: 1. Se recorre de nuevo el registro histórico hacia atrás comenzando en el último registro y se realiza una operación deshacer por cada registro del registro histórico que pertenezca a una transacción Ti de la lista-deshacer. En esta fase se ignoran los registros del registro histórico concernientes a transacciones de la lista-rehacer. El recorrido del registro histórico termina cuando se encuentran registros <Ti iniciada> para cada transacción Ti de la lista-deshacer.

www.detodoprogramacion.com


17.6

Gestión de la memoria intermedia

581

2. Se localiza el último registro <revisión L> del registro histórico. Obsérvese que este paso puede necesitar un recorrido del registro histórico hacia delante si el registro del punto de revisión quedara atrás en el paso 1. 3. Se recorre el registro histórico hacia delante desde el último registro <revisión L> y se realiza una operación rehacer por cada registro del registro histórico que pertenezca a una transacción Ti de la lista-rehacer. En esta fase se ignoran los registros del registro histórico concernientes a transacciones de la lista-deshacer. Es importante procesar el registro histórico hacia atrás en el paso 1 para garantizar que el estado resultante de la base de datos sea correcto. Después de haber deshecho todas las transacciones de la lista-deshacer se rehacen aquellas transacciones que pertenezcan a la lista-rehacer. En este caso es importante procesar el registro histórico hacia delante. Cuando se ha completado el proceso de recuperación, se continúa con el procesamiento normal de las transacciones. Es importante el hecho de deshacer las transacciones de la lista-deshacer antes de rehacer las transacciones de la lista-rehacer al utilizar los pasos 1 a 3 del algoritmo anterior. El siguiente problema podría ocurrir de no hacerse así. Supóngase que el elemento de datos A vale inicialmente 10. Supóngase también que una transacción Ti modifica el valor de A situándolo en 20 y aborta a continuación; el retroceso de la transacción devolvería a A el valor 10. Supóngase que otra transacción Tj cambia entonces a 30 el valor de A, se compromete y, seguidamente, el sistema cae. El estado del registro histórico en el momento de la caída es: <Ti , A, 10, 20> <Tj , A, 10, 30> <Tj comprometida> Si se rehace primero, A tomará el valor 30; y luego, al deshacer, A acabará valiendo 10, lo cual es incorrecto. El valor final de Q debe ser 30, lo que puede garantizarse si se deshace antes de rehacer. 17.6 Gestión de la memoria intermedia

En este apartado se consideran varios detalles sutiles que son esenciales para la implementación de un esquema de recuperación que garantice la consistencia de los datos y que lleve asociado una sobrecarga mínima respecto a la interacción con la base de datos. 17.6.1 Registro histórico con memoria intermedia

Hasta aquí se ha supuesto que cada registro del registro histórico en almacenamiento estable se escribe en el mismo momento de su creación. Esta suposición impone una sobrecarga muy alta en la ejecución del sistema por las siguientes razones. Habitualmente, la unidad de escritura en almacenamiento estable es el bloque. En la mayoría de los casos un registro del registro histórico es mucho más pequeño que un bloque. Así, la escritura de cada registro del registro histórico se traduce en una escritura mucho mayor en el nivel físico. Además de esto, como se vio en el Apartado 17.2.2, la escritura de un bloque en almacenamiento estable puede involucrar varias operaciones de escritura en el nivel físico. El coste de realizar la escritura en almacenamiento estable de un bloque es suficientemente elevado para que sea deseable escribir de una sola vez varios registros del registro histórico. Para hacer esto se escriben los registros del registro histórico en una memoria intermedia almacenada en la memoria principal en la que permanecen durante un tiempo hasta que se guardan en almacenamiento estable. Se pueden acumular varios registros del registro histórico en la memoria intermedia del registro histórico y escribirse en almacenamiento estable con una sola operación. El orden de los registros del registro histórico en el almacenamiento estable debe ser exactamente el mismo orden en el que fueron escritos en la memoria intermedia del registro histórico. Debido a la utilización de la memoria intermedia en el registro histórico, antes de ser escrito en almacenamiento estable, un registro del registro histórico puede permanecer únicamente en memoria principal (almacenamiento volátil) durante un espacio de tiempo considerable. Como esos registros se

www.detodoprogramacion.com


582

Capítulo 17

Sistema de recuperación

perderían si el sistema cayese, es necesaria la imposición de nuevos requisitos sobre las técnicas de recuperación para garantizar la atomicidad de las transacciones: • Después de que el registro <Ti comprometida> se haya escrito en almacenamiento estable, la transacción Ti pasa al estado comprometida. • Antes de escribir en almacenamiento estable el registro <Ti comprometida>, todos los registros del registro histórico pertenecientes a la transacción Ti se deben escribir en almacenamiento estable. • Antes de que un bloque de datos en memoria principal se pueda escribir en la base de datos (en almacenamiento no volátil) todos los registros del registro histórico pertenecientes a los datos de ese bloque se deben escribir en almacenamiento estable. Este último requisito se denomina regla de registro de escritura anticipada (REA). Estrictamente hablando, la regla REA sólo necesita que haya sido puesta en almacenamiento estable la información concerniente a la operación deshacer y permite que la información relativa a la operación rehacer pueda escribirse más tarde. La diferencia es relevante en aquellos sistemas en los que la información para rehacer y deshacer se guarda en registros del registro histórico independientes. Las reglas anteriores representan situaciones en las que ciertos registros del registro histórico deben haber sido escritos en almacenamiento estable. No se produce ningún problema como resultado de la escritura de los registros del registro histórico antes de que sea necesaria. Así, cuando el sistema decide que es necesario escribir en almacenamiento estable un registro del registro histórico, puede escribir un bloque entero de ellos si hay suficientes registros en memoria principal como para llenar un bloque. Si no hay suficientes registros para llenar el bloque, se forma un bloque parcialmente lleno con todos los registros que hubiera en memoria principal y se ponen en almacenamiento estable. La escritura en disco de la memoria intermedia del registro histórico se denomina a veces forzar el registro histórico. 17.6.2 Base de datos con memoria intermedia

En el Apartado 17.2 se describió el uso de una jerarquía de almacenamiento de dos niveles. La base de datos se almacena en almacenamiento no volátil (disco) y, cuando es necesario, se traen a memoria principal los bloques de datos que hagan falta. Como la memoria principal suele ser mucho más pequeña que la base de datos completa, puede ser necesaria la sobrescritura de un bloque B1 en memoria principal cuando es necesario traer a memoria otro bloque B2 . Si B1 ha sido modificado, B1 se debe escribir antes de traer B2 . Como se estudió en el Apartado 11.5.1, en el Capítulo 11, esta jerarquía de almacenamiento se corresponde con el concepto usual de memoria virtual. Las reglas que rigen la escritura de registros del registro histórico limitan la libertad del sistema para escribir bloques de datos. Si la lectura del bloque B2 provoca que el bloque B1 tenga que escribirse en almacenamiento estable, todos los registros del registro histórico pertenecientes a los datos de B1 se deben escribir en almacenamiento estable antes de la escritura de B1 . Por tanto, la secuencia de acciones que ha de llevar a cabo el sistema sería ésta: • Escritura en almacenamiento estable de los registros del registro histórico hasta que todos los registros pertenecientes al bloque B1 se hayan escrito. • Escritura en disco del bloque B1 . • Lectura del bloque B2 desde el disco a la memoria principal. Es un hecho importante el que no se produzcan escrituras sobre el bloque B1 mientras que se lleva a cabo la anterior secuencia de acciones. Esto puede garantizarse, como se explica a continuación, utilizando un medio de bloqueo especial. Antes de que una transacción realice una escritura sobre un elemento de datos debe adquirir un bloqueo en exclusiva sobre el bloque en el que reside el citado elemento de datos. Inmediatamente después de haber realizado la modificación, el bloqueo se puede liberar. Antes

www.detodoprogramacion.com


17.6

Gestión de la memoria intermedia

583

de la escritura de un bloque, el sistema obtiene un bloqueo exclusivo sobre ese bloque para asegurarse de que ninguna transacción está modificándolo. Una vez que la escritura del bloque se ha completado, el bloqueo se libera. Los bloqueos de corta duración se denominan con frecuencia pestillos. Los pestillos y los bloqueos utilizados por el sistema de control de concurrencia se tratan de forma diferente. Como resultado, los pestillos pueden liberarse sin necesidad de cumplir ningún protocolo de bloqueo, como el bloqueo de dos fases requerido por el sistema de control de concurrencia. Para ilustrar la necesidad del requisito de registro histórico con escritura anticipada considérese el ejemplo bancario con las transacciones T0 y T1 . Supóngase que el estado del registro histórico es <T0 iniciada> <T0 , A, 1000, 950> y que la transacción T0 realiza una operación leer(B). Supóngase también que el bloque en el que se encuentra B no está en memoria principal y que esa memoria principal está llena. Supóngase por último que el bloque en el que reside A es el elegido para la sustitución y, por tanto, ha de escribirse en disco. Si el sistema escribe este bloque en disco y luego sucede una caída, los valores para las cuentas A, B y C en la base de datos son 950, 2.000 y 700 e respectivamente. Este estado de la base de datos es inconsistente. Sin embargo, según los requisitos de la regla REA, el registro del registro histórico <T0 , A, 1000, 950> debe escribirse en almacenamiento estable antes de producirse la escritura del bloque en el que se encuentra A. El sistema puede usar ese registro del registro histórico durante la recuperación para devolver a la base de datos a un estado consistente. 17.6.3 La función del sistema operativo en la gestión de la memoria intermedia

La memoria intermedia de la base de datos puede gestionarse usando uno de estos dos enfoques: 1. El sistema de base de datos reserva parte de la memoria principal para utilizarla como memoria intermedia y es él, en vez del sistema operativo, el que se encarga de gestionarlo. El sistema de base de datos gestiona la transferencia de los bloques de datos de acuerdo con los requisitos del Apartado 17.6.2. El inconveniente de este enfoque es que limita la flexibilidad en la utilización de la memoria principal. El tamaño de la memoria intermedia no debe ser muy grande para que otras aplicaciones tengan suficiente espacio disponible en la memoria principal para sus propias necesidades. Sin embargo, incluso cuando ninguna otra aplicación esté en ejecución, la base de datos no podrá hacer uso de toda la memoria disponible. Asimismo, aquellas aplicaciones que no tienen nada que ver con la base de datos no pueden usar la región de la memoria reservada para la memoria intermedia de la base de datos aunque no se estén utilizando algunas de las páginas almacenadas en la memoria intermedia. 2. El sistema de base de datos implementa su memoria intermedia dentro de la memoria virtual del sistema operativo. Como el sistema operativo conoce los requisitos de memoria de todos los procesos del sistema, es lógico que pueda decidir los bloques de la memoria intermedia que deben escribirse al disco y el momento en el que debe realizarse esta escritura. Pero para garantizar los requisitos del registro histórico de escritura anticipada del Apartado 17.6.1, el sistema operativo no debería realizar él mismo la escritura de las páginas de la base de datos de la memoria intermedia, sino que debería pedírselo al sistema de base de datos para que fuera éste el que forzara la escritura de los bloques de la memoria intermedia. El sistema de base de datos, después de escribir en almacenamiento estable los registros del registro histórico relevantes, forzaría la escritura en la base de datos de los bloques de la memoria intermedia. Desafortunadamente, casi todos los sistemas operativos de la generación actual ejercen un control completo sobre la memoria virtual. El sistema operativo reserva espacio en el disco para almacenar las páginas de memoria virtual que no se encuentran en ese momento en la memoria principal; este espacio se denomina espacio de intercambio. Si el sistema operativo decide escribir un bloque Bx , ese bloque se escribe

www.detodoprogramacion.com


584

Capítulo 17

Sistema de recuperación

en el espacio de intercambio del disco por lo que el sistema de base de datos no tiene forma de controlar la escritura de los bloques de la memoria intermedia. Por consiguiente, si la memoria intermedia de la base de datos está en la memoria virtual, las transferencias entre los archivos de la base de datos y la memoria intermedia en memoria virtual deben estar gestionadas por el sistema de base de datos, hecho que subraya el cumplimiento de los requisitos del registro histórico de escritura anticipada que se vieron. Este enfoque puede provocar una escritura adicional de datos en el disco. Si el sistema operativo realiza la escritura de un bloque Bx , éste no se escribe en la base de datos sino que se escribe en el espacio de intercambio que utiliza la memoria virtual del sistema operativo. Cuando la base de datos necesita escribir Bx , el sistema operativo puede necesitar primero leer Bx de su espacio de intercambio. Así, en lugar de realizar una sola escritura de Bx , son necesarias dos escrituras (una del sistema operativo y otra del sistema de base de datos) y una lectura adicional. Aunque ambos enfoques tienen algunos inconvenientes, debe elegirse cualquiera de los dos excepto si el sistema operativo está diseñado para soportar los requisitos del registro histórico de base de datos. De los sistemas operativos actuales sólo unos pocos, como el sistema operativo Mach, soportan estos requisitos. 17.7 Fallo con pérdida de almacenamiento no volátil

Hasta ahora sólo se ha considerado el caso en el que un fallo conduce a la pérdida de información residente en almacenamiento volátil mientras que el contenido del almacenamiento no volátil permanecía intacto. A pesar de que es raro encontrarse con un fallo en el que se pierda información de almacenamiento no volátil, es necesario prepararse para afrontar este tipo de fallos. En este apartado se hablará sólo del almacenamiento en disco. La argumentación puede aplicarse también a otras clases de almacenamiento no volátil. La idea básica es volcar periódicamente (digamos, una vez al día) el contenido entero de la base de datos en almacenamiento estable. Por ejemplo, puede volcarse la base de datos en una o más cintas magnéticas. Se utilizará el volcado más reciente para que la base de datos recupere un estado consistente cuando ocurra un fallo que conduzca a la pérdida de algunos bloques físicos de la base de datos. Una vez que se complete esta operación, el sistema utilizará el registro histórico para llevar al sistema de base de datos al último estado consistente en el que estuvo antes de producirse el fallo. Más precisamente, ninguna transacción puede estar activa durante el procedimiento de volcado y tendrá lugar una secuencia de acciones similar a la utilizada en los puntos de revisión: 1. Escribir en almacenamiento estable todos los registros del registro histórico que residan en ese momento en memoria principal. 2. Escribir en disco todos los bloques de la memoria intermedia. 3. Copiar el contenido de la base de datos en almacenamiento estable. 4. Escribir el registro del registro histórico <volcar> en almacenamiento estable. Los pasos 1, 2 y 4 se corresponden con los tres pasos utilizados para realizar un punto de revisión en el Apartado 17.4.3. Para la recuperación por pérdida de almacenamiento no volátil se restituye la base de datos en el disco utilizando el último volcado realizado. Entonces se consulta el registro histórico y se rehacen todas las transacciones que se hubieran comprometido desde que se efectuó ese último volcado. Obsérvese que no es necesario ejecutar ninguna operación deshacer. Un volcado del contenido de una base de datos se denomina también volcado de archivo ya que pueden archivarse los volcados y utilizarlos más tarde para examinar estados anteriores de la base de datos. Los volcados de una base de datos y la realización de puntos de revisión de las memorias intermedias son dos procesos análogos. El procedimiento de volcado simple que se ha descrito anteriormente es costoso debido a las dos razones siguientes. En primer lugar, debe copiarse en almacenamiento estable la base de datos entera, lo

www.detodoprogramacion.com


17.8

Técnicas avanzadas de recuperación∗∗

585

que conlleva una considerable transferencia de datos. En segundo lugar, se pierden ciclos de CPU porque se detiene el procesamiento de transacciones durante el procedimiento de volcado. Se han desarrollado esquemas de volcado difuso que permiten que las transacciones sigan activas mientras se realiza el volcado. Son esquemas similares a los de los puntos de revisión difusos. Para obtener más detalles véanse las notas bibliográficas.

∗∗

17.8 Técnicas avanzadas de recuperación

Las técnicas de recuperación descritas en el Apartado 17.5 requieren que, una vez que una transacción modifica un elemento de datos, ninguna otra pueda modificar el mismo elemento de datos hasta que la primera se comprometa o retroceda. Utilizando el bloqueo estricto de dos fases se garantiza esa condición. Aunque el bloqueo estricto de dos fases es aceptable para los registros en las relaciones, como se vio en el Apartado 16.9, provoca un decremento significativo en la concurrencia cuando se aplica sobre determinadas estructuras, como las páginas indexadas con árboles B+ . Para incrementar la concurrencia puede usarse el algoritmo de control de concurrencia en árboles B+ descrito en el Apartado 16.9 y así permitir que los bloqueos se liberen rápidamente, no con el procedimiento de dos fases. Como consecuencia, sin embargo, no serán aplicables las técnicas de recuperación del Apartado 17.5. Se han propuesto varias técnicas de recuperación alternativas que pueden aplicarse incluso con bloqueos de liberación rápida. Estos esquemas se pueden usar en varias aplicaciones, no sólo para recuperar árboles B+ . En primer lugar se describe un esquema de recuperación avanzado que soporta los bloqueos de liberación rápida. A continuación se describe el esquema de recuperación ARIES, que se usa ampliamente en la industria. ARIES es más complejo que el esquema de recuperación avanzado descrito anteriormente, pero incorpora varias optimizaciones para minimizar el tiempo de recuperación, y proporciona varias características útiles. 17.8.1 Registro de deshacer lógico

En las operaciones donde los bloqueos son de liberación rápida no pueden realizarse las operaciones deshacer escribiendo simplemente el valor anterior de los elementos de datos. Considérese una transacción T que inserta una entrada en un árbol B+ y, siguiendo el protocolo de control de concurrencia con árboles B+ , libera algunos bloqueos después de completarse la operación inserción, pero antes de que la transacción se comprometa. Después de liberar los bloqueos, otras transacciones pueden realizar inserciones o borrados posteriores cambiando de este modo los nodos del árbol B+ . Incluso aunque la operación libere rápidamente algunos bloqueos debe conservar suficientes bloqueos como para garantizar que ninguna otra transacción tenga permiso para ejecutar cualquier operación conflictiva (como leer o borrar el valor insertado). Por este motivo, el protocolo de control de concurrencia con árboles B+ que se estudió anteriormente mantiene ciertos bloqueos en las hojas del árbol B+ hasta el final de la transacción. Considérese ahora cómo realizar retrocesos de transacciones. Si se usa una operación deshacer física, es decir, si durante el retroceso se escriben los valores anteriores de los nodos internos del árbol B+ (antes de ejecutar la operación inserción), podrían perderse algunas de las modificaciones realizadas por inserciones o borrados ejecutados posteriormente por otras transacciones. La operación inserción no debe deshacerse así, sino con una operación deshacer lógica, esto es, mediante la ejecución de una operación de borrado en este caso. Así, cuando finaliza la acción de inserción, antes de que libere ningún bloqueo, escribe en el registro histórico un registro <Ti , Oj , fin-operación, U >, donde D denota la información para deshacer y Oj es un identificador único de la operación. Por ejemplo, si la operación insertó una entrada en el árbol B+ , la información para deshacer D indicaría lo que habría que borrar del árbol B+ . Este registro histórico de información acerca de las operaciones se denomina registro histórico lógico. En cambio, el registro histórico de la información sobre el valor anterior y el nuevo valor se denomina registro histórico físico, y los correspondientes registros del registro histórico se llaman registros del registro histórico físico. Las operaciones de inserción y borrado son ejemplos de un tipo de operaciones que requiere operaciones deshacer lógicas ya que liberan rápidamente los bloqueos. Estas operaciones se denominan operaciones lógicas. Antes de que una operación lógica dé comienzo, escribe en el registro histórico un registro <Ti , Oj , inicio-operación>, donde Oj es el identificador único de la operación. Durante la

www.detodoprogramacion.com


586

Capítulo 17

Sistema de recuperación

ejecución de la operación se registran todas las modificaciones realizadas por la operación de forma normal. De esta manera se escribe para cada modificación la información habitual sobre el valor anterior y el nuevo valor. Al finalizar la operación se escribe en el registro histórico un registro de fin-operación como se describió anteriormente. 17.8.2 Retroceso de transacciones

Considérese primero el retroceso de transacciones durante el modo de operación normal (esto es, no durante la fase de recuperación). Se recorre el registro histórico hacia atrás y se usan los registros del registro histórico pertenecientes a la transacción para devolver a los elementos de datos sus valores anteriores. A diferencia del retroceso durante una operación normal, se escriben registros especiales sólo para la operación rehacer de la forma <Ti , Xj , V > que contienen el valor V con el que se ha restaurado el elemento de datos Xj durante el retroceso. Estos registros del registro histórico se denominan a veces registros de compensación del registro histórico. Estos registros no necesitan información para deshacer puesto nunca es necesario realizar esa operación. Se toman acciones especiales cuando se encuentra un registro del registro histórico de la forma <Ti , Oj , fin-operación, U >: 1. Se hace retroceder la operación mediante la información para deshacer D que se encuentra en el registro del registro histórico. Las modificaciones realizadas durante el retroceso de la operación se registran de la misma manera que las modificaciones realizadas cuando la operación se ejecutó por primera vez. En otras palabras, el sistema registra información de deshacer física para las actualizaciones realizadas durante el retroceso, en lugar de usar registros de compensación del registro histórico. Esto es debido a que puede ocurrir una caída mientras la operación deshacer lógica se encuentre en curso, y el sistema debe completar durante la recuperación la operación deshacer lógica, usando la información deshacer física, y después realizar de nueva la operación deshacer lógica, como se verá en el Apartado 17.8.4. Al final de la operación de retroceso, en lugar de generar un registro del registro histórico <Ti , Oj , fin-operación, U >, el sistema de bases de datos genera <Ti , Oj , abortar-operación>. 2. Cuando continúa el recorrido hacia atrás del registro histórico, el sistema omite todos los registros del registro histórico de la transacción hasta que encuentra el registro <Ti , Oj , inicio-operación>. Una vez que encuentra el registro inicio-operación en el registro histórico, el resto de registros referentes a la transacción se procesa de nuevo normalmente. Obsérvese que, durante el retroceso, la omisión de los registros del registro histórico físico cuando se encuentra el registro fin-operación asegura que los valores anteriores del registro no se usen para el retroceso una vez que termine la operación. Si el sistema encuentra un registro <Ti , Oj , abortar-operación>, omite todos los registros precedentes hasta que se encuentra el registro <Ti , Oj , inicio-operación>. Estos registros precedentes se deben omitir para evitar varios retrocesos de la misma operación en el caso de que haya una caída durante el retroceso anterior, y de que la transacción haya retrocedido parcialmente. Cuando la transacción Ti haya retrocedido, el sistema añadirá al registro <Ti abortada>. Si sucede un fallo mientras se está ejecutando una operación lógica, el registro fin-operación de la operación no se encontrará cuando la transacción retroceda. Sin embargo, para cada actualización realizada por la operación hay disponible en el registro histórico información para deshacer (como valor anterior en los registros del registro histórico físico). Los registros del registro histórico físico se usarán para hacer retroceder la operación incompleta. 17.8.3 Puntos de revisión

Los puntos de revisión se llevan a cabo como se describió en el Apartado 17.5. Se suspenden temporalmente las modificaciones sobre la base de datos y se llevan a cabo las siguientes acciones: 1. Se escriben en almacenamiento estable todos los registros del registro histórico que se encuentren en ese momento en la memoria principal.

www.detodoprogramacion.com


17.8

Técnicas avanzadas de recuperación∗∗

587

2. Se escriben en disco todos los bloques de la memoria intermedia que se hayan modificado. 3. Se escribe en almacenamiento estable el registro <revisión L>, donde L es una lista de todas las transacciones activas. 17.8.4 Recuperación al reiniciar

Las acciones de recuperación se realizan en dos fases cuando se vuelve a iniciar el sistema de base de datos después de un fallo: 1. En la fase rehacer se vuelven a realizar modificaciones de todas las transacciones mediante la exploración hacia delante del registro histórico a partir del último punto de revisión. Los registros del registro histórico que se vuelven a ejecutar incluyen los registros de transacciones que retrocedieron antes de la caída del sistema y de las que no se habían comprometido cuando ocurrió la caída. Los registros del registro histórico son los registros habituales de la forma <Ti , Xj , V1 , V2 >, así como los registros especiales del registro histórico de la forma <Ti , Xj , V2 >; el elemento de datos Xj adquiere el valor V2 en cualquier caso. Esta fase también determina todas las transacciones que o bien se encuentran en la lista de transacciones del registro del punto de revisión, o bien comenzaron más tarde, pero no tienen ni el registro <Ti abortada> ni el registro <Ti comprometida> en el registro histórico. Todas estas transacciones deben retrocederse y sus identificadores de transacción se ponen en una lista-deshacer. 2. En la fase deshacer retroceden todas las transacciones de la lista-deshacer. El retroceso se realiza recorriendo el registro histórico hacia atrás empezando por el final. Cuando se encuentra un registro del registro histórico perteneciente a una transacción de la lista-deshacer se realizan las operaciones para deshacer de la misma manera que si el registro se hubiera encontrado durante el retroceso de una transacción fallida. Así pues, se ignoran los registros del registro histórico de una transacción que preceden a un registro fin-operación, pero que se encuentran detrás del correspondiente registro inicio-operación. Cuando se encuentra en el registro histórico un registro <Ti iniciada> para una transacción Ti de la lista-deshacer, se escribe en el registro histórico un registro <Ti abortada>. El recorrido hacia atrás del registro histórico finaliza cuando se encuentran los registros <Ti iniciada> para todas las transacciones de la lista-deshacer. La fase rehacer de la recuperación al reiniciar reproduce cada registro físico del registro histórico desde que tuvo lugar el último punto de revisión. En otras palabras, esta fase de la recuperación al reiniciar repite todas las acciones de modificación que fueron ejecutadas después del punto de revisión y cuyos registros alcanzaron un registro histórico estable. Se incluyen aquí las acciones de transacciones incompletas y las acciones llevadas a cabo para retroceder transacciones fallidas. Las acciones se repiten en el mismo orden en el que se llevaron a cabo; de aquí que este proceso se denomine repetición de la historia. Al repetir la historia se simplifican bastante los esquemas de recuperación. Obsérvese que si una operación deshacer estaba en curso cuando ocurrió la caída del sistema, se encontrarían los registros del registro histórico físico escritos durante la operación deshacer, y la operación deshacer parcial se desharía según estos registros del registro histórico físico. Después de ello, el registro fin-operación de la operación original se encontraría durante la recuperación, y la operación deshacer se ejecutaría de nuevo. 17.8.5 Revisión difusa

La revisión difusa descrita en el Apartado 17.5.3 requiere que, mientras se efectúa el punto de revisión, se suspendan temporalmente todas las modificaciones de la base de datos. Si el número de páginas de la memoria intermedia es grande, un punto de revisión puede llevar mucho tiempo, lo que puede provocar una interrupción inaceptable en el procesamiento de transacciones. Para evitar estas interrupciones es posible modificar la técnica para permitir modificaciones después de haber escrito en el registro histórico el registro revisión, pero antes de escribir en disco los bloques

www.detodoprogramacion.com


588

Capítulo 17

Sistema de recuperación

de la memoria intermedia que han sufrido modificaciones. El punto de revisión así generado recibe el nombre de punto de revisión difuso. Dado que las páginas se escriben en disco sólo después de que se haya escrito el registro revisión, es posible que el sistema caiga antes de que todas las páginas se hayan escrito. Por tanto, los puntos de revisión en disco pueden estar incompletos. Una forma de manejar los puntos de revisión incompletas es la siguiente. La ubicación del registro de revisión en el registro histórico del último punto de revisión completado se almacena en una posición fijada, última-revisión, en disco. El sistema no actualiza esta información cuando escribe el registro revisión. En su lugar, antes de escribirlo, crea una lista de todos los bloques de memoria intermedia modificados. La información de última-revisión se actualiza sólo cuando todos los bloques de memoria intermedia de la lista de bloques modificados se hayan escrito en disco. Incluso con la revisión difusa, un bloque de memoria intermedia no se debe actualizar mientras se esté escribiendo en disco, aunque otros bloques sí se pueden actualizar concurrentemente. Una vez que todos los bloques han sido escritos en disco debe seguirse el protocolo de registro histórico de escritura anticipada. Obsérvese que en este esquema sólo se utiliza el proceso de registro histórico lógico para deshacer mientras que el proceso de registro histórico físico se usa tanto para deshacer como para rehacer. Existen otros esquemas de recuperación que utilizan el proceso de registro histórico lógico para rehacer. Para deshacer lógicamente, el estado de la base de datos en disco debe ser consistente en cuanto a operaciones, es decir, no debería tener efectos parciales de ninguna operación. Es difícil garantizar esta consistencia de la base de datos en disco si una operación puede afectar a más de una página, puesto que no es posible escribir más de una página de forma atómica. Por tanto, el registro histórico deshacer lógico se restringe usualmente sólo a operaciones que afectan a una única página. Se verá la forma de tratar estas operaciones rehacer lógicas en el Apartado 17.8.6. En cambio, las operaciones deshacer lógicas se realizan sobre un estado consistente en cuanto a operaciones de la base de datos repitiendo la historia y después realizando la operación deshacer física de las operaciones completadas parcialmente.

17.8.6 ARIES

El método de recuperación ARIES es un representante de los métodos actuales de recuperación. La técnica de recuperación avanzada que se ha descrito se ha modelado después de ARIES, pero se ha simplificado significativamente para ilustrar los conceptos clave y hacerlo más fácil de comprender. En cambio, ARIES utiliza varias técnicas para reducir el tiempo de recuperación y para reducir la sobrecarga de los puntos de revisión. En particular, ARIES es capaz de evitar rehacer muchas operaciones registradas que ya se han realizado y de reducir la cantidad de información registrada. El precio pagado supone una mayor complejidad, pero los beneficios merecen la pena. Las diferencias principales entre ARIES y el algoritmo de recuperación avanzada expuesto son que ARIES: 1. Usa un número de secuencia del registro histórico (NSR) para identificar a los registros del registro histórico, y emplea esos números en las páginas de la base de datos para identificar las operaciones que se han realizado sobre una página de la base de datos. 2. Soporta operaciones rehacer fisiológicas, que son físicas en el sentido en que la página afectada está físicamente identificada, pero que pueden ser lógicas en la página. Por ejemplo, el borrado de un registro de una página puede provocar que muchos otros registros de la página se desplacen si se usa una estructura de páginas con ranuras. Con el registro histórico rehacer físico, hay que registrar todos los bytes de la página afectada por el desplazamiento de los registros. Con el registro histórico fisiológico, la operación borrado se puede registrar, lo que da lugar a un registro mucho más pequeño. Al rehacer la operación borrado se borraría el registro y se desplazarían los registros que hiciera falta. 3. Emplea una tabla de páginas desfasadas para minimizar las operaciones rehacer innecesarias durante la recuperación. Las páginas desfasadas son las que se han actualizado en memoria pero no en su versión en disco.

www.detodoprogramacion.com


17.8

Técnicas avanzadas de recuperación∗∗

589

4. Utiliza un esquema de revisión difusa que sólo registra información sobre las páginas desfasadas e información asociada, y no requiere siquiera la escritura de las páginas desfasadas a disco. Procesa las páginas desfasadas en segundo plano continuamente, en lugar de escribirlas durante los puntos de revisión. En el resto de este apartado se proporciona una visión general de ARIES. Las notas bibliográficas incluyen referencias que proporcionan una descripción completa de ARIES.

17.8.6.1 Estructuras de datos

Cada registro del registro histórico de ARIES tiene un número de secuencia del registro histórico (NSR) que lo identifica unívocamente. El número es conceptualmente tan sólo un identificador lógico cuyo valor es mayor para los registros que aparecen después en el registro histórico. En la práctica, el NSR se genera de forma que también se puede usar para localizar el registro del registro histórico en disco. Normalmente, ARIES divide el registro histórico en varios archivos de registro histórico, cada uno con un número de archivo. Cuando un archivo crece hasta un determinado límite, ARIES añade los nuevos registros del registro histórico en un nuevo archivo; el nuevo archivo de registro histórico tiene un número de archivo que es 1 mayor que el anterior archivo. El NSR consiste en un número de archivo y un desplazamiento dentro del archivo. Cada página también mantiene un identificador denominado NSRPágina. Cada vez que se aplica una operación (física o lógica) en la página, la operación almacena el NSR de su registro en el campo NSRPágina de la página. Durante la fase rehacer de la recuperación cualquier registro con un NSR menor o igual que el NSRPágina de la página no se debería ejecutar, ya que sus acciones ya están reflejadas en la página. En combinación con un esquema para el registro de los NSRPágina como parte de los puntos de revisión, que se presenta más adelante, ARIES puede evitar incluso leer muchas páginas cuyas operaciones registradas ya se han reflejado en el disco. Por tanto, el tiempo de recuperación se reduce significativamente. El NSRPágina es esencial para asegurar la idempotencia en presencia de operaciones rehacer fisiológicas, ya que volver a aplicar una operación rehacer fisiológica que ya se haya aplicado a una página podría causar cambios incorrectos en una página. Las páginas no se deberían enviar a disco mientras se esté realizando una actualización, dado que las operaciones fisiológicas no se pueden rehacer sobre el estado parcialmente actualizado de la página en disco. Por tanto, ARIES usa pestillos sobre las páginas de la memoria intermedia para evitar que se escriban en disco mientras se actualicen. Los pestillos de las páginas de la memoria intermedia sólo se liberan cuando se completan las actualizaciones, y el registro del registro histórico para la actualización se haya escrito en el registro histórico. Cada registro del registro histórico también contiene el NSR del registro anterior de la misma transacción. Este valor, almacenado en el campo NSRAnterior, permite que se encuentren los registros del registro histórico anteriores sin necesidad de leer el registro histórico completo. En ARIES hay registros especiales sólo-rehacer generados durante el retroceso de transacciones, denominados registros de compensación del registro histórico (RCR). Los RCR tienen un campo extra denominado DeshacerSiguienteNSR, que registra el NSR del registro que hay que deshacer a continuación cuando la transacción retrocede. Este campo sirve para el mismo propósito que el identificador de operaciones en el registro abortar-operación del esquema anterior, que ayuda a omitir los registros que ya hayan retrocedido. La TablaPáginasDesfasadas contiene una lista de páginas que se han actualizado en la memoria intermedia de la base de datos. Para cada página se almacena el NSRPágina y un campo denominado RegNSR que ayuda a identificar los registros que ya se han aplicado a la versión en disco de la página. Cuando se inserta una página en la TablaPáginasDesfasadas (cuando se modifica por primera vez en el grupo de memorias intermedias) el valor de RegNSR se establece en el fin actual del registro histórico. Cada vez que se envía una página a disco, la página se elimina de la TablaPáginasDesfasadas. El registro punto de revisión del registro histórico contiene la TablaPáginasDesfasadas y una lista de transacciones activas. Para cada transacción, el registro punto de revisión del registro histórico también anota ÚltimoNSR, el NSR del último registro escrito por la transacción. Una posición fijada en disco también anota el NSR del último registro punto de revisión del registro histórico (completado).

www.detodoprogramacion.com


590

Capítulo 17

Sistema de recuperación

17.8.6.2 Algoritmo de recuperación

ARIES recupera de una caída del sistema en tres fases:

• Paso de análisis. Este paso determina las transacciones que hay que deshacer, las páginas que están desfasadas en el momento de la caída y el NSR en el que debería comenzar el paso rehacer. • Paso rehacer. Este paso comienza en una posición determinada durante el análisis y realiza una operación rehacer, repitiendo la historia, para llevar a la base de datos al estado anterior a la caída. • Paso deshacer. Este paso hace retroceder todas las transacciones incompletas en el momento de la caída. Paso de análisis. El paso de análisis busca el último registro punto de revisión completado del registro histórico y lee la TablaPáginasDesfasadas en este registro. A continuación establece RehacerNSR al mínimo RegistroNSR de las páginas de TablaPáginasDesfasadas. Si no hay páginas desfasadas, establece RehacerNSR al NSR del registro punto de revisión del registro histórico. El paso rehacer comienza explorando el registro histórico desde RehacerNSR. Todos los registros anteriores a este punto ya se han aplicado a las páginas de la base de datos en el disco. El paso de análisis establece inicialmente la lista de transacciones que se deben deshacer, lista-deshacer, a la lista de transacciones en el registro punto de revisión del registro histórico. El paso de análisis también lee del registro punto de revisión del registro histórico los NSR del último registro del registro histórico de cada transacción de las lista-deshacer. El paso de análisis continúa examinando hacia delante desde el punto de revisión. Cada vez que encuentra un registro de una transacción que no esté en la lista-deshacer, añade la transacción a la lista-deshacer. Cada vez que encuentra un registro de fin de transacción, borra la transacción de la listadeshacer. Todas las transacciones que queden en la lista-deshacer al final del análisis se deben hacer retroceder más tarde en el paso deshacer. El paso de análisis también almacena el último registro de cada transacción en la lista-deshacer, que se usa en el paso deshacer. El paso de análisis también actualiza TablaPáginasDesfasadas cada vez que encuentra un registro del registro histórico de la actualización de una página. Si la página no está en la TablaPáginasDesfasadas, el paso de análisis la añade a ella y establece el RegistroNSR de la página al NSR del registro. Paso rehacer. El paso rehacer repite la historia volviendo a ejecutar cada acción sobre una página que no se haya reflejado en disco. El paso rehacer examina el registro histórico hacia delante a partir de RehacerNSR. Cada vez que encuentra un registro actualizar realiza: 1. Si la página no está en la TablaPáginasDesfasadas o el NSR del registro actualizar es menor que el RegistroNSR de la página de TablaPáginasDesfasadas, entonces el paso rehacer omite el registro. 2. En caso contrario, el paso rehacer extrae la página de disco y, si NSRPágina es menor que el NSR del registro, se rehace el registro. Obsérvese que si cualquiera de las comprobaciones son negativas, entonces los efectos del registro del registro histórico ya han aparecido en la página. Si la primera comprobación es negativa, ni siquiera es necesario extraer la página de disco. Paso deshacer y retroceso de transacciones. El paso deshacer es relativamente simple. Realiza una exploración hacia atrás del registro histórico, deshaciendo todas las transacciones de la lista-deshacer. Si se encuentra un RCR, usa el campo DeshacerSiguienteNSR para omitir los registros que ya se hayan retrocedido. En caso contrario, usa el campo NSRAnterior del registro para encontrar el siguiente a deshacer. Cada vez que se usa un registro del registro histórico para realizar una operación deshacer (para el retroceso de transacciones durante el procesamiento normal del retroceso o durante el reinicio del paso deshacer) el paso deshacer genera un RCR que contiene la acción deshacer realizada (que debe ser fisiológica). Establece DeshacerSiguienteNSR del RCR al valor NSRAnterior del registro actualizar del registro histórico.

www.detodoprogramacion.com


17.9

Sistemas remotos de copias de seguridad

591

17.8.6.3 Otras características

Algunas de las características que proporciona ARIES son: • Independencia de recuperación. Algunas páginas se pueden recuperar independientemente de otras, de forma que se pueden usar incluso cuando se estén recuperando otras. Si fallan algunas páginas del disco se pueden recuperara sin parar el procesamiento de transacciones en otras páginas. • Puntos de almacenamiento. Las transacciones pueden registrar puntos de almacenamiento y pueden retroceder parcialmente hasta un punto de almacenamiento. Esto puede ser muy útil en el manejo de interbloqueos, dado que las transacciones pueden retroceder hasta un punto que permita la liberación de los bloqueos requeridos y luego reiniciarse desde ese punto. • Bloqueo de grano fino. El algoritmo de recuperación ARIES se puede usar con algoritmos de control de concurrencia de índices que permiten el bloqueo en el nivel de tuplas de los índices, en lugar del bloqueo en el nivel de las páginas, lo que aumenta significativamente la concurrencia. • Optimizaciones de la recuperación. La TablaPáginasDesfasadas se puede usar para preextraer páginas durante la operación rehacer, en lugar de extraer una página sólo cuando el sistema encuentra un registro del registro histórico a aplicar a la página. La operación rehacer-no-válidos también es posible. Esta operación se puede posponer sobre una página que se vaya a extraer del disco y realizarse cuando se extraiga. Mientras tanto se pueden seguir procesando otros registros. En resumen, el algoritmo ARIES es un algoritmo de recuperación actual que incorpora varias optimizaciones diseñadas para mejorar la concurrencia, reducir la sobrecarga por el registro histórico y reducir el tiempo de recuperación. 17.9 Sistemas remotos de copias de seguridad

Los sistemas tradicionales de procesamiento de transacciones son sistemas centralizados o sistemas cliente-servidor. Esos sistemas son vulnerables frente a desastres ambientales como el fuego, las inundaciones o los terremotos. Hay una necesidad creciente de sistemas de procesamiento de transacciones que ofrezcan una disponibilidad elevada y que puedan funcionar pese a los desastres ambientales. Estos sistemas deben proporcionar una disponibilidad elevada, es decir, el tiempo en que el sistema no es utilizable debe ser extremadamente pequeño. Se puede obtener una disponibilidad elevada realizando el procesamiento de transacciones en un solo sitio, denominado sitio principal, pero tener un sitio remoto copia de seguridad, en el que se repliquen todos los datos del sitio principal. El sitio remoto copia de seguridad se denomina también a veces sitio secundario. El sitio remoto debe mantenerse sincronizado con el sitio principal, ya que las actualizaciones se realizan en el sitio principal. La sincronización se obtiene enviando todos los registros del registro histórico desde el sitio principal al sitio remoto de copia de seguridad. El sitio remoto copia de seguridad debe hallarse físicamente separado del principal—por ejemplo, se puede ubicar en otra provincia— para que una catástrofe en el sitio principal no afecte al sitio remoto copia de seguridad. En la Figura 17.8 se muestra la arquitectura de los sistemas remotos para copias de seguridad. Cuando falla el sitio principal, el sitio remoto de copia de seguridad asume el procesamiento. En primer lugar, sin embargo, lleva a cabo la recuperación utilizando su copia (tal vez anticuada) de los datos del sitio principal y de los registros del registro histórico recibidos del mismo. En realidad, el sitio remoto copia de seguridad lleva a cabo acciones de recuperación que se hubieran llevado a cabo en el sitio principal cuando éste se hubiera recuperado. Se pueden utilizar los algoritmos estándar de recuperación para la recuperación en el sitio remoto copia de seguridad con pocas modificaciones. Una vez realizada la recuperación, el sitio remoto copia de seguridad comienza a procesar transacciones. La disponibilidad aumenta mucho en comparación con los sistemas con un solo sitio, dado que el sistema puede recuperarse aunque se pierdan todos los datos del sitio principal. El rendimiento de los sistemas remotos para copias de seguridad es mejor que el de los sistemas distribuidos con compromiso de dos fases.

www.detodoprogramacion.com


592

Capítulo 17

Sistema de recuperación

principal

red

copia de seguridad

registros del registro histórico Figura 17.8

Arquitectura de los sistemas remotos de copias de seguridad.

Se deben abordar varios aspectos al diseñar sistemas remotos para copias de seguridad, tales como: • Detección de fallos. Al igual que en los protocolos para el manejo de fallos en sistemas distribuidos, es importante que el sistema remoto de copia de seguridad detecte que el sitio principal ha fallado. El fallo de las líneas de comunicación puede hacer creer al sitio remoto de copia de seguridad que el sitio principal ha fallado. Para evitar este problema hay que mantener varios enlaces de comunicaciones con modos de fallo independientes entre el sitio principal y el sitio remoto copia de seguridad. Por ejemplo, además de la conexión de red puede haber otra conexión mediante módem por línea telefónica con servicio suministrado por diferentes compañías de telecomunicaciones. Estas conexiones pueden complementarse con la intervención manual de operadores, que se pueden comunicar por vía telefónica. • Transferencia del control. Cuando el sitio principal falla, el sitio de copia de seguridad asume el procesamiento y se transforma en el nuevo sitio principal. Cuando el sitio principal original se recupera puede desempeñar el papel de sitio remoto de copia de seguridad o volver a asumir el papel de sitio principal. En cualquiera de los casos, el sitio principal antiguo debe recibir un registro histórico de actualizaciones realizado por el sitio de copia de seguridad mientras el sitio principal antiguo estaba fuera de servicio. La manera más sencilla de transferir el control es que el sitio principal antiguo reciba el registro histórico de operaciones rehacer del sitio de copia de seguridad antiguo y se ponga al día con las actualizaciones aplicándolas de manera local. El sitio principal antiguo puede entonces actuar como sitio remoto de copia de seguridad. Si hay que devolver el control, el sitio remoto copia de seguridad antiguo puede simular que ha fallado, lo que da lugar a que el sitio principal antiguo asuma el control. • Tiempo de recuperación. Si el registro histórico del sitio remoto de copia de seguridad se hace grande, la recuperación puede tardar mucho. El sitio remoto copia de seguridad puede procesar de manera periódica los registros rehacer del registro histórico que haya recibido y realizar un punto de revisión, de manera que se puedan borrar las partes más antiguas del registro histórico. Como consecuencia se puede reducir el retraso antes de que el sitio remoto de copia de seguridad asuma el control. Una configuración de relevo en caliente puede hacer la toma del control por el sitio de copia de seguridad casi instantáneo. En esta configuración el sitio remoto copia de seguridad procesa los registros rehacer del registro histórico según llegan, y aplica las actualizaciones de manera local. Tan pronto como se detecta el fallo del sitio principal, el sitio de copia de seguridad completa la recuperación haciendo retroceder las transacciones incompletas y queda preparado para procesar las nuevas. • Tiempo de compromiso. Para asegurar que las actualizaciones de una transacción comprometida sean duraderas no se debe declarar comprometida una transacción hasta que sus registros del registro histórico hayan alcanzado el sitio de copia de seguridad. Este retraso puede dar lugar a una espera más prolongada para comprometer la transacción y, en consecuencia, algunos sistemas permiten grados inferiores de durabilidad. Los grados de durabilidad pueden clasificarse de la manera siguiente.

www.detodoprogramacion.com


17.10

Resumen

593

¤ Uno seguro. Las transacciones se comprometen tan pronto como sus registros de compromiso del registro histórico se escriben en un almacenamiento estable en el sitio principal. El problema de este esquema es que puede que las actualizaciones de una transacción comprometida no hayan alcanzado el sitio de copia de seguridad cuando éste asuma el control del procesamiento. Por tanto, puede parecer que las actualizaciones se han perdido. Cuando se recupera el sitio principal, las actualizaciones perdidas no se pueden mezclar directamente, dado que pueden entrar en conflicto con actualizaciones posteriores llevadas a cabo en el sitio de copia de seguridad. Por tanto, puede que se necesite la intervención humana para devolver a la base de datos a un estado consistente. ¤ Dos muy seguro. Las transacciones se comprometen tan pronto como sus registros de compromiso del registro histórico se escriben en un almacenamiento estable en el sitio principal y en el sitio de copia de seguridad. El problema de este esquema es que el procesamiento de transacciones no puede continuar si alguno de los puntos no está operativo. Por tanto, la disponibilidad es realmente menor que en el caso de un solo sitio, aunque la posibilidad de la pérdida de datos es mucho más reducida. ¤ Dos seguro. Este esquema es idéntico al esquema dos muy seguro si tanto el sitio principal como el sitio de copia de seguridad están activos. Si sólo está activo el sitio principal se permite que la transacción se comprometa tan pronto como su registro de compromiso del registro histórico se escriba en un almacenamiento estable en el sitio principal. Este esquema proporciona mejor disponibilidad que el esquema dos muy seguro, al tiempo que evita el problema de las transacciones perdidas afrontado por el esquema uno seguro. Da lugar a un compromiso más lento que el esquema uno seguro pero las ventajas generalmente superan los inconvenientes. Varios sistemas comerciales de disco compartido proporcionan un nivel de tolerancia de fallos intermedio entre el de los sistemas centralizados y el de los sistemas remotos para copias de seguridad. En estos sistemas el fallo de una CPU no da lugar al fallo del sistema. En lugar de ello, otra CPU asume el control y lleva a cabo la recuperación. Las acciones de recuperación incluyen el retroceso de las transacciones que se ejecutaban en la CPU que falló y la recuperación de los bloqueos mantenidos por dichas transacciones. Dado que los datos se hallan en un disco compartido, no hace falta transferir registros del registro histórico. Sin embargo, se deberían proteger los datos contra el fallo del disco utilizando, por ejemplo, una organización de discos RAID. Una forma alternativa de conseguir alta disponibilidad es usar una base de datos distribuida con los datos replicados en más de un sitio. Son necesarias transacciones para actualizar todas las réplicas de cualquier elemento de datos que actualicen. Las bases de datos distribuidas, incluyendo la réplica, se estudian en el Capítulo 22. 17.10 Resumen

• Los sistemas informáticos, al igual que cualquier otro dispositivo eléctrico o mecánico, están sujetos a fallos. Estos fallos se producen por diferentes motivos incluyendo fallos de disco, cortes de corriente o fallos en el software. En cada uno de estos casos puede perderse información concerniente a la base de datos. • Las transacciones pueden fallar, además de por un fallo del sistema, por otras razones como una violación de las restricciones de integridad o interbloqueos. • El esquema de recuperación es una parte integrante del sistema de base de datos el cual es responsable de la detección de fallos y del restablecimiento de un estado de la base datos anterior al momento de producirse el fallo. • Los diferentes tipos de almacenamiento en una computadora son el volátil, el no volátil y el almacenamiento estable. Los datos del almacenamiento volátil, como ocurre con los guardados en la memoria RAM, se pierden cuando la computadora cae. Los datos del almacenamiento no volátil, como los guardados en un disco, no se pierden cuando la computadora cae, pero pueden

www.detodoprogramacion.com


594

Capítulo 17

Sistema de recuperación

perderse ocasionalmente debido a fallos de disco. Los datos del almacenamiento estable nunca se pierden. • El almacenamiento estable de acceso en tiempo real puede aproximarse con discos con imagen u otras formas de RAID que proporcionan almacenamiento redundante de datos. El almacenamiento estable, sin conexión o de archivo, puede consistir en una serie de copias en cinta de los datos guardadas en un lugar físicamente seguro. • El estado del sistema de base de datos puede no volver a ser consistente en caso de ocurrir un fallo; esto es, puede no reflejar un estado del mundo potencialmente alcanzable por la base de datos. Para preservar la consistencia es necesario que cada transacción sea atómica. Garantizar la propiedad de atomicidad es responsabilidad del esquema de recuperación. • En los esquemas basados en registro histórico todas las modificaciones se escriben en el registro histórico, el cual debe estar guardado en almacenamiento estable. ¤ En el esquema de modificación diferida, durante la ejecución de una transacción, se difieren todas las operaciones escribir hasta que la transacción se compromete parcialmente, momento en el que se utiliza la información del registro histórico asociada con la transacción para ejecutar las escrituras diferidas. ¤ Con la técnica de modificación inmediata, todas las modificaciones se aplican directamente sobre la base de datos. Si ocurre una caída se utiliza la información del registro histórico para conducir a la base de datos a un estado consistente previo. Puede usarse la técnica de los puntos de revisión para reducir la sobrecarga que conlleva la búsqueda en el registro histórico y rehacer las transacciones. • El procesamiento de transacciones se basa en un modelo de almacenamiento en el que la memoria principal contiene una memoria intermedia para el registro histórico, una memoria intermedia para la base de datos y una memoria intermedia para el sistema. La memoria intermedia del sistema alberga páginas de código objeto del sistema y áreas de trabajo local de las transacciones. • Una implementación eficiente de un esquema de recuperación de datos requiere que el número de escrituras en la base de datos y en almacenamiento estable sea mínimo. Los registros del registro histórico pueden guardarse inicialmente en la memoria intermedia del registro histórico en almacenamiento volátil, pero se deben copiar en almacenamiento estable cuando se da una de estas dos condiciones: ¤ Deben escribirse en almacenamiento estable todos los registros del registro histórico pertenecientes a la transacción Ti antes de que el registro <Ti comprometida> se pueda escribir en almacenamiento estable. ¤ Deben escribirse en almacenamiento estable todos los registros del registro histórico pertenecientes a los datos de un bloque antes de que ese bloque de datos se escriba desde la memoria principal a la base de datos (en almacenamiento no volátil). • Para recuperarse de los fallos que resultan en la pérdida de almacenamiento no volátil debe realizarse un volcado periódicamente (por ejemplo, una vez al día) del contenido entero de la base de datos en almacenamiento estable. Se usará el último volcado para devolver a la base de datos a un estado consistente previo cuando ocurra un fallo que conduzca a la pérdida de algún bloque físico de la base de datos. Una vez realizada esta operación se utilizará el registro histórico para llevar a la base de datos al estado consistente más reciente. • Se han desarrollado técnicas avanzadas de recuperación para soportar técnicas de bloqueo de alta concurrencia, como las utilizadas para el control de concurrencia con árboles B+ . Estas técnicas se basan en el registro deshacer lógico y siguen el principio de repetir la historia. En la recuperación de un fallo del sistema se realiza una fase rehacer utilizando el registro histórico, seguida de una fase deshacer sobre el registro histórico para retroceder las transacciones incompletas. • El esquema de recuperación ARIES es un esquema actual que soporta varias características para proporcionar mayor concurrencia, reducir la sobrecarga del registro histórico y permitir opera-

www.detodoprogramacion.com


Términos de repaso

595

ciones deshacer lógicas. El esquema procesa páginas continuamente y no necesita procesar todas las páginas en el momento de un punto de revisión. Usa números de secuencia del registro histórico (NSR) para implementar varias optimizaciones que reducen el tiempo de recuperación. • Los sistemas remotos de copia de seguridad proporcionan un alto nivel de disponibilidad, permitiendo que continúe el procesamiento de transacciones incluso si se destruye el sitio primario por fuego, inundación o terremoto. Términos de repaso

• Esquema de recuperación.

• Memoria intermedia de la base de datos.

• Clasificación de los fallos: ¤ Fallo de transacción. ¤ Error lógico. ¤ Error del sistema. ¤ Caída del sistema. ¤ Fallo de transferencia de datos.

• Pestillos.

• Supuesto de fallo-parada.

• Volcado difuso.

• Fallo de disco.

• Técnica de recuperación avanzada.

• Sistema operativo y gestión de la memoria intermedia. • Pérdida del almacenamiento no volátil. • Volcado de archivo.

¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤

• Tipos de almacenamiento: ¤ Volátil ¤ No volátil ¤ Estable • Bloques: ¤ Físicos. ¤ De memoria intermedia. • Memoria intermedia de disco. • Escritura forzada.

Operación deshacer física. Operación deshacer lógica. Registro histórico físico. Registro histórico lógico. Operaciones lógicas. Retroceso de transacciones. Puntos de revisión. Recuperación al reiniciar. Fase rehacer. Fase deshacer.

• Recuperación basada en el registro histórico.

• Repetición de la historia.

• Registro histórico.

• ARIES

• Puntos de revisión difusos.

• Registros del registro histórico.

¤ Número de secuencia del registro histórico (NSR). ¤ NSRPágina. ¤ Operación rehacer fisiológica. ¤ Registros de compensación del registro histórico (RCR). ¤ TablaPáginasDesfasadas. ¤ Registro punto de revisión.

• Registro actualizar del registro histórico. • Modificación diferida. • Idempotente. • Modificación inmediata. • Modificaciones no comprometidas. • Puntos de revisión.

• Alta disponibilidad.

• Recogida de basura. • Recuperación con transacciones concurrentes. ¤ Retroceso de transacciones. ¤ Puntos de revisión difusos. ¤ Recuperación al reiniciar. • Gestión de la memoria intermedia.

• Sistemas remotos de copia de seguridad. ¤ Sitio principal. ¤ Sitio remoto de copia de seguridad. ¤ Sitio secundario. • Detección de fallos. • Transferencia del control.

• Registro histórico con memoria intermedia.

• Tiempo de recuperación.

• Registro de escritura anticipada (REA).

• Configuración de relevo en caliente.

• Forzar el registro histórico.

• Tiempo de compromiso.

www.detodoprogramacion.com


596

Capítulo 17

Sistema de recuperación

¤ Uno seguro. ¤ Dos muy seguro.

¤ Dos seguro.

Ejercicios prácticos

17.1 Compárense, en términos de facilidad de implementación y de sobrecarga, las versiones de modificación inmediata y modificación diferida de las técnicas de recuperación basadas en registro histórico. 17.2 Cuando el sistema se recupera después de una caída (véase el Apartado 17.5.4) construye una lista-deshacer y una lista-rehacer. Explíquese por qué deben procesarse en orden inverso los registros del registro histórico de las transacciones que se encuentran en la lista-deshacer, mientras que los registros del registro histórico correspondientes a las transacciones de la lista-rehacer se procesan hacia delante. 17.3 Explíquense las razones por las que la recuperación en transacciones interactivas es más difícil de tratar que la recuperación en transacciones por lotes. ¿Existe alguna forma sencilla de tratar esta dificultad? Sugerencia: considérese una transacción de un cajero automático por la que se retira dinero. 17.4 A veces hay que deshacer una transacción después de que se haya comprometido porque se ejecutó erróneamente, debido por ejemplo a la introducción incorrecta de datos de un cajero. a. Dese un ejemplo para demostrar que el uso de un mecanismo normal para deshacer esta transacción podría conducir a un estado inconsistente. b. Una forma de manejar esta situación es llevar la base de datos a un estado anterior al compromiso de la transacción errónea (denominado recuperación a un instante). En este esquema se deshacen los efectos de las transacciones comprometidas después. Sugiérase una modificación del mecanismo de recuperación avanzada para implementar la recuperación a un instante. c. Las transacciones correctas se pueden volver a ejecutar lógicamente, pero no se pueden reejecutar usando sus registros del registro histórico. ¿Por qué? 17.5 En los lenguajes de programación persistentes no se realiza explícitamente el registro histórico de las modificaciones. Descríbase cómo pueden usarse las protecciones de acceso a las páginas que proporcionan los sistemas operativos modernos para crear imágenes anteriores y posteriores de las páginas que son modificadas. Sugerencia: véase el Ejercicio práctico 16.9. 17.6 ARIES da por supuesto que hay espacio en cada página para un NSR. Al manejar objetos grandes que abarcan varias páginas, tales como archivos del sistema operativo, un objeto puede usar una página completa, sin dejar espacio para el NSR. Sugiérase una técnica para manejar esta situación; esta técnica debe soportar operaciones rehacer físicas pero no es necesario que soporte operaciones rehacer fisiológicas. Ejercicios

17.7 Explíquese la diferencia en cuanto al coste E/S entre los tres tipos de almacenamiento—volátil, no volátil y estable. 17.8 El almacenamiento estable no se puede implementar. a. Explíquese el motivo. b. Explíquese cómo tratan este problema los sistemas de las bases de datos. 17.9 Supóngase que un sistema utiliza modificación inmediata. Demuéstrese con un ejemplo cómo podría darse un estado inconsistente en la base de datos si no se escriben en almacenamiento estable los registros del registro histórico de una transacción antes de que el dato actualizado por la transacción se escriba a disco.

www.detodoprogramacion.com


Notas bibliográficas

597

17.10 Explíquese el propósito del mecanismo de los puntos de revisión. ¿Con qué frecuencia deberían realizarse los puntos de revisión? Explíquese cómo afecta la frecuencia de los puntos de revisión: • Al rendimiento del sistema cuando no ocurre ningún fallo. • Al tiempo que se tarda para recuperarse de una caída del sistema. • Al tiempo que se tarda para recuperarse de una caída del disco. 17.11 Explíquese cómo el gestor de la memoria intermedia puede conducir a la base de datos a un estado inconsistente si algunos registros del registro histórico pertenecientes a un bloque no se escriben en almacenamiento estable antes de escribir en el disco el citado bloque. 17.12 Explíquese las ventajas del registro histórico lógico. Proporciónense ejemplos de una situación en la que sea preferible el registro histórico lógico frente al registro histórico físico y de lo contrario. 17.13 Explíquese la diferencia entre una caída del sistema y un “desastre”. 17.14 Para cada uno de los siguientes requisitos identifíquese la mejor opción del grado de durabilidad en un sistema remoto de copia de seguridad. a. Pérdida de datos que se debe evitar pero se puede tolerar alguna pérdida de disponibilidad. b. El compromiso de transacciones se debe realizar rápidamente, incluso perdiendo algunas transacciones comprometidas en caso de desastre. c. Se requiere un alto grado de disponibilidad y durabilidad, pero es aceptable un mayor tiempo de ejecución para el protocolo de compromiso de transacciones. 17.15 Las aplicaciones del sistema de bases de datos de Oracle deshacen los registros del registro histórico para proporcionar una vista instantánea de la base de datos a las transacciones de sólo lectura. La vista instantánea refleja las actualizaciones de todas las transacciones comprometidas cuando comenzó la transacción de sólo lectura; las actualizaciones del resto de transacciones no son visibles para la transacción de sólo lectura. Descríbase un esquema para el gestor de memoria intermedia en el que se proporcione una vista instantánea de las páginas de la memoria intermedia. Inclúyanse los detalles de la forma de usar el registro histórico para generar la vista instantánea, asumiendo que se use el algoritmo avanzado de recuperación. Asúmase por simplicidad que tanto la operación lógica como deshacerla afectan sólo a una página.

Notas bibliográ cas

El libro de Gray y Reuter [1993] constituye una excelente fuente de información sobre la recuperación incluyendo interesantes implementaciones y detalles históricos. El libro de Bernstein et al. [1987] es una fuente de información sobre el control de concurrencia y recuperación. Davies [1973] y Bjork [1973] son dos de los primeros documentos que presentan trabajos teóricos en el campo de la recuperación. Otro trabajo pionero en este campo es el de Chandy et al. [1975], que describe modelos analíticos para el retroceso y las estrategias de recuperación en los sistemas de bases de datos. En Gray et al. [1981] se presenta una visión de conjunto del esquema de recuperación de System R. En Gray [1978], Lindsay et al. [1980] y Verhofstad [1978] pueden encontrarse guías de aprendizaje y visiones de conjunto sobre varias técnicas de recuperación para sistemas de bases de datos. Los conceptos de punto de revisión difusa y volcado difuso se describen en Lindsay et al. [1980]. Haerder y Reuter [1983] ofrece una amplia presentación de los principios de la recuperación. La situación actual de los métodos de recuperación se ilustra mejor con el método de recuperación ARIES, descrito en Mohan et al. [1992] y en Mohan [1990b]. ARIES y sus variantes se usan en varios productos de bases de datos, incluyendo DB2 de IBM y SQL Server de Microsoft. La recuperación en Oracle se describe en Lahiri et al. [2001a]. Mohan y Levine [1992] y Mohan [1993] proporcionan técnicas de recuperación especializadas para estructuras con índices; Mohan y Narang [1994] describe técnicas de recuperación para arquitecturas cliente-servidor, mientras que Mohan y Narang [1991] y Mohan y Narang [1992] describen técnicas de recuperación para arquitecturas de bases de datos paralelas.

www.detodoprogramacion.com


598

Capítulo 17

Sistema de recuperación

King et al. [1991] y Polyzois y Garcia-Molina [1994] consideran las copias de seguridad remotas para recuperación de desastres (pérdida completa de un componente del sistema informático a causa de, por ejemplo, un incendio, una inundación o un terremoto). En el Capítulo 25 se encuentran referencias sobre las transacciones de larga duración y los aspectos de recuperación relacionados.

www.detodoprogramacion.com


P

A

R

T

E

6

Minería de datos y recuperación de información

Las consultas de la base de datos se diseñan normalmente para extraer información específica, como el saldo de una cuenta o la suma de los saldos de la cuentas de un cliente. Sin embargo, las consultas diseñadas para ayudar a formular una estrategia corporativa requieren a menudo la agregación a una escala mucho más grande, e incluyen análisis estadísticos que no se expresan fácilmente con las características de SQL vistas anteriormente. Estas consultas deben tener acceso a menudo a datos de diversas fuentes. Un almacén de los datos es un repositorio de datos recopilados de múltiples fuentes y almacenados bajo un esquema unificado de la base de datos. Los datos almacenados en almacén se analizan mediante agregaciones complejas y análisis estadísticos. Además, las técnicas de descubrimiento del conocimiento se pueden utilizar para intentar descubrir reglas y patrones de datos. Por ejemplo, un minorista puede descubrir que ciertos productos tienden a comprarse juntos, y puede utilizar esa información para desarrollar estrategias de marketing. Este proceso del descubrimiento del conocimiento se llama minería de datos. El Capítulo 18 trata estos aspectos. En nuestras estudios hasta el momento nos hemos centrado en datos relativamente simples y bien estructurados. Sin embargo, hay una cantidad enorme de datos textuales no estructurados en Internet, intranets en organizaciones y en las computadoras de usuarios individuales. Los usuarios desean encontrar la información relevante de esta gran fuente de información textual fundamentalmente, usando mecanismos simples de consulta como consultas basadas en palabras clave. El campo de la recuperación de información se ocupa de consultar estos datos no estructurados, y presta atención particular a la clasificación de los resultados de la consulta. Aunque este campo de investigación recorre varias décadas, ha experimentado un gran crecimiento con el desarrollo de World Wide Web. El Capítulo 19 proporciona una introducción al campo de la recuperación de información.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

18

Análisis y minería de datos

Las empresas han comenzado a aprovechar los cada vez más numerosos datos en línea para tomar mejores decisiones sobre sus actividades, como los artículos que deben tener en inventario y el modo de dirigirse mejor a los clientes para aumentar las ventas. Muchas de las consultas, sin embargo, son bastante complejas y algunos tipos de información no pueden extraerse ni siquiera empleando SQL. Se encuentran disponibles varias técnicas y herramientas de ayuda a la toma de decisiones. Existen herramientas para el análisis de datos que permiten a los analistas ver los datos de diferentes formas. Otras herramientas de análisis realizan un cálculo previo de resúmenes de cantidades muy grandes de datos con objeto de dar respuestas rápidas a las consultas. Las normas SQL:1999 y SQL:2003 contienen ahora constructores adicionales para soportar el análisis de datos. Otro enfoque para obtener información de los datos es utilizar la minería de datos, que pretende detectar varios tipos de estructuras en grandes volúmenes de datos. La minería de datos complementa varios tipos de técnicas estadísticas con objetivos parecidos. Este capítulo trata sobre la ayuda a la toma de decisiones, incluidos el procesamiento analítico en línea, los almacenes de datos y la minería de datos. 18.1 Sistemas de ayuda a la toma de decisiones

Las aplicaciones de bases de datos pueden clasificarse grosso modo en sistemas de procesamiento de transacciones y de ayuda a la toma de decisiones. Los sistemas de procesamiento de transacciones son sistemas que registran información sobre las transacciones, como ventas de productos o matrículas e información de titulaciones para las universidades. Los sistemas de procesamiento de transacciones se utilizan mucho hoy en día y las empresas han acumulado una enorme cantidad de información generada por ellos. Los sistemas de ayuda a la toma de decisiones facilitan a los gestores la decisión de los productos que se deben almacenar en una tienda, los productos que es necesario fabricar o las personas que se deberían admitir en una universidad. Por ejemplo, las bases de datos de las empresas suelen contener enormes cantidades de información sobre los clientes y las transacciones. La cantidad de información necesaria puede llegar a varios centenares de gigabytes o, incluso, a los terabytes para las cadenas de grandes almacenes. La información de las transacciones de un gran almacén puede incluir el nombre o identificador (como puede ser el número de la tarjeta de crédito) del cliente, los artículos adquiridos, el precio pagado y las fechas en que se realizaron las compras. La información sobre los artículos adquiridos puede incluir el nombre del artículo, el fabricante, el número del modelo, el color y la talla. La información sobre los clientes puede incluir su historial de crédito, sus ingresos anuales, su domicilio, su edad e, incluso, su nivel académico. Estas bases de datos de gran tamaño pueden resultar minas de información para adoptar decisiones empresariales, como los artículos que debe haber en inventario y los descuentos que hay que ofrecer. Por ejemplo, puede que una cadena de grandes almacenes note un aumento súbito de las compras de 601

www.detodoprogramacion.com


602

Capítulo 18

Análisis y minería de datos

camisas de franela en la Sierra de Guadarrama, darse cuenta de que hay una tendencia y comenzar a almacenar un mayor número de esas camisas en las tiendas de esa zona. O puede que una empresa automovilística descubra, al consultar su base de datos, que la mayor parte de los coches deportivos de pequeño tamaño los compran mujeres jóvenes cuyos ingresos anuales superan los 50.000 e. Puede que la empresa dirija su publicidad para que atraiga más mujeres de esas características a que compren coches deportivos de pequeño tamaño y evite desperdiciar dinero intentando atraer a otras categorías de consumidores para que compren esos coches. En ambos casos la empresa ha identificado pautas de comportamiento de los consumidores y las ha utilizado para adoptar decisiones empresariales. El almacenamiento y recuperación de los datos para la ayuda a la toma de decisiones plantea varios problemas: • Aunque muchas consultas para ayuda a la toma de decisiones pueden escribirse en SQL, otras no pueden expresarse en SQL o no pueden hacerlo con facilidad. En consecuencia, se han propuesto varias extensiones de SQL para facilitar el análisis de los datos. El área de procesamiento analítico en línea (Online Analytical Processing, OLAP) trata de las herramientas y de las técnicas para el análisis de datos que pueden dar respuestas casi instantáneas a las consultas de datos resumidos, aun cuando la base de datos sea extremadamente grande. En el Apartado 18.2 se estudian las extensiones de SQL para el análisis de datos y las técnicas para el procesamiento analítico en línea. • Los lenguajes de consultas de bases de datos no son eficaces para el análisis estadístico detallado de datos. Existen varios paquetes, como SAS y S++, que ayudan en el análisis estadístico. A estos paquetes se les han añadido interfaces con las bases de datos para permitir que se almacenen en ellas grandes volúmenes de datos y se recuperen de manera eficiente para su análisis. El campo del análisis estadístico es una gran disciplina por sí misma, véanse las referencias en las notas bibliográficas para obtener más información. • Las grandes empresas tienen varios orígenes de datos que necesitan utilizar para adoptar decisiones empresariales. Los orígenes pueden almacenar los datos según diferentes esquemas. Por motivos de rendimiento (así como por motivos de control de la organización) los orígenes de datos no suelen permitir que otras partes de la empresa recuperen datos a petición. Para ejecutar de manera eficiente las consultas sobre datos tan diferentes las empresas han creado almacenes de datos. Los almacenes de datos reúnen los datos de varios orígenes bajo un esquema unificado en un solo sitio. Por tanto, ofrecen al usuario una sola interfaz uniforme para los datos. Los problemas de la creación y mantenimiento de los almacenes de datos se estudian en el Apartado 18.3. • Las técnicas de descubrimiento de conocimiento intentan determinar de manera automática reglas estadísticas y patrones a partir de los datos. El campo de la minería de datos combina las técnicas de descubrimiento de conocimiento creadas por los investigadores en inteligencia artificial y los analistas estadísticos con las técnicas de implementación eficiente que permiten utilizarlas en bases de datos extremadamente grandes. El Apartado 18.4 estudia la minería de datos. El área de ayuda a la toma de decisiones puede considerarse que abarca todas las áreas anteriores, aunque algunas personas utilizan el término en un sentido más restrictivo que excluye el análisis estadístico y la minería de datos. 18.2 Análisis de datos y OLAP

Aunque es mejor dejar el análisis estadístico complejo a los paquetes estadísticos las bases de datos deben soportar las formas sencillas, utilizadas frecuentemente, de análisis estadístico. Dado que los datos almacenados en las bases de datos suelen ser de gran volumen, hay que resumirlos de algún modo si hay que obtener información que puedan utilizar los usuarios. Las herramientas OLAP soportan el análisis interactivo de la información de resumen. Se han desarrollado varias extensiones de SQL para soportar las herramientas OLAP. Hay muchas tareas utilizadas con frecuencia que no pueden realizarse empleando las facilidades básicas de agregación y agrupamiento

www.detodoprogramacion.com


18.2

talla:

Análisis de datos y OLAP

603

all color

falda vestido nombre_artículo camisa pantalón Total Figura 18.1

oscuro 8 20 14 20 62

pastel 35 10 7 2 54

blanco 10 5 28 5 48

Total 53 35 49 27 164

Tabulación cruzada de ventas con nombre_artículo y color.

de SQL. Entre los ejemplos se hallan la búsqueda de percentiles, las distribuciones acumulativas o los agregados sobre ventanas deslizantes de datos ordenados secuencialmente. Recientemente se han propuesto varias extensiones de SQL para soportar estas tareas y se han implementado en productos como Oracle y DB2 de IBM. 18.2.1 Procesamiento analítico en línea

El análisis estadístico suele necesitar el agrupamiento de varios atributos. Considérese una aplicación en que una tienda desea averiguar las prendas que son más populares. Supóngase que las prendas están caracterizadas por su nombre de artículo, su color y su talla y que se tiene la relación ventas con el esquema ventas (nombre_artículo, color, talla, número). Supóngase que nombre_artículo puede adoptar los valores (falda, vestido, camisa, pantalón), color puede adoptar los valores (oscuro, pastel, blanco) y talla puede adoptar los valores (pequeña, mediana, grande). Dada una relación utilizada para el análisis de datos se pueden identificar algunos de sus atributos como atributos de medida, ya que miden algún valor y pueden agregarse. Por ejemplo, el atributo número de la relación ventas es un atributo de medida, ya que mide la cantidad de unidades vendidas. Algunos de los demás atributos (o todos ellos) de la relación se identifican como atributos de dimensión, ya que definen las dimensiones en las que se ven los atributos de medida y los resúmenes de los atributos de medida. En la relación ventas, nombre_artículo, color y talla son atributos de dimensión. (Una versión más realista de la relación ventas tendría más dimensiones, como tiempo o lugar de venta, y más medidas como el valor monetario de la venta). Los datos que pueden modelarse como atributos de dimensión y como atributos de medida se denominan datos multidimensionales. Para analizar los datos multidimensionales puede que el administrador desee ver los datos dispuestos como se encuentran en la tabla de la Figura 18.1. La tabla muestra las cifras totales de diferentes combinaciones de nombre_artículo y color. El valor de talla se especifica como todas, lo que indica que los valores mostrados son un resumen para todos los valores de talla. La tabla de la Figura 18.1 es un ejemplo de tabulación cruzada, también denominada tabla dinámica. En general, las tabulaciones cruzadas son tablas en las que los valores de uno de los atributos (por ejemplo, A) forman las cabeceras de las filas, los valores del otro atributo (por ejemplo, B) forman las cabeceras de las columnas y los valores de cada celda se obtienen como sigue: cada celda puede identificarse como (ai , bj ), donde ai es un valor de A, y bj es un valor de B. Si hay como máximo una tupla con cualquier valor de (ai , bj ), el valor de la celda se obtiene de esa única tupla (si es que hay alguna); por ejemplo, puede ser el valor de uno o varios atributos de la tupla. Si puede haber varias tuplas con el valor (ai , bj ), el valor de la celda debe obtenerse por agregación de las tuplas con ese valor. En este ejemplo la agregación utilizada es la suma de los valores del atributo número para todos los valores de talla, como se indica por talla: all en la tabla cruzada de la Figura 18.1. En este ejemplo la tabulación cruzada también tiene una columna y una fila adicionales que guardan los totales de las celdas de cada fila o columna. La mayor parte de las tabulaciones cruzadas tienen esas filas y columnas de resumen. Las tabulaciones cruzadas son diferentes de las tablas relacionales que suelen guardarse en las bases de datos, ya que el número de columnas de la tabulación cruzada depende de los datos. Una modificación en los valores de los datos puede dar lugar a que se añadan más columnas, lo que no resulta

www.detodoprogramacion.com


604

Capítulo 18

Análisis y minería de datos

nombre_artículo falda falda falda falda vestido vestido vestido vestido camisa camisa camisa camisa pantalón pantalón pantalón pantalón all all all all Figura 18.2

color oscuro pastel blanco all oscuro pastel blanco all oscuro pastel blanco all oscuro pastel blanco all oscuro pastel blanco all

talla all all all all all all all all all all all all all all all all all all all all

número 8 35 10 53 20 10 5 35 14 7 28 49 20 2 5 27 62 54 48 164

Representación relacional de los datos de la Figura 18.1.

deseable para el almacenamiento de los datos. No obstante, la vista de tabulación cruzada es deseable para mostrársela a los usuarios. La representación de las tabulaciones cruzadas sin valores resumen en un formulario relacional con un número fijo de columnas es directa. La tabulación cruzada con columnas o filas resumen puede representarse introduciendo el valor especial todos para representar los subtotales, como en la Figura 18.2. La norma SQL:1999 utiliza realmente el valor null (nulo) en lugar de all; pero, para evitar confusiones con los valores nulos habituales, en el libro se seguirá utilizando all. Considérense las tuplas (falda, all, all, 53) y (vestido, all, all, 35). Se han obtenido estas tuplas eliminando las tuplas individuales con diferentes valores de color y talla, y sustituyendo el valor de número por un agregado— es decir, una suma. El valor all puede considerarse representante del conjunto de los valores de un atributo. Las tuplas con el valor all para las dimensiones color y talla pueden obtenerse mediante una agregación de la relación ventas con una agrupación en la columna nombre_artículo. De manera parecida, se puede utilizar una agrupación en color y talla para conseguir las tuplas con el valor all para nombre_artículo, y se puede utilizar una agrupación sin atributo alguno (que en SQL puede omitirse simplemente) para obtener la tupla con el valor all para nombre_artículo, color y talla. La generalización de las tabulaciones cruzadas, que son bidimensionales, a n dimensiones pueden visualizarse como cubos n-dimensionales, denominados cubos de datos. La Figura 18.3 muestra un cubo de datos para la relación ventas. El cubo de datos tiene tres dimensiones, a saber, nombre_artículo, color y talla, y el atributo de medida es número. Cada celda se identifica por los valores de estas tres dimensiones. Cada celda del cubo de datos contiene un valor, igual que en la tabulación cruzada. En la Figura 18.3, el valor contenido en la celda se muestra en una de las caras de la celda; las otras caras de la celda se muestran en blanco si son visibles. Todas las celdas contienen valores, aunque no sean visibles. El valor de una dimensión puede ser all, en cuyo caso la celda contiene un resumen de todos los valores de esa dimensión, como en el caso de las tabulaciones cruzadas. El número de maneras diferentes en que las tuplas pueden agruparse para su agregación puede ser grande. De hecho, para una tabla con n dimensiones, se puede realizar la agregación con la agrupación de cada uno de los 2n subconjuntos de las n dimensiones1 . El sistema de procesamiento analítico en línea o sistema OLAP es un sistema interactivo que permite a los analistas ver diferentes resúmenes de los datos multidimensionales. Las palabras en línea indican que 1. La agrupación sobre el conjunto de las n dimensiones sólo resulta útil si la tabla puede tener duplicados.

www.detodoprogramacion.com


Análisis de datos y OLAP

18.2

2

5

4 2

3

7 8

6 5

1 12

7

605

11 29

22 16

oscuro

color

pastel blanco

8 35 10

20 10 8

14 7 28

20 2 5

62 54

4 34

18 9

21

45 42

48

pequeña

77 35

49

27

falda vestido camisa pantalón

164 all

la

53

all

ta l

all

mediana grande

nombre_artículo Figura 18.3

Cubo de datos tridimensional.

los analistas deben poder solicitar nuevos resúmenes y obtener respuestas en línea, en pocos segundos, y no deberían verse obligados a esperar mucho tiempo para ver el resultado de las consultas. Con los sistemas OLAP los analistas de datos pueden ver diferentes tabulaciones cruzadas para los mismos datos seleccionando de manera interactiva los atributos de las tabulaciones cruzadas. Cada tabulación cruzada es una vista bidimensional del cubo de datos multidimensional. Por ejemplo, el analista puede seleccionar una tabulación cruzada para nombre_artículo y talla o una tabulación cruzada para color y talla. La operación de modificación de las dimensiones utilizadas en las tabulaciones cruzadas se denomina pivotaje. Los sistemas OLAP también ofrecen otras funcionalidades. Por ejemplo, puede que un analista desee ver una tabulación cruzada de nombre_artículo y color para un valor fijo de talla, por ejemplo, grande, en lugar de la suma para todas las tallas. Esta operación se conoce como corte, ya que puede considerarse como la vista de una rebanada del cubo de datos. A veces la operación se denomina corte de cubos, especialmente cuando se fijan los valores de varias dimensiones. Cuando se utilizan tabulaciones cruzadas para ver cubos multidimensionales los valores de los atributos de dimensión que no forman parte de la tabulación cruzada se muestran por encima de ella. El valor de estos atributos puede ser all, como puede verse en la Figura 18.1, lo que indica que los datos de la tabulación cruzada son un resumen de todos los valores del atributo. El corte y la creación de datos consisten simplemente en la selección de valores concretos de estos atributos, que se muestran luego por encima de la tabulación cruzada. Los sistemas OLAP permiten a los usuarios examinar los datos con cualquier nivel de granularidad que se desee. La operación de pasar de datos con una granularidad más fina a una granularidad más gruesa (mediante la agregación) se denomina abstracción. En este ejemplo, a partir del cubo de datos para la tabla ventas, se obtiene la tabulación cruzada de ejemplo abstrayendo el atributo talla. La operación inversa — la de pasar de datos con una granularidad más gruesa a una más fina—se denomina concreción. Claramente, los datos con granularidad más fina no pueden generarse a partir datos con una granularidad más gruesa; deben generarse a partir de los datos originales o de datos resumidos de granularidad aún más fina. Puede que un analista desee examinar una dimensión con niveles diferentes de detalle. Por ejemplo, los atributos de tipo FechaHora contienen una fecha y una hora del día. El empleo de horas con precisión de segundos (o menos) puede que no sea significativo: los analistas que estén interesados en la hora aproximada del día puede que sólo miren el valor horario. Los analistas que estén interesados en las ventas de cada día de la semana puede que apliquen la fecha al día de la semana y sólo se fijen en eso. Puede que otro analista esté interesado en agregados mensuales, trimestrales o de años enteros. Los diferentes niveles de detalle de los atributos pueden organizarse en una jerarquía. La Figura 18.4a muestra una jerarquía para el atributo FechaHora. La Figura 18.4b, que puede ser otro ejem-

www.detodoprogramacion.com


606

Capítulo 18

Análisis y minería de datos

Año Trimestre Región Día de la semana

Mes País

Fecha

Hora del día

Estado Ciudad

FechaHora (a) Jerarquía de tiempo Figura 18.4

(b) Jerarquía de ubicación

Jerarquías de las dimensiones.

plo, muestra una jerarquía para la ubicación, con la ciudad en la parte inferior de la jerarquía, el estado por encima, el país en el nivel siguiente y la región en el nivel superior. En el ejemplo anterior la ropa puede agruparse por categorías (por ejemplo, ropa de hombre o de mujer); la categoría estaría por encima de nombre-artículo en la jerarquía de la ropa. En el nivel de los valores reales las faldas y los vestidos caerían dentro de la categoría de ropa de mujer y los pantalones y las camisas en la de ropa de hombre. Puede que un analista esté interesado en consultar las ventas de ropa divididas entre ropa de hombre y ropa de mujer y que no esté interesado en sus valores individuales. Tras ver los agregados en el nivel de ropa de hombre y ropa de mujer puede que el analista concrete la jerarquía para ver los valores individuales. Un analista que examine el nivel detallado puede abstraer la jerarquía y examinar agregados de niveles más gruesos. Ambos niveles pueden mostrarse en la misma tabulación cruzada, como en la Figura 18.5. 18.2.2 Implementación de OLAP

Los primeros sistemas de OLAP utilizaban arrays de memoria multidimensionales para almacenar los cubos de datos y se denominaban sistemas OLAP multidimensionales (Multidimensional OLAP, MOLAP). Posteriormente, los servicios OLAP se integraron en los sistemas relacionales y los datos se almacenaron en las bases de datos relacionales. Estos sistemas se denominan sistemas OLAP relacionales (Relational OLAP, ROLAP). Los sistemas híbridos, que almacenan algunos resúmenes en la memoria y los datos básicos y otros resúmenes en bases de datos relacionales, se denominan sistemas OLAP híbridos (Hybrid OLAP, HOLAP).

talla:

all categoría

nombre_artículo oscuro

ropa de mujer

ropa de hombre

total Figura 18.5

falda vestido subtotal pantalón camisa subtotal

8 20 28 14 20 34 62

color pastel

blanco

8 20 28 14 20 34 62

10 5 15 28 5 33 48

total 53 35 88 49 27 76 164

Tabulación cruzada de ventas con la jerarquía para nombre_artículo.

www.detodoprogramacion.com


18.2

Análisis de datos y OLAP

607

Muchos sistemas OLAP se implementan como sistemas cliente–servidor. El servidor contiene la base de datos relacional y los cubos de datos MOLAP. Los sistemas clientes obtienen vistas de los datos comunicándose con el servidor. Una manera ingenua de calcular todo el cubo de datos (todas las agrupaciones) de una relación es utilizar cualquier algoritmo estándar para calcular las operaciones de agregación, agrupación a agrupación. El algoritmo ingenuo necesita un gran número de exploraciones de la relación. Una optimización sencilla consiste en calcular el agregado para, por ejemplo, (nombre_artículo, color) a partir del agregado (nombre_artículo, color, talla), en lugar de hacerlo a partir de la relación original. Para las funciones de agregación estándar de SQL se pueden calcular agregados con agrupaciones sobre un conjunto de atributos A a partir de un agregado con agrupación sobre un conjunto de atributos B si A ⊆ B; se puede hacer como ejercicio (véase el Ejercicio 18.1), pero hay que tener en cuenta que al calcular avg también es necesario el valor count (para algunas funciones de agregación no estándar como la mediana, los agregados no pueden calcularse de la manera indicada; la optimización aquí descrita no es aplicable a estas funciones de agregación no-descomponibles). La cantidad de datos que se lee disminuye de manera significativa al calcular los agregados a partir de otros agregados, en lugar de hacerlo a partir de la relación original. Se pueden conseguir otras mejoras; por ejemplo, se pueden calcular varias agrupaciones con una sola lectura de los datos. Véanse las notas bibliográficas para hallar referencias a los algoritmos para el cálculo eficiente de cubos de datos. Las primeras implementaciones OLAP calculaban previamente los cubos de datos completos, es decir, las agrupaciones por todos los subconjuntos de los atributos de dimensión, y los almacenaban. El cálculo previo permite que las consultas OLAP se respondan en pocos segundos, incluso para conjuntos de datos que pueden contener millones de tuplas que suponen gigabytes de datos. No obstante, hay 2n agrupaciones con n atributos de dimensión; las jerarquías de los atributos aumentan más aún el número. En consecuencia, todo el cubo de datos suele ser mayor que la relación original que lo generó y, en muchos casos, no resulta posible almacenarlo entero. En lugar de calcular previamente todas las agrupaciones posibles y almacenarlas, resulta razonable calcular previamente algunas de las agrupaciones y almacenarlas y calcular el resto según se soliciten. En lugar de calcular las consultas a partir de la relación original, lo que puede tardar mucho tiempo, se pueden calcular a partir de otras consultas calculadas previamente. Por ejemplo, supóngase que una consulta necesita resúmenes según (nombre_artículo, color), que no se ha calculado con anterioridad. El resultado de la consulta puede calcularse a partir de resúmenes según (nombre_artículo, color, talla), si ya se ha calculado. Véanse las notas bibliográficas para hallar referencias al modo de seleccionar para su cálculo previo un buen conjunto de agrupaciones, dados los límites de almacenamiento disponible para los resultados calculados previamente. Los datos de los cubos no se pueden generar mediante una sola consulta SQL utilizando las estructuras básicas group by, ya que los agregados se calculan para varias agrupaciones diferentes de los atributos de dimensión. El Apartado 18.2.3 estudia las extensiones de SQL para el soporte de la funcionalidad OLAP. 18.2.3 Agregación extendida

La funcionalidad de agregación de SQL-92 está limitada, por lo que diferentes sistemas de bases de datos han implementado varias extensiones. No obstante, la norma SQL:1999 define un amplio conjunto de funciones de agregación, que se describen en este apartado y en los dos siguientes. Las bases de datos de Oracle y de DB2 de IBM soportan la mayor parte de estas características y, sin duda, otras bases de datos soportarán estas características en un futuro próximo. Las nuevas funciones de agregación para un solo atributo son la desviación estándar y la varianza (stddev y variance). La desviación estándar es la raíz cuadrada de la varianza2 . Algunos sistemas de bases de datos soportan otras funciones de agregación como la mediana y la moda. Algunos sistemas de bases de datos incluso permiten que los usuarios añadan nuevas funciones de agregación. 2. La norma SQL:1999 soporta en realidad dos tipos de varianza, denominadas varianza de la población y varianza de la muestra y, por tanto, dos tipos de desviación estándar. La definición de los dos tipos difiere ligeramente; los detalles se pueden consultar en cualquier libro de texto de estadística.

www.detodoprogramacion.com


608

Capítulo 18

Análisis y minería de datos

SQL:1999 también soporta una nueva clase de funciones de agregación binarias, que pueden calcular resultados estadísticos para parejas de atributos; entre ellas están las correlaciones, las covarianzas y las curvas de regresión, que dan una línea que aproxima la relación entre los valores de la pareja de atributos. Las definiciones de estas funciones pueden hallarse en cualquier libro de texto estándar, como los que se citan en las notas bibliográficas. SQL:1999 también soporta generalizaciones de la estructura group by, mediante las estructuras cube y rollup. Un uso representativo de la estructura cube es el siguiente:

select nombre_artículo, color, talla, sum(número) from ventas group by cube(nombre_artículo, color, talla) Esta consulta calcula la unión de ocho agrupaciones diferentes de la relación ventas: { (nombre_artículo, color, talla), (nombre_artículo, color), (nombre_artículo, talla), (color, talla), (nombre_artículo), (color), (talla), () } donde () denota una lista group by vacía. Para cada agrupación el resultado contiene el valor nulo para los atributos no presentes en la agrupación. Por ejemplo, la tabla de la Figura 18.2, sustituyendo all por null, la puede calcular la consulta select nombre_artículo, color, sum(número) from ventas group by cube(nombre_artículo, color) Una estructura rollup representativa es: select nombre_artículo, color, talla, sum(número) from ventas group by rollup(nombre_artículo, color, talla) En este caso sólo se han generado cuatro agrupaciones: { (nombre_artículo, color, talla), (nombre_artículo, color), (nombre_artículo), () } La instrucción rollup puede utilizarse para generar agregados en varios niveles de una jerarquía para una columna. Por ejemplo, supóngase que se tiene la tabla categoríaartículo(nombre_artículo, categoría) que da la categoría de cada artículo. La consulta select categoría, nombre_artículo, sum(número) from ventas, categoríaartículo where ventas.nombre_artículo = categoríaartículo.nombre_artículo group by rollup(categoría, nombre_artículo) da un resumen jerárquico según nombre_artículo y según categoría. Se pueden utilizar varios rollup y varios cube en una sola cláusula group by. Por ejemplo, la consulta siguiente: select nombre_artículo, color, talla, sum(número) from ventas group by rollup(nombre_artículo), rollup(color, talla) genera las agrupaciones { (nombre_artículo, color, talla), (nombre_artículo, color), (nombre_artículo), (color, talla), (color), () }

www.detodoprogramacion.com


18.2

Análisis de datos y OLAP

609

Para comprender el motivo hay que tener en cuenta que rollup(nombre_artículo) genera dos agrupaciones, {(nombre_artículo), ()}, y que rollup(color, talla) genera tres agrupaciones, {(color, talla), (color), () }. El producto cartesiano de los dos da como resultado las seis agrupaciones mostradas. Como ya se ha mencionado en el Apartado 18.2.1, SQL:1999 utiliza el valor null para indicar el sentido habitual de nulo así como all. Este uso dual de null puede generar ambigüedad si los atributos utilizados en una cláusula rollup o en una cláusula cube contienen valores nulos. Se puede aplicar la función grouping a un atributo; devuelve 1 si el valor es un valor nulo que represente a all, y devuelve 0 en los demás casos. Considérese la consulta siguiente: select nombre_artículo, color, talla, sum(número), grouping(nombre_artículo) as indicador_nombre_artículo, grouping(color) as indicador_color, grouping(talla) as indicador_talla from ventas group by cube(nombre_artículo, color, talla) El resultado es el mismo que en la versión de la consulta sin grouping, pero con tres columnas adicionales denominadas indicador_nombre_artículo, indicador_color e indicador_talla. En cada tupla el valor de los campos indicador es 1 si el campo correspondiente es un valor nulo que representa a all. En lugar de utilizar etiquetas para indicar los valores nulos que representan a all, se pueden sustituir los valores nulos por un valor a la elección del usuario: decode(grouping(nombre_artículo), 1, ’todos’, nombre_artículo) Esta expresión devuelve el valor “todos” si el valor de nombre_artículo es un valor nulo que se corresponda con all, y devuelve el valor real de nombre_artículo en caso contrario. Esta expresión puede utilizarse en lugar de nombre_artículo en la cláusula select para obtener “todos” en el resultado de la consulta, en lugar de valores nulos que representen a all. Ni la cláusula rollup ni la cláusula cube ofrecen un control completo de las agrupaciones que se generan. Por ejemplo, no se pueden utilizar para especificar que sólo se desean las agrupaciones {(color, talla), (talla, nombre_artículo)}. Estas agrupaciones restringidas pueden generarse utilizando la estructura grouping en la cláusula having; los detalles se dejan como ejercicio para el lector. 18.2.4 Clasi cación

Hallar la posición de un valor en un conjunto más grande es una operación frecuente. Por ejemplo, puede que se desee asignar una clasificación a los estudiantes de acuerdo con sus notas totales, con el puesto 1 para el estudiante con las notas más altas, el puesto 2 para el estudiante con las segundas mejores notas, etc. Aunque estas consultas pueden expresarse en SQL-92, resultan difíciles de expresar e ineficientes a la hora de la evaluación. Los programadores suelen recurrir a escribir en parte la consulta en SQL y en parte en un lenguaje de programación. Un tipo de consulta relacionado es la búsqueda del percentil que le corresponde a un valor de un (multi)conjunto, por ejemplo, el tercio inferior, el tercio central o el tercio superior. Aquí se estudiará el soporte de SQL:1999 para estos tipos de consultas. La clasificación se realiza conjuntamente con una especificación order by. Supóngase que se tiene una relación notas_estudiante(id_estudiante, notas) que almacena las notas obtenidas por cada estudiante. La consulta siguiente da la clasificación de cada estudiante. select id_estudiante, rank() over (order by (notas) desc) as clasificación_e from notas_estudiante Obsérvese que el orden de las tuplas en el resultado no se ha definido, por lo que puede que no estén ordenadas según su clasificación. Se necesita una cláusula order by adicional para dejarlas ordenadas, como puede verse a continuación. select id_estudiante, rank () over (order by (notas) desc) as clasificación_e from notas_estudiante order by clasificación_e

www.detodoprogramacion.com


610

Capítulo 18

Análisis y minería de datos

Un aspecto básico de las clasificaciones es el modo de tratar el caso de que haya varias tuplas que sean iguales en el atributo o atributos de ordenación. En el ejemplo anterior esto significa decidir lo que se hace si hay dos estudiantes con la misma nota. La función rank devuelve la misma clasificación a todas las tuplas que sean iguales en los atributos order by. Por ejemplo, si la nota más elevada la comparten dos estudiantes, los dos obtendrían el puesto 1. El puesto siguiente sería el 3, no el 2, por lo que si tres estudiantes consiguieran la siguiente nota más alta, todos ellos obtendrían el puesto 3, y los siguientes estudiantes obtendrían el puesto 5, etc. También hay una función dense_rank que no crea saltos en la ordenación. En el ejemplo anterior las tuplas con el segundo valor más alto obtienen el puesto 2 y las tuplas con el tercer valor más elevado obtienen el puesto 3, etc. Se puede llevar a cabo la clasificación dentro de particiones de los datos. Por ejemplo, supóngase que se tiene una relación adicional estudiante _sección(id_estudiante, sección) que almacena para cada estudiante la sección en la que estudia. La consulta siguiente da la clasificación de los estudiantes dentro de cada sección. select id_estudiante, sección, rank () over (partition by sección order by notas desc) as clasificación_sec from notas_estudiante, sección_estudiante where notas_estudiante.id_estudiante = sección_estudiante.id_estudiante order by sección, clasificación_sec La cláusula order by externa ordena las tuplas del resultado por secciones y, dentro de cada sección, por su clasificación. Se pueden utilizar varias expresiones rank dentro de cada sentencia select; por tanto, se puede obtener la clasificación general y la clasificación dentro de cada sección empleando dos expresiones rank en la misma cláusula select. Una pregunta interesante es lo que ocurre cuando se produce una clasificación (posiblemente con partición) junto con una cláusula group by. En ese caso, la cláusula group by se aplica en primer lugar y la partición y la clasificación se realizan sobre los resultados de la cláusula group by. Así, los valores agregados pueden utilizarse para la clasificación. Por ejemplo, supóngase que se tienen las notas de cada estudiante en varias asignaturas. Para clasificar a los estudiantes por la suma de sus notas en varias asignaturas se puede utilizar una cláusula group by para calcular las notas agregadas de cada estudiante y luego clasificar a los estudiantes por la suma agregada. Los detalles se le dejan al lector como ejercicio. Las funciones de clasificación pueden utilizarse para hallar las n primeras tuplas incrustando una consulta de clasificación en una consulta de un nivel exterior; los detalles se dejan para un ejercicio. Téngase en cuenta que las n últimas tuplas son simplemente las mismas que las n primeras con un orden inverso. Varios sistemas de bases de datos ofrecen extensiones no estándar de SQL para especificar directamente que sólo se necesitan los n primeros resultados; esas extensiones no necesitan la función de clasificación y simplifican el trabajo del optimizador, pero (actualmente) no son tan generales, ya que no soportan las particiones. SQL:1999 también especifica otras funciones que pueden utilizarse en lugar de rank. Por ejemplo, percent_rank de una tupla da la clasificación de la tupla en forma de fracción. Si hay n tuplas en la partición3 y la clasificación de la tupla es r, su clasificación percentual se define como (r − 1)/(n − 1) (y como nula si sólo hay una tupla en la partición). La función cume_dist, abreviatura de distribución acumulativa (cumulative distribution), para una tupla se define como p/n, donde p es el número de tuplas de la partición con valores de ordenación que preceden o son iguales al valor de ordenación de la tupla, y n es el número de tuplas de la partición. La función row_number ordena las filas y da a cada una un número único correspondiente a su posición en el orden; filas diferentes con el mismo valor de ordenación reciben números de fila diferentes, de manera no determinista. Finalmente, para una constante dada n, la función de clasificación ntile(n) toma las tuplas de cada partición en el orden especificado y las divide en n cajones con igual número de tuplas4 . Para cada tupla, ntile(n) da el número del cajón en el que se halla, con los números de los cajones comenzando por 1. Esta 3. Todo el conjunto se trata como una sola partición si no se utiliza ninguna partición explícita. 4. Si el número total de tuplas de una partición no es divisible por n, el número de tuplas de cada cajón puede variar como mucho en 1. Las tuplas con el mismo valor del atributo de ordenación pueden asignarse cajones diferentes, de manera no determinista, para hacer igual el número de tuplas de cada cajón.

www.detodoprogramacion.com


18.2

Análisis de datos y OLAP

611

función resulta especialmente útil para la creación de histogramas basados en percentiles. Por ejemplo, se pueden ordenar los empleados por su salario y utilizar ntile(3) para hallar el rango (tercio inferior, tercio central o tercio superior) en el que se halla cada empleado, y para calcular el salario total ganado por los empleados de cada rango: select tercil, sum(sueldo) from ( select sueldo, ntile(3) over (order by (sueldo)) as tercil from empleado) as s group by tercil La presencia de valores nulos puede complicar la definición de la clasificación, dado que no está claro si deben colocarse antes en el orden. SQL:1999 permite que el usuario especifique dónde deben aparecer mediante nulls first o nulls last, por ejemplo: select id_estudiante, rank () over (order by notas desc nulls last) as clasificación_e from notas_estudiante 18.2.5 Ventanas

Un ejemplo de consulta ventana es una consulta que, dados los valores de ventas para cada fecha, calcula para cada fecha el promedio de ventas de ese día, del día anterior y del día siguiente; esas consultas de media móvil se utilizan para suavizar las variaciones aleatorias. Otro ejemplo de consulta ventana es la consulta que calcula el saldo acumulado de una cuenta, dada una relación que especifique las imposiciones y las retiradas de fondos de la cuenta. Esas consultas resultan difíciles o imposibles de expresar (depende de la consulta en concreto) en SQL básico. SQL:1999 ofrece una característica de ventanas para soportar esas consultas. A diferencia de group by, la misma tupla puede estar en varias ventanas. Supóngase que se tiene la relación transacción (número _cuenta, fecha_hora, valor), donde valor es positivo para las imposiciones de fondos y negativo para las retiradas. Se da por supuesto que hay como máximo una transacción por cada valor fecha_hora. Considérese la consulta select número_cuenta, fecha_hora, sum(valor) over (partition by número_cuenta order by fecha_hora rows unbounded preceding) as saldo from transacción order by número_cuenta, fecha_hora La consulta da los saldos acumulados de cada cuenta justo antes de cada transacción en esa cuenta; el saldo acumulado de una cuenta es la suma de valores de todas las transacciones anteriores de la cuenta. La cláusula partition by separa las tuplas por número de cuenta, de modo que para cada fila sólo se consideren las tuplas de su partición. Se crea una ventana para cada tupla; las palabras clave rows unbounded preceding especifican que la ventana de cada tupla consiste en todas las tuplas de la partición que la preceden en el orden especificado (en este caso, orden creciente de fecha_hora). La función de agregación sum(valor) se aplica a todas las tuplas de la ventana. Obsérvese que la consulta no utiliza ninguna cláusula group by, ya que hay una tupla de resultado por cada tupla de la relación transacción. Aunque la consulta puede escribirse sin las estructuras ampliadas, sería bastante difícil de formular. Obsérvese también que se pueden superponer diferentes ventanas, es decir, una tupla puede estar presente en más de una ventana. Se pueden especificar otros tipos de ventanas. Por ejemplo, para obtener una ventana que contenga las 10 filas anteriores a cada fila, se puede especificar rows 10 preceding. Para obtener una ventana que contenga la fila actual, la anterior y la siguiente se puede utilizar between rows 1 preceding and 1 following. Para obtener las filas siguientes y la fila actual se puede decir between rows unbounded

www.detodoprogramacion.com


Capítulo 18

Análisis y minería de datos

origen de datos 1

cargadores de datos origen de datos 2

612

SGBD

herramientas de consulta y análisis

almacén de datos

origen de datos n Figura 18.6

Arquitectura de los almacenes de datos.

preceding and current. Obsérvese que si la ordenación se realiza sobre un atributo que no sea clave el resultado no es determinista, ya que el orden de las tuplas no está definido completamente. Se pueden especificar ventanas mediante rangos de valores, en lugar de hacerlo mediante número de filas. Por ejemplo, supóngase que el valor de ordenación de una tupla es v; entonces, range between 10 preceding and current row devolverá tuplas cuyo valor de ordenación se halle entre v − 10 y v (ambos valores inclusive). Al tratar con fechas se puede utilizar range interval 10 day preceding para obtener una ventana que contenga tuplas con los 10 días anteriores, pero sin incluir la fecha de la tupla. Evidentemente, la funcionalidad de ventanas de SQL:1999 es mucho más rica y puede utilizarse para escribir consultas bastante complejas con poco esfuerzo. 18.3 Almacenes de datos

Las grandes empresas tienen presencia en muchos lugares, cada uno de los cuales puede generar un gran volumen de datos. Por ejemplo, las cadenas de tiendas minoristas poseen centenares o millares de tiendas, mientras que las compañías de seguros pueden tener datos de millares de oficinas locales. Además, las organizaciones grandes tienen una estructura compleja de organización interna y, por tanto, puede que los diferentes datos se hallen en ubicaciones, sistemas operativos o bajo esquemas diferentes. Por ejemplo, puede que los datos de los problemas de fabricación y los datos sobre las quejas de los clientes estén almacenados en diferentes sistemas de bases de datos. Los encargados de adoptar las decisiones empresariales necesitan tener acceso a la información de todos esos orígenes. La formulación de consultas a cada uno de los orígenes es a la vez engorrosa e ineficiente. Además, puede que los orígenes de datos sólo almacenen los datos actuales, mientras que es posible que los encargados de adoptar las decisiones empresariales necesiten tener acceso también a datos anteriores, por ejemplo, información sobre la manera en que se han modificado las pautas de compra el año pasado puede resultar de gran importancia. Los almacenes de datos proporcionan una solución a estos problemas. Los almacenes de datos (data warehouses) son depósitos (o archivos) de información reunida de varios orígenes, almacenada bajo un esquema unificado en un solo sitio. Una vez reunida, los datos se almacenan mucho tiempo, lo que permite el acceso a datos históricos. Así, los almacenes de datos proporcionan a los usuarios una sola interfaz consolidada con los datos, por lo que las consultas de ayuda a la toma de decisiones resultan más fáciles de escribir. Además, al tener acceso a la información para la ayuda de la toma de decisiones desde un almacén de datos, el encargado de adoptar las decisiones se asegura de que los sistemas de procesamiento en línea de las transacciones no se vean afectados por la carga de trabajo de la ayuda de la toma de decisiones. 18.3.1 Componentes de los almacenes de datos

La Figura 18.6 muestra la arquitectura de un almacén de datos típico e ilustra la recogida de los datos, su almacenamiento y el soporte de las consultas y del análisis de datos. Entre los problemas que hay que resolver al crear un almacén de datos están los siguientes:

www.detodoprogramacion.com


18.3

Almacenes de datos

613

• Momento y modo de la recogida de datos. En una arquitectura dirigida por los orígenes para la recogida de los datos, los orígenes de los datos transmiten la información nueva, bien, de manera continua (a medida que se produce el procesamiento de las transacciones) o de manera periódica (de noche, por ejemplo). En una arquitectura dirigida por el destino, el almacén de datos envía de manera periódica solicitudes de datos nuevos a los orígenes de datos. A menos que las actualizaciones de los orígenes de datos se repliquen en el almacén de datos mediante un compromiso de dos fases, el almacén de datos nunca estará actualizado respecto a los orígenes de datos. El compromiso de dos fases suele resultar demasiado costoso para ser una opción aceptable, por lo que los almacenes de datos suelen tener datos ligeramente desactualizados. Eso, no obstante, no suele suponer un problema para los sistemas de ayuda a la toma de decisiones. • Selección del esquema. Es probable que los orígenes de datos que se han creado de manera independiente tengan esquemas diferentes. De hecho, puede que utilicen diferentes modelos de datos. Parte de la labor de los almacenes de datos es llevar a cabo la integración de los esquemas y convertir los datos al esquema integrado antes de almacenarlos. En consecuencia, los datos almacenados en el almacén de datos no son una mera copia de los datos de los orígenes de datos. Por el contrario, se pueden considerar como una vista materializada de los datos de los orígenes de datos. • Transformación y limpieza de los datos. La labor de corregir y realizar un procesamiento previo de los datos se denomina limpieza de los datos. Los orígenes de datos suelen entregar datos con numerosas inconsistencias de carácter menor, que pueden corregirse. Por ejemplo, los nombres suelen estar mal escritos y pueden que las direcciones tengan mal escritos los nombres de la calle, del distrito o de la ciudad, o puede que los códigos postales se hayan introducido de manera incorrecta. Esto puede corregirse en un grado razonable consultando una base de datos de los nombres de las calles y de los códigos postales de cada ciudad. El encaje aproximado de los datos requeridos para esta tarea se conoce como búsqueda difusa. Las listas de direcciones recogidas de varios orígenes pueden tener duplicados que haya que eliminar en una operación de mezcla–purga (esta operación también se conoce como desduplicación). Los registros de varias personas de una misma casa pueden agruparse para que sólo se realice a cada casa un envío de correo; esta operación se denomina domiciliación. Los datos se pueden transformar de otras formas además de la limpieza, como cambiar las unidades de medida o convertir los datos a un esquema diferente reuniendo datos de relaciones de varios orígenes. Los almacenes de los datos tienen normalmente herramientas gráficas para dar soporte a la transformación de datos. Estas herramientas permiten que la transformación se especifique con cuadros, y se puede crear arcos para indicar el flujo de datos. Los cuadros condicionales pueden encaminar datos al siguiente paso apropiado en la transformación. Véase en la Figura 29.7 un ejemplo de una transformación especificada usando la herramienta gráfica proporcionada por SQL Server de Microsoft. • Propagación de las actualizaciones. Las actualizaciones de las relaciones en los orígenes de datos deben propagarse a los almacenes de datos. Si las relaciones en los almacenes de datos son exactamente las mismas que en los orígenes de datos, la propagación es directa. En caso contrario, el problema de la propagación de las actualizaciones es básicamente el problema del mantenimiento de las vistas que se estudió en el Apartado 14.5. • Resúmenes de los datos. Los datos brutos generados por un sistema de procesamiento de transacciones pueden ser demasiado grandes para almacenarlos en línea. No obstante, se pueden responder muchas consultas manteniendo únicamente datos resumen obtenidos por agregación de las relaciones, en lugar de mantener las relaciones enteras. Por ejemplo, en lugar de almacenar los datos de cada venta de ropa, se pueden almacenar las ventas totales de ropa por nombre de artículo y por categoría. Supóngase que la relación r ha sido sustituida por la relación resumen s. Todavía se puede permitir a los usuarios que planteen consultas como si la relación r estuviera disponible en lí-

www.detodoprogramacion.com


614

Capítulo 18

Análisis y minería de datos

nea. Si la consulta sólo necesita datos resumidos, puede que sea posible transformarla en una equivalente utilizando s en lugar de r; véase el Apartado 14.5. Los distintos pasos implicados en obtener datos a partir de un almacén de los datos se denominan extracción, transformación y carga o tareas ETC; la extracción se refiere a conseguir datos de los orígenes, mientras que la carga refiere a cargar los datos en el almacén de datos. 18.3.2 Esquemas de los almacenes de datos

Los almacenes de datos suelen tener esquemas diseñados para el análisis de los datos y emplean herramientas como las herramientas OLAP. Por tanto, los datos suelen ser datos multidimensionales, con atributos de dimensión y atributos de medida. Las tablas que contienen datos multidimensionales se denominan tablas de hechos y suelen ser de gran tamaño. Las tablas que registran información de ventas de una tienda minorista, con una tupla para cada artículo a la venta, son un ejemplo típico de tablas de hechos. Las dimensiones de la tabla ventas incluyen lo que es el artículo (generalmente un identificador del artículo como el utilizado en los códigos de barras), la fecha en que se ha vendido, la ubicación (tienda) en que se vendió, el cliente que lo ha comprado, etc. Entre los atributos de medida pueden estar el número de artículos vendidos y el precio de cada artículo. Para minimizar los requisitos de almacenamiento los atributos de dimensiones suelen ser identificadores breves que actúan de claves externas en otras tablas denominadas tablas de dimensiones. Por ejemplo, la tabla de hechos ventas tiene los atributos id_artículo, id_tienda, id_cliente y fecha y los atributos de medida número y precio. El atributo id_tienda es una clave externa en la tabla de dimensiones tienda, que tiene otros atributos como la ubicación de la tienda (ciudad, estado, país). El atributo id_artículo de la tabla ventas es una clave externa de la tabla de dimensiones info_artículo, que contiene información como el nombre del artículo, la categoría a la que pertenece el artículo y otros detalles del artículo como el color y la talla. El atributo id_cliente es una clave externa de la tabla cliente, que contiene atributos como el nombre y la dirección de los clientes. También se puede ver el atributo fecha como clave externa de la tabla info_fecha, que da el mes, el trimestre y el año de cada fecha. El esquema resultante aparece en la Figura 18.7. Un esquema así, con una tabla de hechos, varias tablas de dimensiones y claves externas procedentes de la tabla de hechos en las tablas de dimensiones, se denomina esquema en estrella. Los diseños complejos de almacenes de datos pueden tener varios niveles de tablas de dimensiones; por ejemplo, la tabla info_artículo puede tener un atributo id_fabricante que es clave externa en otra tabla que da detalles del fabricante. Estos esquemas se denominan esquemas en copo de nieve. Los diseños complejos de almacenes de datos pueden tener también más de una tabla de hechos.

información_artículo id_artículo nombre_artículo color talla categoría

información_fecha

ventas id_artículo id_almacén id_cliente fecha número precio

fecha mes trimestre año

Figura 18.7

almacén id_almacén ciudad población provincia

cliente id_cliente nombre calle ciudad población código_postal provincia

Esquema en estrella de un almacén de datos.

www.detodoprogramacion.com


18.4

Minería de datos

615

18.4 Minería de datos

El término minería de datos (data mining) hace referencia vagamente al proceso de análisis semiautomático de bases de datos de gran tamaño para hallar estructuras útiles. Al igual que la búsqueda de conocimiento en la inteligencia artificial (también denominada aprendizaje de la máquina), o el análisis estadístico, la minería de datos intenta descubrir reglas y estructuras a partir de los datos. No obstante, la minería de datos se diferencia del aprendizaje de la máquina y de la estadística en que trata con grandes volúmenes de datos, almacenados sobre todo en disco. Es decir, la minería de datos trata de la “búsqueda de conocimiento en las bases de datos”. Algunos tipos de conocimiento descubiertos a partir de una base de datos pueden representarse por un conjunto de reglas. A continuación se ofrece un ejemplo de regla, formulada de manera informal: “Las mujeres jóvenes con ingresos anuales superiores a 50.000 e son las personas que con mayor probabilidad compran coches deportivos de pequeño tamaño”. Por supuesto, estas reglas no son verdaderas de modo universal, y tienen grados de “soporte” y de “confianza” como se estudiará más adelante. Otros tipos de conocimiento se representan por ecuaciones que relacionan entre sí diferentes variables, o mediante otros mecanismos de predicción de resultados cuando se conocen los valores de algunas variables. Hay gran variedad de tipos posibles de estructuras que pueden resultar útiles, y se emplean diferentes técnicas para hallar tipos diferentes de estructuras. Se estudiarán unos cuantos ejemplos de estructuras y se verá el modo en que pueden obtenerse de manera automática de las bases de datos. Suele haber una parte manual en la minería de datos, que consiste en el preprocesamiento de los datos hasta una forma aceptable para los algoritmos, y en el posprocesamiento de las estructuras descubiertas para hallar otras nuevas que puedan resultar útiles. También puede haber más de un tipo de estructura que se pueda descubrir a partir de una base de datos dada, y puede que se necesite la interacción manual para escoger los tipos de estructuras útiles. Por este motivo, la minería de datos es realmente un proceso semiautomático en la vida real. No obstante, la descripción que sigue se centrará en el aspecto automático de la minería.

18.4.1 Aplicaciones de la minería de datos

La información hallada tiene numerosas aplicaciones. Las aplicaciones más utilizadas son las que necesitan algún tipo de predicción. Por ejemplo, cuando una persona solicita una tarjeta de crédito, la compañía emisora quiere predecir si la persona constituye un buen riesgo de crédito. La predicción tiene que basarse en los atributos conocidos de la persona, como la edad, sus ingresos, sus deudas y su historial de pago de deudas. Las reglas para realizar la predicción se deducen de los mismos atributos de titulares de tarjetas de crédito pasados y actuales, junto con su conducta observada, como puede ser si han dejado de pagar los cargos de su tarjeta de crédito. Entre otros tipos de predicción está la de los clientes que puedan elegir a un competidor (puede que se ofrezca a esos clientes descuentos especiales para intentar que no se cambien), la predicción de la gente que pueda responder a correo publicitario (“correo basura”) o la predicción de los usos de tarjetas telefónicas que puedan resultar fraudulentos. Otra clase de aplicaciones busca asociaciones, por ejemplo, los libros que se suelen comprar a la vez. Si un cliente compra un libro, puede que la librería en línea le sugiera otros libros asociados. Si una persona compra una cámara, puede que el sistema sugiera accesorios que suelen comprarse junto a las cámaras. Un buen vendedor está atento a esas tendencias y las aprovecha para realizar más ventas. El desafío consiste en automatizar el proceso. Puede que otros tipos de asociación lleven al descubrimiento de relaciones causa — efecto. Por ejemplo, el descubrimiento de asociaciones inesperadas entre un medicamento recién introducido y los problemas cardiacos llevó al hallazgo de que el medicamento puede causar problemas cardiacos en algunas personas. El medicamento se retiró del mercado. Las asociaciones son un ejemplo de patrones descriptivos. Las agrupaciones son otro ejemplo de este tipo de patrones. Por ejemplo, hace más de un siglo se descubrió una agrupación de casos de fiebre tifoidea alrededor de un pozo, lo que llevó al descubrimiento de que el agua del pozo estaba contaminada y estaba difundiendo la fiebre tifoidea. La detección de agrupaciones de enfermedades sigue siendo importante hoy en día.

www.detodoprogramacion.com


616

Capítulo 18

Análisis y minería de datos

18.4.2 Clasi cación

Como ya se mencionó en el Apartado 18.4.1, la predicción es uno de los tipos más importantes de minería de datos. Se describirá lo que es la clasificación, se estudiarán técnicas para la creación de un tipo de clasificadores, denominados clasificadores de árboles de decisión, y se estudiarán otras técnicas de predicción. De manera abstracta, el problema de la clasificación es el siguiente: dado que los elementos pertenecen a una de las clases, y dados los casos pasados (denominados ejemplos de formación) de los elementos junto con las clases a las que pertenecen, el problema es predecir la clase a la que pertenece un elemento nuevo. La clase del caso nuevo no se conoce, por lo que hay que utilizar los demás atributos del caso para predecir la clase. La clasificación se puede llevar a cabo hallando reglas que dividan los datos dados en grupos disjuntos. Por ejemplo, supóngase que una compañía de tarjetas de crédito quiera decidir si debe conceder una tarjeta a un solicitante. La compañía tiene amplia información sobre esa persona, como puede ser su edad, su nivel educativo, sus ingresos anuales y sus deudas actuales, la cual puede utilizar para adoptar una decisión. Parte de esta información puede ser importante para el valor de crédito del solicitante, mientras que puede que otra parte no lo sea. Para adoptar la decisión la compañía asigna un nivel de valor de crédito de excelente, bueno, mediano o malo a cada integrante de un conjunto de muestra de clientes actuales según su historial de pagos. Luego, la compañía intenta hallar reglas que clasifiquen a sus clientes actuales como excelentes, buenos, medianos o malos con base en la información sobre esas personas diferente de su historial de pagos actual (que no está disponible para los clientes nuevos). Considérense sólo dos atributos: el nivel educativo (la titulación más alta conseguida) y los ingresos. Las reglas pueden ser de la forma siguiente: ∀personaP, P .titulaci´o n = m´ aster and P .ingresos > 75.000 ⇒ P .cr´e dito = excelente ∀personaP, P .titulaci´o n = bachiller or (P .ingresos ≥ 25.000 and P .ingresos ≤ 75.000) ⇒ P .cr´e dito = bueno También aparecen reglas parecidas para los demás niveles de valor de crédito (mediano y malo). El proceso de creación de clasificadores comienza con una muestra de los datos, denominada conjunto de formación. Para cada tupla del conjunto de formación ya se conoce la clase a la que pertenece. Por ejemplo, el conjunto de formación de las solicitudes de tarjetas de crédito pueden ser los clientes ya existentes, con su riesgo crediticio determinado a partir de su historial de pagos. Los datos actuales, o población, puede consistir en toda la gente, incluida la que no es todavía cliente. Hay varias maneras de crear clasificadores, como se verá. 18.4.2.1 Clasi cadores de árboles de decisión

Los clasificadores de árboles de decisión son una técnica muy utilizada para la clasificación. Como sugiere el nombre, los clasificadores de árboles de decisión utilizan un árbol; cada nodo hoja tiene una clase asociada, y cada nodo interno tiene un predicado (o, de manera más general, una función) asociado. La Figura 18.8 muestra un ejemplo de árbol de decisión. Para clasificar un nuevo caso se empieza por la raíz y se recorre el árbol hasta alcanzar una hoja; en los nodos internos se evalúa el predicado (o la función) para el ejemplo de datos, para hallar a qué nodo hijo hay que ir. El proceso continúa hasta que se llega a un nodo hoja. Por ejemplo, si el nivel académico de la persona es de máster y sus ingresos son de 40K, partiendo de la raíz se sigue el arco etiquetado “máster”, y desde allí el arco etiquetado “25K a 75K”, hasta alcanzar una hoja. La clase de la hoja es “bueno”, por lo que se puede predecir que la solvencia de esa persona es buena. Creación de clasificadores de árboles de decisión La pregunta que se plantea es el modo de crear un clasificador de árboles de decisión, dado un conjunto de casos de formación. La manera más frecuente de hacerlo es utilizar un algoritmo impaciente, que trabaja de manera recursiva, comenzando por la raíz y construyendo el árbol hacia abajo. Inicialmente sólo hay un nodo, la raíz, y todos los casos de formación están asociados con ese nodo.

www.detodoprogramacion.com


18.4

Minería de datos

617

titulación

ninguna

ingresos

ingresos

50 to 100K

ingresos >75K

<25K >=50K

<50K

doctorado

ingresos

>100K

<50K

máster

graduado

<25K

>=25K

25 to 75K

malo mediano bueno

malo

bueno

mediano Figura 18.8

excelente

Árbol de clasificación.

En cada nodo, si todos o “casi todos” los ejemplos de formación asociados con el nodo pertenecen a la misma clase, el nodo se convierte en un nodo hoja asociado con esa clase. En caso contrario, hay que seleccionar un atributo de partición y condiciones de partición para crear nodos hijo. Los datos asociados con cada nodo hijo son el conjunto de ejemplos de formación que satisfacen la condición de partición de ese nodo hijo. En el ejemplo elegido, se escoge el atributo titulación y se crean cuatro hijos, uno por cada valor de la titulación. Las condiciones para los cuatro nodos hijo son titulación = ninguna, titulación = bachiller, titulación = máster y titulación = doctorado, respectivamente. Los datos asociados con cada hijo son los ejemplos de formación asociados con ese hijo. En el nodo correspondiente a máster se escoge el atributo ingresos con el rango de valores dividido en los intervalos 0 a 25K, 25K a 50K, 50K a 75K y más de 75K. Los datos asociados con cada nodo son los ejemplos de formación con atributo titulación igual a máster y el atributo ingresos en cada uno de los rangos, respectivamente. Como optimización, ya que la clase para el rango de 25K a 50K y el rango de 50K a 75K es el mismo bajo el nodo titulación = máster, se han unido los dos rangos en uno solo que va de 25K a 75K. Las mejores particiones De manera intuitiva, al escoger una secuencia de atributos de partición, se comienza con el conjunto de todos los ejemplos de formación, que es “impuro” en el sentido de que contiene ejemplos de muchas clases, y se acaba con las hojas, que son “puras” en el sentido de que en cada hoja todos los ejemplos de formación pertenecen a una única clase. Se verá brevemente el modo de medir cuantitativamente la pureza. Para evaluar la ventaja de escoger un atributo concreto y la condición para la partición de los datos en un nodo se mide la pureza de los datos en los hijos resultantes de la partición según ese atributo. Se escogen el atributo y la condición que producen la pureza máxima. La pureza de un conjunto S de ejemplos de formación puede medirse cuantitativamente de varias maneras. Supóngase que hay k clases y que de los ejemplos en S la fracción de ejemplos de la clase i es pi . Una medida de pureza, la medida de Gini, se define como Gini(S) = 1 −

k X

p2i

i−1

Cuando todos los ejemplos están en una sola clase, el valor de Gini es 0, mientras que alcanza su máximo (de 1 − 1/k) si cada clase tiene el mismo número de ejemplos. Otra medida de la pureza es la medida de la entropía, que se define como k X Entrop´ia(S) = − pi log2 pi i−1

www.detodoprogramacion.com


618

Capítulo 18

Análisis y minería de datos

la entropía es 0 si todos los ejemplos están en una sola clase y alcanza su máximo cuando cada clase tiene el mismo número de ejemplos. La medida de la entropía proviene de la teoría de la información. Cuando un conjunto S se divide en varios conjuntos Si , i = 1, 2, . . . , r, se puede medir la pureza del conjunto de conjuntos resultante como: Pureza(S1 , S2 , . . . , Sr ) =

r X |Si | i=1

|S|

pureza(Si )

Es decir, la pureza es la media ponderada de la pureza de los conjuntos Si . La fórmula anterior puede utilizarse tanto con la medida de la pureza de Gini como con la medida de la pureza de la entropía. La ganancia de información debida a una partición concreta de S en Si , i = 1, 2, . . . , r es, entonces, Ganancia_informaci´on(S, {S1 , S2 , . . . , Sr }) = pureza(S) − pureza(S1 , S2 , . . . , Sr ) Las particiones en menor número de conjuntos son preferibles a las particiones en muchos conjuntos, ya que llevan a árboles de decisión más sencillos y significativos. El número de elementos en cada uno de los conjuntos Si también puede tenerse en cuenta; en caso contrario, que un conjunto Si tenga uno o ningún elemento supondría una gran diferencia en el número de conjuntos, aunque la partición fuera la misma para casi todos los elementos. El contenido de información de una partición concreta puede expresarse en términos de entropía como Contenido_informaci´on(S, {S1 , S2 , . . . , Sr }) = −

r X |Si | i−1

|S|

log2

|Si | |S|

Todo esto lleva a una definición: la mejor partición para un atributo es la que da el máximo índice de ganancia de información, definido como Ganancia_informaci´on(S, {S1 , S2 , . . . , Sr }) Contenido_informaci´ on(S, {S1 , S2 , . . . , Sr }) Búsqueda de las mejores particiones Hay que averiguar el modo de hallar la mejor partición para un atributo. El modo de dividir un atributo depende del tipo de atributo. Los atributos pueden tener valores continuos, es decir, los valores se pueden ordenar de manera significativa para la clasificación, como la edad o los ingresos, o pueden ser determinantes; es decir, no tener ningún orden significativo, como los nombres de los departamentos o los de los países. No se espera que el orden de los nombres de los departamentos o el de los países tenga ningún significado para la clasificación. Generalmente, los atributos que son números (enteros o reales) se tratan como valores continuos y los atributos de cadenas de caracteres se tratan como categóricos, pero esto puede controlarlo el usuario del sistema. En el ejemplo escogido se ha tratado el atributo titulación como categórico y el atributo ingresos como valor continuo. En primer lugar se considera el modo de hallar las mejores particiones para los atributos con valores continuos. Por simplificar sólo se considerarán particiones binarias de los atributos con valores continuos, es decir, particiones que den lugar a dos hijos. El caso de las particiones múltiples es más complicado; véanse las notas bibliográficas para hallar referencias sobre este asunto. Para hallar la mejor partición binaria de un atributo con valores continuos, en primer lugar, se ordenan los valores del atributo en los ejemplos de formación. Luego se calcula la ganancia de información obtenida por la división en cada valor. Por ejemplo, si los ejemplos de formación tienen los valores 1, 10, 15 y 25 para un atributo, los puntos de partición considerados son 1, 10 y 15; en cada caso, los valores menores o iguales que el punto de partición forman una partición y el resto de los valores forman la otra. La mejor partición binaria para el atributo es la partición que da la ganancia de información máxima. Para los atributos categóricos se pueden tener particiones múltiples, con un hijo para cada valor del atributo. Esto funciona muy bien para los atributos categóricos con pocos valores diferentes, como la titulación o el sexo. No obstante, si el atributo tiene muchos valores diferentes, como los nombres de los departamentos en compañías grandes, la creación de un hijo para cada valor no es una buena idea. En

www.detodoprogramacion.com


18.4

Minería de datos

619

procedure CultivarÁrbol(S) Partición(S); procedure Partición (S) if (pureza(S) > δp or |S| < δs ) then return; for each atributo A evaluar las particiones según el atributo A; Usar la mejor partición hallada (para todos los atributos) para dividir S into S1 , S2 , . . . , Sr ; for i = 1, 2, . . . , r Partición(Si ); Figura 18.9

Construcción recursiva de un árbol de decisión.

esos casos se procura combinar varios valores en cada hijo para crear un número menor de hijos. Véanse las notas bibliográficas para hallar referencias al modo de hacerlo. Algoritmo de construcción del árbol de decisión La idea principal de la construcción de árboles de decisión es la evaluación de los diferentes atributos y de las distintas condiciones de partición y la selección del atributo y de la condición de partición que generen el índice máximo de ganancia de información. El mismo procedimiento funciona de manera recursiva en cada uno de los conjuntos resultantes de la partición, lo que hace que se construya de manera recursiva el árbol de decisión. Si los datos pueden clasificarse de manera perfecta, la recursión se detiene cuando la pureza de un conjunto sea 0. No obstante, los datos suelen tener ruido, o puede que un conjunto sea tan pequeño que no se justifique estadísticamente su partición. En ese caso, la partición se detiene cuando la pureza del conjunto es “bastante alta” y la clase de la hoja resultante se define como la clase de la mayoría de los elementos del conjunto. En general, las diferentes ramas del árbol pueden crecer hasta niveles diferentes. La Figura 18.9 muestra pseudocódigo para un procedimiento recursivo de construcción de un árbol, que toma al conjunto de ejemplos de formación S como parámetro. La recursión se detiene cuando el conjunto es lo bastante puro o el conjunto S es demasiado pequeño para que más particiones resulten estadísticamente significativas. Los parámetros δp y δs definen los valores de corte para la pureza y el tamaño; puede que el sistema les dé valores predeterminados, que los usuarios pueden cancelar. Hay gran variedad de algoritmos de construcción de árboles de decisión y se esbozarán las características distintivas de unos cuantos. Véanse las notas bibliográficas para hallar más detalles. Con conjuntos de datos de tamaño muy grande la realización de particiones puede resultar muy costosa, ya que implica la realización repetida de copias. Por tanto, se han desarrollado varios algoritmos para minimizar el coste de E/S y el coste de computación cuando los datos de formación son mayores que la memoria disponible. Varios de los algoritmos también podan los subárboles del árbol de decisión generado para reducir el exceso de ajuste: un subárbol tiene exceso de ajuste si se ha ajustado tanto a los detalles de los datos de formación que comete muchos errores de clasificación con otros datos. Se poda un subárbol sustituyéndolo por un nodo hoja. Hay varias heurísticas de poda; una utiliza parte de los datos de formación para construir el árbol y otra parte para comprobarlo. La heurística poda el subárbol si descubre que los errores de clasificación de los casos de prueba se reducirían si se sustituyera por un nodo hoja. Se pueden generar reglas de clasificación a partir de los árboles de decisión, si se desea. Para cada hoja se genera una regla de la manera siguiente: la parte izquierda es la conjunción de todas las condiciones de partición del camino hasta la hoja y la clase es la clase de la mayoría de los ejemplos de formación de la hoja. Un ejemplo de estas reglas de clasificación es titulaci´o n = m´ aster and ingresos > 75.000 ⇒ excelente

www.detodoprogramacion.com


620

Capítulo 18

Análisis y minería de datos

18.4.2.2 Otros tipos de clasi cadores

Hay varios tipos de clasificadores aparte de los clasificadores de árbol. Dos tipos que han resultado bastante útiles son los clasificadores de redes neuronales y los clasificadores bayesianos. Los clasificadores de redes neuronales utilizan los datos de formación para adiestrar redes neuronales artificiales. Hay gran cantidad de literatura sobre las redes neuronales y aquí no se hablará más de ellas. Los clasificadores bayesianos hallan la distribución de los valores de los atributos para cada clase de los datos de formación; cuando se da un nuevo caso, d, utilizan la información de la distribución para estimar, para cada clase cj , la probabilidad de que el caso d pertenezca a la clase cj , denotada por p(cj |d), de la manera que aquí se describe. La clase con la probabilidad máxima se transforma en la clase predicha para el caso d. Para hallar la probabilidad p(cj |d) de que el caso d esté en la clase cj los clasificadores bayesianos utilizan el teorema de Bayes, que establece p(cj |d) =

p(d|cj )p(cj ) p(d)

donde p(d|cj ) es la probabilidad de que se genere el caso d dada la clase cj , p(cj ) es la probabilidad de ocurrencia de la clase cj , y p(d) es la probabilidad de que ocurra el caso d. De éstas, p (d) puede ignorarse, ya que es igual para todas las clases. p(d) no es más que la fracción de los casos de formación que pertenecen a la clase cj . Hallar exactamente p(d|cj ) resulta difícil, ya que exige una distribución completa de los casos de cj . Para simplificar la tarea los clasificadores bayesianos ingenuos dan por hecho que los atributos tienen distribuciones independientes y, por tanto, estiman p(d|cj ) = p(d1 |cj ) ∗ p(d2 |cj ) ∗ . . . ∗ p(dn |cj ) Es decir, la probabilidad de que ocurra el caso d es el producto de la probabilidad de ocurrencia de cada uno de los valores di del atributo d, dado que la clase es cj . Las probabilidadess p(di |cj ) proceden de la distribución de los valores de cada atributo i, para cada clase cj . Esta distribución se calcula a partir de los ejemplos de formación que pertenecen a cada clase cj ; la distribución suele aproximarse mediante un histograma. Por ejemplo, se puede dividir el rango de valores del atributo i en intervalos iguales y almacenar la fracción de casos de la clase cj que caen en cada intervalo. Dado un valor di para el atributo i, el valor de p(di |cj ) es simplemente la fracción de casos que pertenecen a la clase cj que caen en el intervalo al que pertenece di . Una ventaja significativa de los clasificadores bayesianos es que pueden clasificar los casos con valores de los atributos desconocidos y nulos—los atributos desconocidos o nulos simplemente se omiten del cálculo de probabilidades. Por el contrario, los clasificadores de árboles de decisión no pueden tratar de manera significativa las situaciones en que el caso que hay que clasificar tiene un valor nulo para el atributo de partición utilizado para avanzar por el árbol de decisión. 18.4.2.3 Regresión

La regresión trata de la predicción de valores, no de clases. Dados los valores de un conjunto de variables, X1 , X2 , . . . , Xn , se desea predecir el valor de una variable Y . Por ejemplo, se puede tratar el nivel educativo como un número y los ingresos como otro número y , con base en estas dos variables, querer predecir la posibilidad de impago, que podría ser un porcentaje de probabilidad de impago o el importe impagado. Una manera de inferir los coeficientes a0 , a1 , a2 , . . . , an tales que Y = a0 + a1 ∗ X1 + a2 ∗ X2 + · · · + an ∗ Xn La búsqueda de ese polinomio lineal se denomina regresión lineal. En general, se quiere hallar una curva (definida por un polinomio o por otra fórmula) que se ajuste a los datos; el proceso también se denomina ajuste de la curva. El ajuste sólo puede ser aproximado, debido al ruido de los datos o a que la relación no sea exactamente un polinomio, por lo que la regresión pretende hallar coeficientes que den el mejor ajuste posible.

www.detodoprogramacion.com


18.4

Minería de datos

621

Hay técnicas estándar en estadística para hallar los coeficientes de regresión. Aquí no se estudiarán esas técnicas, pero las notas bibliográficas ofrecen referencias. 18.4.3 Reglas de asociación

Los comercios minoristas suelen estar interesados en las asociaciones entre los diferentes artículos que compra la gente. Ejemplos de esas asociaciones son: • Alguien que compra pan es bastante probable que compre también leche. • Una persona que compró el libro Fundamentos de bases de datos es bastante probable que también compre el libro Fundamentos de sistemas operativos. La información de asociación puede utilizarse de varias maneras. Cuando un cliente compra un libro determinado puede que la librería en línea le sugiera los libros asociados. Puede que la tienda de alimentación decida colocar el pan cerca de la leche, ya que suelen comprarse juntos, para ayudar a los clientes a hacer la compra más rápidamente. O puede que la tienda los coloque en extremos opuestos del mostrador y coloque otros artículos asociados entre medias para inducir a la gente a comprar también esos artículos, mientras los clientes van de un extremo a otro del mostrador. Puede que una tienda que ofrece descuento en un artículo asociado no lo ofrezca en el otro, ya que, de todos modos, el cliente comprará el segundo artículo. Un ejemplo de regla de asociación es pan ⇒ leche En el contexto de las compras de alimentación, la regla dice que los clientes que compran pan también tienden a comprar leche con una probabilidad elevada. Una regla de asociación debe tener una población asociada: la población consiste en un conjunto de casos. En el ejemplo de la tienda de alimentación, la población puede consistir en todas las compras en la tienda de alimentación; cada compra es un caso. En el caso de una librería, la población puede consistir en toda la gente que realiza compras, independientemente del momento en que las hayan realizado. Cada consumidor es un caso. Aquí, el analista ha decidido que el momento de realización de la compra no es significativo, mientras que, para el ejemplo de la tienda de alimentación, puede que el analista haya decidido concentrarse en cada compra, ignorando las diferentes visitas de un mismo cliente. Las reglas tienen un soporte, así como una confianza asociados. Los dos se definen en el contexto de la población: • El soporte es una medida de la fracción de la población que satisface tanto el antecedente como el consecuente de la regla. Por ejemplo, supóngase que sólo el 0.001 por ciento de todas las compras incluyen leche y destornilladores. El soporte de la regla leche ⇒ destornilladores es bajo. Puede que la regla ni siquiera sea estadísticamente significativa—quizás solo hubiera una única compra que incluyera leche y destornilladores. Las empresas no suelen estar interesadas en las reglas que tienen un soporte bajo, ya que afectan a pocos clientes y no merece la pena prestarles atención. Por otro lado, si el 50 por ciento de las compras implica leche y pan, el soporte de las reglas que afecten al pan y a la leche (y a ningún otro artículo) es relativamente elevado, y puede que merezca la pena prestarles atención. El grado mínimo de soporte que se considera deseable exactamente depende de la aplicación. • La confianza es una medida de la frecuencia con que el consecuente es cierto cuando lo es el antecedente. Por ejemplo, la regla pan ⇒ leche tiene una confianza del 80 por ciento si el 80 por ciento de las compras que incluyen pan incluyen también leche. Las reglas con una confianza baja no son significativas. En las aplicaciones comer-

www.detodoprogramacion.com


622

Capítulo 18

Análisis y minería de datos

ciales las reglas suelen tener confianzas significativamente menores del 100 por ciento, mientras que en otros campos, como la física, las reglas pueden tener confianzas elevadas. Hay que tener en cuenta que la confianza de pan ⇒ leche puede ser muy diferente de la confianza de leche ⇒ pan, aunque las dos tienen el mismo soporte. Para descubrir reglas de asociación de la forma i1 , i2 , . . . , in ⇒ i0 en primer lugar hay que determinar los conjuntos de elementos con soporte suficiente, denominados conjuntos grandes de elementos. En el ejemplo que se trata se hallan conjuntos de elementos que están incluidos en un número de casos lo bastante grande. En breve se verá el modo de calcular conjuntos grandes de elementos. Para cada conjunto grande de elementos se obtienen todas las reglas con confianza suficiente que afecten a todos los elementos del conjunto y sólo a ellos. Para cada conjunto grande de elementos S se obtiene una regla S − s ⇒ s para cada subconjunto s ⊂ S, siempre que S − s ⇒ s tenga confianza suficiente; la confianza de la regla la da el soporte de s dividido por el soporte de S. Ahora se considerará el modo de generar todos los conjuntos grandes de elementos. Si el número de conjuntos de elementos posibles es pequeño, basta con un solo paso por los datos para detectar el nivel de soporte de todos los conjuntos. Se lleva una cuenta, con valor inicial 0, para cada conjunto de elementos. Cuando se captura el registro de una compra, la cuenta se incrementa para cada conjunto de elementos tal que todos los elementos del conjunto estén contenidos en la compra. Por ejemplo, si una compra incluye los elementos a, b y c, se incrementará el contador para {a}, {b}, {c}, {a, b}, {b, c}, {a, c} y {a, b, c}. Los conjuntos con un contador lo bastante elevado al final del pase se corresponden con los elementos que tienen un grado de asociación elevado. El número de conjuntos crece de manera exponencial, lo que hace inviable el proceso que se acaba de describir si el número de elementos es elevado. Afortunadamente, casi todos los conjuntos tienen normalmente un soporte muy bajo; se han desarrollado optimizaciones para no considerar la mayor parte de esos conjuntos. Estas técnicas utilizan varios pases por la base de datos y sólo consideran algunos conjuntos en cada pase. En la técnica a priori para la generación de conjuntos de artículos grandes sólo se consideran en el primer pase los conjuntos con un solo elemento. En el segundo pase se consideran los conjuntos con dos artículos, etc. Al final de cada pase todos los conjuntos con soporte suficiente se consideran conjuntos grandes de elementos. Los conjuntos que se ha hallado que tienen demasiado poco soporte al final de cada pase se eliminan. Una vez eliminado un conjunto no hace falta considerar ninguno de sus superconjuntos. En otros términos, en el pase i sólo hay que contar el soporte de los conjuntos de tamaño i tales que se haya hallado que todos sus subconjuntos tienen un soporte lo bastante elevado; basta con probar todos los subconjuntos de tamaño i − 1 para asegurase de que se cumple esta propiedad. Al final del pase i se halla que ningún conjunto de tamaño i tiene el soporte suficiente, por lo que no hace falta considerar ningún conjunto de tamaño i + 1. Entonces, el cálculo se termina. 18.4.4 Otros tipos de asociación

El uso de meras reglas de asociación tiene varios inconvenientes. Uno de los principales es que muchas asociaciones no son muy interesantes, ya que pueden predecirse. Por ejemplo, si mucha gente compra cereales y mucha gente compra pan, se puede predecir que un número bastante grande de personas comprará las dos cosas, aunque no haya ninguna relación entre las dos compras. De hecho, incluso si la compra de cereal tiene una influencia negativa suave en la compra de pan (es decir, los clientes que compran cereal tienden a comprar pan menos a menudo que el cliente medio), la asociación entre el cereal y el pan puede tener un soporte alto. Lo que resultaría interesante es una desviación de la ocurrencia conjunta de las dos compras. En términos estadísticos, se buscan correlaciones entre los artículos; las correlaciones pueden ser positivas, en las que la ocurrencia conjunta es superior a lo esperado, o negativa, en la que los elementos ocurren conjuntamente menos frecuentemente de lo predicho. Así, si la compra de pan no se correlaciona con el cereal, no se informa, incluso si hubiese una asociación fuerte entre los dos. Hay medidas estándares de

www.detodoprogramacion.com


18.4

Minería de datos

623

correlación usadas ampliamente en el área de la estadística. Se puede consultar cualquier libro de texto estándar de estadística para hallar más información sobre las correlaciones. Otra clase importante de aplicaciones de minería de datos son las asociaciones de secuencias (o correlaciones de secuencias). Las series de datos temporales, como las cotizaciones bursátiles en una serie de días, constituyen un ejemplo de datos de secuencias. Los analistas bursátiles desean hallar asociaciones entre las secuencias de cotizaciones. Un ejemplo de asociación de este tipo es la regla siguiente: “Siempre que las tasas de interés de los bonos suben, las cotizaciones bursátiles bajan en un plazo de dos días”. El descubrimiento de esta asociación entre secuencias puede ayudar a adoptar decisiones de inversión inteligentes. Véanse las notas bibliográficas para hallar referencias a la investigación en este campo. Las desviaciones de las estructuras temporales suelen resultar interesantes. Por ejemplo, si una empresa ha estado creciendo a una tasa constante cada año, una desviación de la tasa de crecimiento habitual resulta sorprendente. Si las ventas de ropa de invierno bajan en verano, ya que puede predecirse con base en los años anteriores, una desviación que no se pudiera predecir a partir de la experiencia pasada se consideraría interesante. Las técnicas de minería pueden hallar desviaciones de lo esperado con base en las estructuras temporales o secuenciales pasadas. Véanse las notas bibliográficas para hallar referencias a la investigación en este campo. 18.4.5 Agrupamiento

De manera intuitiva, el agrupamiento hace referencia al problema de hallar agrupaciones de puntos en los datos dados. El problema del agrupamiento puede formalizarse de varias maneras a partir de las métricas de distancias. Una manera es formularlo como el problema de agrupar los puntos en k conjuntos (para un k dado) de modo que la distancia media de los puntos al centroide de su agrupación asignada sea mínima5 . Otra manera es agrupar los puntos de modo que la distancia media entre cada par de puntos de cada agrupación sea mínima. Hay otras definiciones; véanse las notas bibliográficas para hallar más detalles. Pero la intuición subyacente a todas estas definiciones es agrupar los puntos parecidos en un único conjunto. Otro tipo de agrupamiento aparece en los sistemas de clasificaciones de la biología (estos sistemas de clasificación no intentan predecir las clases, sino agrupar los elementos relacionados). Por ejemplo, los leopardos y los seres humanos se agrupan bajo la clase mamíferos, mientras que los cocodrilos y las serpientes se agrupan bajo los reptiles. Tanto los mamíferos como los reptiles están bajo la clase común de los cordados. La agrupación de los mamíferos tiene subagrupaciones, como los carnívoros y los primates. Por tanto, se tiene un agrupamiento jerárquico. Dadas las características de las diferentes especies, los biólogos han creado un esquema complejo de agrupamiento jerárquico que agrupa las especies relacionadas en diferentes niveles de la jerarquía. El agrupamiento jerárquico también resulta útil en otros dominios—para agrupar documentos, por ejemplo. Los sistemas de directorio de Internet (como el de Yahoo) agrupan los documentos relacionados de manera jerárquica (véase el Apartado 19.9). Los algoritmos de agrupamiento jerárquico pueden clasificarse como algoritmos de agrupamiento aglomerativo, que comienzan creando agrupaciones pequeñas y luego crean los niveles superiores, o como algoritmos de agrupamiento divisivo, que primero crean los niveles superiores del agrupamiento jerárquico y luego refinan cada agrupación resultante en agrupaciones de niveles inferiores. La comunidad estadística ha estudiado extensamente los agrupamientos. La investigación en bases de datos ha proporcionado algoritmos escalables de agrupamiento que pueden agrupar conjuntos de datos de tamaño muy grande (que puede que no quepan en la memoria). El algoritmo de agrupamiento Birch es un algoritmo de este tipo. De manera intuitiva, los puntos de datos se insertan en una estructura arbórea multidimensional (basada en los árboles R descritos en el Apartado 24.3.5.3) y son llevados a los nodos hoja correspondientes de acuerdo con su cercanía a los puntos representativos de los nodos internos del árbol. Los puntos próximos, por tanto, se agrupan en los nodos hoja, y se resumen si hay más puntos de los que caben en la memoria. El resultado de esta primera fase de agrupamiento es crear un conjunto de datos agrupado parcialmente que quepa en memoria. Las técnicas estándares de 5. El centroide de un conjunto de puntos se define como un punto cuyas coordenadas en cada dimensión son el promedio de las coordenadas de todos los puntos de ese conjunto en esa dimensión. PorPejemplo, en dos dimensiones, el centroide de un conjunto P de puntos { (x1 , y1 ), (x2 , y2 ), . . . , (xn , yn ) } viene dado por (

n i=1

n

xi

,

n i=1

n

www.detodoprogramacion.com

yi

).


624

Capítulo 18

Análisis y minería de datos

agrupamiento se pueden ejecutar con datos en memoria para conseguir el agrupamiento final. Véanse las notas bibliográficas para hallar las referencias al algoritmo Birch y a otras técnicas de agrupamiento, incluidos los algoritmos para el agrupamiento jerárquico. Una aplicación interesante del agrupamiento es la predicción de las películas nuevas (o de los libros nuevos, o de la música nueva) que es probable que interesen a una persona, con base en: 1. Las preferencias cinematográficas pasadas de esa persona. 2. Otras personas con preferencias pasadas parecidas. 3. Las preferencias de esa gente entre las películas nuevas. Un enfoque de este problema es el siguiente. Para hallar gente con preferencias anteriores parecidas se crean agrupaciones de personas de acuerdo con sus preferencias cinematográficas. La exactitud del agrupamiento puede mejorarse agrupando previamente las películas por su parecido, de modo que, aunque la gente no haya visto las mismas películas, se agruparán si han visto películas parecidas. Se puede repetir el agrupamiento, agrupando alternativamente gente y películas hasta que se alcance un equilibrio. Dado un nuevo usuario, se halla una agrupación de usuarios lo más parecidos posibles a él, con base en las preferencias del usuario por las películas que ya ha visto. Luego se predice que las películas de las agrupaciones de películas que son populares en la agrupación de ese usuario es probable que resulten interesantes para el nuevo usuario. De hecho, este problema es un caso de filtrado colaborativo, en el que los usuarios colaboran en la tarea de filtrado de la información para hallar información de interés.

18.4.6 Otros tipos de minería

La minería de texto aplica las técnicas de minería de datos en documentos de texto. Por ejemplo, hay herramientas que forman agrupaciones de las páginas que ha visitado un usuario; esto ayuda a los usuarios cuando examinan su historial de exploración para hallar las páginas que han visitado anteriormente. La distancia entre las páginas puede basarse, por ejemplo, en las palabras frecuentes en esas páginas (véase el Apartado 19.2.2). Otra aplicación es la clasificación automática de las páginas en directorios Web, de acuerdo con su parecido con otras páginas (véase el Apartado 19.9). Los sistemas de visualización de datos ayudan a los usuarios a examinar grandes volúmenes de datos y a detectar visualmente las estructuras. Las visualizaciones de datos—como los mapas, los gráficos y otras representaciones gráficas—permiten que los datos se presenten a los usuarios de manera compacta. Una sola pantalla gráfica puede codificar tanta información como un número mucho mayor de pantallas de texto. Por ejemplo, si el usuario desea averiguar si los problemas de producción en las factorías están correlacionadas con su ubicación se pueden codificar las ubicaciones problemáticas en un color especial — por ejemplo, rojo—en un mapa. El usuario puede descubrir rápidamente las ubicaciones en las que se dan los problemas. El usuario puede así formular hipótesis sobre el motivo de que los problemas se produzcan en esas ubicaciones y contrastarlas cuantitativamente con la base de datos. Otro ejemplo más: la información sobre los valores puede codificarse como colores y mostrarse con sólo un píxel de área de pantalla. Para detectar las asociaciones entre pares de elementos se puede utilizar una matriz bidimensional de píxeles en la que cada fila y cada columna representen un elemento. El porcentaje de transacciones que compran los dos elementos puede codificarse por la intensidad del color de los píxeles. Los elementos con asociaciones elevadas aparecerán en la pantalla como píxeles brillantes— fáciles de detectar contra el fondo más oscuro. Los sistemas de visualización de datos no detectan de manera automática las estructuras, sino que proporcionan soporte del sistema para que los usuarios las detecten. Dado que los seres humanos son muy buenos en la detección de estructuras visuales, la visualización de los datos es un componente importante de la minería de datos.

www.detodoprogramacion.com


18.5

Resumen

625

18.5 Resumen

• Los sistemas de ayuda a la toma de decisiones analizan en línea los datos recogidos por los sistemas de procesamiento de transacciones para ayudar a los usuarios a adoptar decisiones de negocios. Dado que hoy en día la mayor parte de las organizaciones están intensamente informatizadas, se dispone de una enorme cantidad de información para la ayuda a la toma de decisiones. Los sistemas de ayuda a la toma de decisiones se presentan en varios formatos, incluidos los sistemas OLAP y los sistemas de minería de datos. • Las herramientas de procesamiento analítico en línea (online analytical processing, OLAP) ayudan a los analistas a ver los datos resumidos de diferentes maneras, de forma que puedan obtener una perspectiva del funcionamiento de la organización. ¤ Las herramientas OLAP trabajan con datos multidimensionales, caracterizados por los atributos de dimensiones y por los atributos de medida. ¤ Los cubos de datos consisten en datos multidimensionales resumidos de diferentes maneras. El cálculo previo de los cubos ayuda a acelerar las consultas de resúmenes de datos. ¤ El formato de las tabulaciones cruzadas permite que los usuarios vean simultáneamente dos dimensiones de los datos multidimensionales, junto con resúmenes de los datos. ¤ La concreción, la abstracción y los cortes de los cubos de datos son algunas de las operaciones que los usuarios llevan a cabo con las herramientas OLAP. • El componente OLAP de la norma SQL:1999 proporciona gran variedad de funcionalidades nuevas para el análisis de los datos, incluidas nuevas funciones de agregación; operaciones con cubos y de abstracción, funciones de clasificación; funciones para la creación de ventanas, que soportan la elaboración de resúmenes en ventanas móviles; y la realización de particiones, con la creación de ventanas y la clasificación aplicadas dentro de cada partición. • Los almacenes de los datos ayudan a obtener y archivar datos operacionales importantes. Los almacenes se usan para la ayuda a la toma de decisiones y para el análisis de datos históricos, por ejemplo, para predecir tendencias. La limpieza de datos de orígenes de datos de entrada es a menudo una tarea importante en los almacenes de los datos. Los esquemas de los almacenes de datos tienden a ser multidimensionales, implicando una o varias tablas muy grandes de hechos y varias tablas de dimensiones mucho más pequeñas. • La minería de datos es el proceso de análisis semiautomático de bases de datos de gran tamaño para hallar estructuras útiles. Hay gran número de aplicaciones de minería de datos, como la predicción de valores con base en los ejemplos ya pasados, la búsqueda de asociaciones entre las compras y la agrupación automática de personas y películas. • La clasificación trata de la predicción de la clase de los ejemplos de prueba utilizando los atributos de los ejemplos de prueba con base en los atributos de los ejemplos de formación y en la clase real de los ejemplos de formación. La clasificación puede utilizarse, por ejemplo, para predecir el valor de crédito de los nuevos solicitantes o para predecir el rendimiento de los estudiantes que solicitan el ingreso en una universidad. Hay varios tipos de clasificadores: ¤ Los clasificadores de árboles de decisión llevan a cabo la clasificación creando un árbol basado en los ejemplos de formación con hojas que tienen las etiquetas de las clases. Se recorre el árbol para cada ejemplo de prueba hasta hallar una hoja y la clase de esa hoja es la clase predicha. Se dispone de varias técnicas para crear árboles de decisión, la mayor parte de ellas basadas en heurística impaciente. ¤ Los clasificadores bayesianos son más sencillos de crear que los clasificadores de árboles de decisión y funcionan mejor en caso de que haya valores de los atributos que falten o que sean nulos.

www.detodoprogramacion.com


626

Capítulo 18

Análisis y minería de datos

• Las reglas de asociación identifican los elementos que aparecen juntos con frecuencia, por ejemplo, los artículos que el mismo cliente suele comprar. Las correlaciones buscan las desviaciones respecto de los niveles de asociación esperados. • Otros tipos de minería de datos son el agrupamiento, la minería de texto y la visualización de datos.

Términos de repaso

• Sistemas de ayuda a la toma de decisiones.

• Minería de datos.

• Análisis estadístico.

• Predicción.

• Datos multidimensionales.

• Asociaciones.

¤ Atributos de medida. ¤ Atributos de dimensiones.

• Clasificación. ¤ Datos de formación. ¤ Datos de prueba.

• Tabulaciones cruzadas.

• Clasificadores de árboles de decisión.

• Cubo de datos.

¤ Atributo de partición. ¤ Condición de partición. ¤ Pureza –– Medida de Gini. –– Medida de la entropía. ¤ Ganancia de información. ¤ Contenido de la información. ¤ Tasa de ganancia de la información. ¤ Atributo con valores continuos. ¤ Atributo categórico. ¤ División binaria. ¤ División múltiple. ¤ Exceso de ajuste.

• Procesamiento analítico en línea (online analytical processing, OLAP). ¤ Pivotaje. ¤ Cortes de cubos. ¤ Abstracción y concreción. • OLAP multidimensional (MOLAP). • OLAP relacional (ROLAP). • OLAP híbrido (HOLAP). • Agregación ampliada. ¤ ¤ ¤ ¤

Varianza. Desviación estándar. Correlación. Regresión.

• Funciones de clasificación. ¤ Clasificación. ¤ Clasificación densa. ¤ División mediante. • Creación de ventanas.

• Clasificadores bayesianos. ¤ Teorema de Bayes. ¤ Clasificadores bayesianos ingenuos. • Regresión. ¤ Regresión lineal. ¤ Ajuste de curvas. • Reglas de asociación.

• Almacenes de datos. Recogida de datos. Arquitectura dirigida por el origen. Arquitectura dirigida por el destino. Limpieza de datos. –– Mezcla-purga. –– Domiciliación. ¤ Extraer, Transformar, Cargar (ETL).

¤ ¤ ¤ ¤

¤ ¤ ¤ ¤

• Otros tipos de asociación. • Agrupamiento: ¤ Jerárquico. ¤ Aglomerativo. ¤ Divisivo.

• Esquemas de almacenamiento. ¤ Tabla de hechos. ¤ Tablas de dimensiones. ¤ Esquema en estrella.

Población. Soporte. Confianza. Conjuntos de elementos de gran tamaño.

• Minería de texto. • Visualización de datos.

www.detodoprogramacion.com


Ejercicios

627

Ejercicios prácticos

18.1 Muéstrese el modo de expresar group by cube(a, b, c, d) utilizando rollup; la respuesta sólo debe tener una cláusula group by. 18.2 Dada la relación E(estudiante, asignatura, notas), escríbase una consulta para hallar los n mejores estudiantes por sus notas totales, utilizando la clasificación. 18.3 Escríbase una consulta para hallar saldos acumulativos, equivalente a la mostrada en el Apartado 18.2.5, pero sin utilizar las estructuras ampliadas para la creación de ventanas de SQL. 18.4 Considérese la relación ventas del Apartado 18.2. Escríbase una consulta en SQL para calcular la operación cubo para la relación, dada la relación de la Figura 18.2. No hay que utilizar el constructor cube. 18.5 Descríbanse las ventajas y los inconvenientes de una arquitectura dirigida por el origen para la recolección de datos en los almacenes de datos en comparación con una arquitectura dirigida por el destino. 18.6 Supóngase que hay dos reglas de clasificación, una que dice que la gente con sueldos entre 10.000 e y 20.000 e tienen una calificación de crédito de buena, y otra que dice que la gente con sueldos entre 20.000 e y 30.000 e tienen una calificación de crédito de buena. Indíquense las condiciones para las que se pueden reemplazar ambas reglas, sin pérdida de información, por una sola regla que diga que las personas con sueldos entre 10.000 e y 30.000 e tienen una calificación de crédito de buena. 18.7 Considérese el esquema de la Figura 18.7. Dada una consulta de SQL:1999 para resumir las cifras de ventas y los precios por tienda y por fecha, junto con las jerarquías para tienda y fecha. Ejercicios

18.8 Para cada una de las funciones de agregación de SQL sum, count, min, y max, muéstrese el modo de calcular el valor agregado para el conjunto múltiple S1 ∪ S2 , dados los valores agregados para los conjuntos múltiples S1 y S2 . Basándose en lo anterior hay que dar las expresiones para calcular los valores agregados con el agrupamiento de un subconjunto S de los atributos de la relación r(A, B, C, D, E), dados los valores agregados para agrupamiento de los atributos T ⊇ S para las siguientes funciones de agregación: a. sum, count, min y max b. avg c. Desviación estándar 18.9 Dese un ejemplo de un par de agrupamientos que no puedan expresarse utilizando una sola cláusula group by con cube y con rollup. 18.10 Dada la relación r(a, b, c), muéstrese el modo de utilizar las características ampliadas de SQL para generar un histograma de c frente a a, dividiendo a en veinte particiones de igual tamaño (es decir, que cada partición contenga el cinco por ciento de las tuplas de r, ordenadas según a). 18.11 Considérese el atributo saldo de la relación cuenta. Escríbase una consulta en SQL para calcular un histograma de los valores de saldo, dividiendo el rango desde cero hasta el máximo saldo de una cuenta presente, en tres rangos iguales. 18.12 Créese un clasificador de árboles de decisión con divisiones binarias en cada nodo utilizando las tuplas de la relación r(A, B, C) que se muestra más abajo como datos de formación; el atributo C denota la clase. Muéstrese el árbol final y, con cada nodo, muéstrese la mejor división para cada atributo junto con su valor de ganancia de la información. (1, 2, a), (2, 1, a), (2, 5, b), (3, 3, b), (3, 6, b), (4, 5, b), (5, 5, c), (6, 3, b), (6, 7, c)

www.detodoprogramacion.com


628

Capítulo 18

Análisis y minería de datos

18.13 Supóngase que la mitad de las transacciones de una tienda de ropa adquieren vaqueros y un tercio de las transacciones de la tienda adquieren camisetas. Supóngase también que la mitad de las transacciones que adquieren vaqueros también adquieran camisetas. Hay que anotar todas las reglas de asociación (no triviales) que se puedan deducir de esta información, dando el soporte y la confianza de cada regla. 18.14 Considérese el problema de hallar conjuntos de artículos de gran tamaño. a. Descríbase el modo de hallar el soporte de un conjunto dado de conjuntos de elementos mediante una sola exploración de los datos. Supóngase que los conjuntos de artículos y la información asociada, como los recuentos, caben en la memoria. b. Supóngase que un conjunto de artículos tiene un soporte menor que j. Muéstrese que ningún superconjunto de este conjunto de artículos puede tener un soporte mayor o igual que j. 18.15 Créese un ejemplo pequeño de un conjunto de transacciones que demuestren que aunque muchas transacciones contengan dos artículos (es decir, el conjunto de artículos que contien los dos artículos tiene un gran soporte), la compra de uno de los artículos puede tener una correlación negativa con la compra del otro. 18.16 La organización de partes, capítulos, apartados y subapartados de un libro está relacionada con el agrupamiento. Explíquense la razón y la forma de agrupamiento. 18.17 Propóngase la forma de usar las técnicas de minería en un equipo de deporte usando su deporte preferido como ejemplo. Notas bibliográ cas

Gray et al. [1995] y Gray et al. [1997] describen el operador cubo de datos. Los algoritmos eficientes para calcular cubos de datos se describen en Agarwal et al. [1996], Harinarayan et al. [1996] y Ross y Srivastava [1997]. Las descripciones del soporte ampliado de la agregación en SQL:1999 puede hallarse en los manuales de los productos de sistemas de bases de datos como Oracle y DB2 de IBM. Las definiciones de las funciones estadísticas pueden hallarse en los libros de texto normales de estadística como Bulmer [1979] y Ross [1999]. Los libros de texto Poe [1995] y Mattison [1996] estudian los almacenes de datos. Zhuge et al. [1995] describe el mantenimiento de vistas en un entorno de almacenes de datos. Chaudhuri et al. [2003] describe las técnicas para el encaje difuso en la limpieza de datos, mientras que Sarawagi et al. [2002] describe un sistema para la desduplicación usando técnicas de aprendizaje activo. Witten y Frank [1999] y Han y Kamber [2000] proporcionan cobertura del nivel de los libros de texto de la minería de datos. Mitchell [1997] es un libro de texto clásico sobre aprendizaje de las máquinas y trata con detalle las técnicas de clasificación. Fayyad et al. [1995] presenta un extenso conjunto de artículos sobre el descubrimiento de conocimiento y la minería de datos. Kohavi y Provost [2001] presenta un conjunto de artículos sobre aplicaciones de la minería de datos para el comercio electrónico. Agrawal et al. [1993b] proporcionan una primera introducción a la minería de datos en las bases de datos. En Agrawal et al. [1992] y Shafer et al. [1996] se describen algoritmos para el cálculo de clasificadores con conjuntos de formación de gran tamaño; el algoritmo de creación del árbol de decisión descrito en este capítulo se basa en el algoritmo SPRINT de Shafer et al. [1996]. Agrawal et al. [1993a] introdujo la noción de reglas de asociación, mientras que Agrawal y Srikant [1994] presentó un algoritmo eficiente para la minería de reglas de asociación. Los algoritmos para la minería de diferentes formas de las reglas de asociación se describen en Srikant y Agrawal [1996a] y en Srikant y Agrawal [1996b]. Chakrabarti et al. [1998] describen las técnicas para la minería de estructuras temporales sorprendentes. Las técnicas para la integración de cubos de datos se describen en Sarawagi [2000]. Durante mucho tiempo se ha estudiado el agrupamiento en el área de la estadística, y Jain y Dubes [1988] proporciona cobertura del agrupamiento del nivel de los libros de texto. Ng y Han [1994] describe las técnicas del agrupamiento espacial. Las técnicas de agrupamiento para conjuntos de datos de gran tamaño se describen en Zhang et al. [1996]. Breese et al. [1998] proporciona un análisis empírico de diferentes algoritmos para el filtrado cooperativo. Las técnicas para el filtrado cooperativo de los artículos de noticias se describen en Konstan et al. [1997].

www.detodoprogramacion.com


Herramientas

629

El libro de texto Chakrabarti [2002] proporciona una descripción de recuperación de información, incluyendo un extenso tratamiento de las tareas de minería de datos relacionadas con los datos textuales y de hipertexto, tales como la clasificación y el agrupamiento. Chakrabarti [2000] proporciona una recopilación de técnicas de minería de hipertexto como la clasificación y el agrupamiento de hipertexto. Herramientas

Se dispone de gran variedad de herramientas para cada una de las aplicaciones que se han estudiado en este capítulo. La mayor parte de los fabricantes de bases de datos proporcionan herramientas OLAP como parte de sus sistemas de bases de datos, o como aplicaciones complementarias. Entre ellas están las herramientas OLAP de Microsoft Corp., Oracle Express e Informix Metacube. La herramienta OLAP Arbor Essbase procede de un fabricante de software independiente. El sitio www.databeacon.com proporciona una demostración en línea de las herramientas OLAP de Databeacon para su empleo en la Web y en orígenes de datos de archivos de texto. Muchas empresas también ofrecen herramientas de análisis para aplicaciones específicas, como la gestión de las relaciones con los clientes. Los principales fabricantes de bases de datos también ofrecen almacenes de datos acoplados a sus sistemas de bases de datos. Proporcionan ayuda para el modelado de datos, limpieza, carga y consultas. El sitio web www.dwinfocenter.org proporciona información de los almacenes de datos. También hay una gran variedad de herramientas de minería de datos de propósito general que incluyen las herramientas de minería del SAS Institute, IBM Intelligent Miner y SGI Mineset. Se necesita una gran experiencia para aplicar las herramientas de minería de datos de propósito general para aplicaciones concretas. En consecuencia, se han desarrollado gran número de herramientas de minería para abordar aplicaciones especializadas. El sitio web www.kdnuggets.com proporciona un amplio directorio de software de minería de datos, soluciones, publicaciones, etc.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

19

Recuperación de información

Los datos de texto no están estructurados, a diferencia de los datos rígidamente estructurados de las bases de datos relacionales. El término recuperación de información suele hacer referencia a la consulta de datos de texto no estructurados. Los sistemas de recuperación de información tienen mucho en común con los sistemas de bases de datos, en especial, el almacenamiento y la recuperación de los datos del almacenamiento secundario. No obstante, el énfasis en el campo de los sistemas de información es diferente del de los sistemas de bases de datos y se centra en problemas como las consultas basadas en palabras clave; la relevancia de los documentos para la consulta y el análisis, la clasificación y el indexado de documentos. 19.1 Visión general

El campo de la recuperación de información se ha desarrollado en paralelo con el campo de las bases de datos. En el modelo tradicional usado en el campo de la recuperación de información, ésta se organiza en documentos, dando por supuesto que existe un gran número de documentos. Los datos contenidos en los documentos no están estructurados, no tienen ningún esquema asociado. El proceso de recuperación de información consiste en localizar los documentos importantes, de acuerdo con los datos suministrados por el usuario, como las palabras clave o los documentos de ejemplo. Web ofrece una manera cómoda de llegar a las fuentes de información y de interactuar con ellas a través de Internet. No obstante, un problema persistente que sufre Web es la explosión de la información almacenada, con pocas indicaciones que ayuden al usuario a localizar la que es interesante. La recuperación de información ha desempeñado un papel crítico para hacer que Web sea una herramienta productiva y útil, especialmente para los investigadores. Ejemplos tradicionales de sistemas de recuperación de información son los catálogos de bibliotecas en línea y los sistemas de gestión de la documentación en línea como los que almacenan los artículos de los periódicos. Los datos de estos sistemas se organizan como conjuntos de documentos; los artículos de los periódicos y las entradas de los catálogos (en los catálogos de las bibliotecas) son ejemplos de documentos. En el contexto de Web, se suele considerar cada página HTML como un documento. Los usuarios de esos sistemas puede que deseen recuperar un documento concreto o una clase de documentos concreta. Los documentos deseados se suelen describir mediante un conjunto de palabras clave—por ejemplo, las palabras clave “sistema de bases de datos” se pueden usar para localizar los libros sobre sistemas de bases de datos y las palabras clave “valores” y “escándalo” se pueden usar para localizar artículos sobre escándalos de los mercados de valores. Cada documento tiene asociado un conjunto de palabras clave y se recuperan los documentos cuyas palabras clave contienen las facilitadas por los usuarios. La recuperación de información basada en las palabras clave no sólo se puede usar para recuperar datos de texto, sino también para recuperar otros tipos de datos, como los datos de vídeo o de sonido, que 631

www.detodoprogramacion.com


632

Capítulo 19

Recuperación de información

tengan asociadas palabras clave descriptivas. Por ejemplo, una película de vídeo puede tener asociadas palabras clave como el título, el director, los actores, el tipo de película, etc. Existen varias diferencias entre este modelo y los modelos usados en los sistemas tradicionales de bases de datos. • Los sistemas de bases de datos gestionan varias operaciones que no se abordan en los sistemas de recuperación de información. Por ejemplo, los sistemas de bases de datos gestionan las actualizaciones y los requisitos transaccionales asociados con el control de concurrencia y de durabilidad. Estos asuntos se consideran menos importantes en los sistemas de información. De manera parecida, los sistemas de bases de datos gestionan información estructurada organizada mediante modelos de datos relativamente complejos (como el modelo relacional o los modelos de datos orientados a los objetos), mientras que los sistemas de recuperación de información han usado tradicionalmente un modelo mucho más sencillo, en el que la información de la base de datos se organiza simplemente como un conjunto de documentos sin estructurar. • Los sistemas de recuperación de información afrontan varios problemas que no se han abordado de manera adecuada en los sistemas de bases de datos. Por ejemplo, el campo de la recuperación de información ha tratado los problemas de la gestión de documentos sin estructurar, como la búsqueda aproximada mediante palabras clave y de la clasificación de los documentos por el grado estimado de relevancia de cada documento para la consulta. Los sistemas de recuperación de información suelen permitir las expresiones de consulta formadas mediante palabras clave y las conectivas lógicas y, o y no. Por ejemplo, el usuario puede pedir todos los documentos que contengan las palabras clave “motocicleta y mantenimiento”, o los documentos que contienen las palabras clave “computadora o microprocesador”, o incluso los documentos que contienen la palabra clave “computadora pero no base de datos”. Se da por supuesto que una consulta que contenga palabras clave sin ninguna de las conectivas indicadas usa y para conectar las palabras clave de manera implícita. En la recuperación de texto completo se considera que todas las palabras de cada documento son palabras clave. Para los documentos no estructurados la recuperación de texto completo resulta fundamental, ya que puede que no haya información sobre las palabras del documento que son palabras clave. Se usará la palabra término para hacer referencia a las palabras de los documentos, ya que todas las palabras son palabras clave. En su forma más sencilla los sistemas de recuperación de información buscan y devuelven todos los documentos que contienen todas las palabras clave de la consulta, si es que no tiene conectivas; las conectivas se manejan de la forma esperada. Los sistemas más sofisticados estiman la relevancia de cada documento para la consulta, de modo que se puedan mostrar ordenados según esta relevancia. Estos sistemas usan información sobre las apariciones de los términos, así como la información de los hipervínculos, para estimar la relevancia.

19.2 Clasi cación por relevancia según los términos

El conjunto de los documentos que satisfacen una expresión de consulta puede ser muy grande; en concreto, hay miles de millones de documentos en Web y la mayor parte de las consultas por palabras clave en los motores de búsqueda de Web hallan centenares de millares de documentos que contienen esas palabras clave. La recuperación de texto completo agrava este problema: cada documento puede contener muchos términos, incluso términos que sólo se mencionan de pasada se tratan de manera equivalente a documentos en los que el término sí es importante. En consecuencia, puede que se recuperen documentos irrelevantes. Por tanto, los sistemas de recuperación de información estiman la relevancia de cada documento para la consulta y sólo devuelven como respuestas los documentos con una clasificación más elevada. La clasificación por relevancia no es una ciencia exacta, pero hay algunos enfoques aceptados ampliamente.

www.detodoprogramacion.com


19.2

Clasificación por relevancia según los términos

633

19.2.1 Clasi cación según TF-IDF

El primer punto que hay que abordar es, dado un término concreto t, averiguar la relevancia para ese término de un documento dado d. Un enfoque es usar el número de apariciones del término en el documento como medida de su relevancia, con la suposición de que es probable que los términos importantes se mencionen muchas veces en el documento. El mero recuento del número de apariciones de un término no suele ser un buen indicador: en primer lugar, el número de apariciones depende de la longitud del documento y, en segundo lugar, puede que un documento que contenga diez apariciones del término no tenga diez veces la relevancia de un documento que contenga una sola aparición. Un modo de medir T F (d, t), la relevancia del documento d para el término t, es ¶ µ n(d, t) T F (d, t) = log 1 + n(d) donde n(d) denota el número de términos del documento y n(d, t) denota el número de apariciones del término t en el documento d. Obsérvese que esta métrica tiene en cuenta la longitud del documento. La relevancia crece con el número de apariciones del término en el documento, aunque no es directamente proporcional al número de apariciones. Muchos sistemas refinan esta métrica usando otra información. Por ejemplo, si el término aparece en el título, o en la lista de autores o en el resumen, el documento se considera más importante para el término. De manera parecida, si la primera aparición del término se produce muy avanzado el documento, el documento se puede considerar menos importante que si aparece por primera vez al principio del documento. Los conceptos anteriores pueden formalizarse mediante extensiones de la fórmula que se ha mostrado para T F (d, t). En la comunidad de recuperación de información la relevancia de un documento para un término se denomina frecuencia del término (Term Frequency, TF), independientemente de la fórmula concreta usada. Una consulta C puede contener varias palabras clave. La relevancia de cada documento para una consulta con dos o más palabras clave se estima combinando las medidas de relevancia del documento para cada palabra clave. Una manera sencilla de combinar las medidas es sumarlas. No obstante, no todos los términos usados como palabras clave son iguales. Supóngase que una consulta usa dos términos, uno de los cuales aparece con frecuencia, como “base de datos”, y otro que es menos frecuente, como “Silberschatz”. Un documento que contenga “Silberschatz” pero no “base de datos” debe clasificarse por encima de otro que contenga “base de datos” pero no “Silberschatz”. Para solucionar este problema se asignan pesos a los términos usando la frecuencia inversa de los documentos (Inverse Document Frequency, IDF), definida como IDF (t) =

1 n(t)

donde n(t) denota el número de documentos (entre los indexados por el sistema) que contienen el término t. La relevancia del documento d para el conjunto de términos C se define como r(d, C) =

X

T F (d, t) ∗ IDF (t)

t∈C

Esta medida puede refinarse aún más si se permite a los usuarios especificar los pesos p(t) de los términos de la consulta, en cuyo caso los pesos especificados por los usuarios se tienen también en cuenta multiplicando T F (t) por p(t) en la fórmula anterior. Este enfoque de usar la frecuencia de los términos y la frecuencia inversa de los documentos como medida de la relevancia de los documentos se denomina enfoque TF-IDF. Casi todos los documentos de texto (en español) contienen palabras como “y”, “o”, “un”, etc. y, por tanto, estas palabras resultan inútiles para propósitos de consulta, ya que su frecuencia inversa de documentos es extremadamente baja. Los sistemas de recuperación de información definen un conjunto de palabras, denominadas palabras de parada, que contiene aproximadamente cien de las palabras más frecuentes, e ignoran esas palabras al indexar los documentos. Esas palabras no se usan como palabras clave, y se descartan si se hallan entre las palabras proporcionadas por los usuarios.

www.detodoprogramacion.com


634

Capítulo 19

Recuperación de información

Otro factor que se tiene en cuenta cuando una consulta contiene varios términos es la proximidad de los términos en el documento. Si los términos aparecen cercanos entre sí en el documento, el documento se clasificará en una posición más elevada que si aparecen muy separados. La fórmula de r(d, C) puede modificarse para tener en cuenta la proximidad. Dada una consulta C, el trabajo del sistema de recuperación de información es devolver documentos en orden descendente de relevancia para C. Dado que puede haber un número muy grande de documentos que sean relevantes, los sistemas de recuperación de información suelen devolver únicamente los primeros documentos con el grado de relevancia estimada más elevado y permiten que los usuarios soliciten más documentos de manera interactiva. 19.2.2 Recuperación basada en la semejanza

Algunos sistemas de recuperación de información permiten la recuperación basada en la semejanza. En este caso, el usuario puede dar al sistema el documento A y pedirle que recupere documentos que sean “semejantes” a A. La semejanza de un documento con otro puede definirse, por ejemplo, con base en los términos comunes. Un enfoque es hallar k términos de A con los valores más elevados de T F (A, t) ∗ IDF (t), y usar esos k términos como consulta para hallar la relevancia de otros documentos. Los términos de la consulta se pesan mediante T F (A, t) ∗ IDF (t). Más genéricamente, la semejanza de los documentos se define mediante la métrica de semejanza del coseno. Sean los términos que aparecen en cualquiera de los dos documentos t1 , t2 , . . . , tn . Sea r(d, t) = T F (d, t) ∗ IDF (t). Entonces, la métrica de semejanza del coseno entre los documentos d y e se define como Pn r(d, ti )r(e, ti ) pPn i=1 pPn 2 r(d, ti )2 i=1 i=1 r(e, ti ) Se puede comprobar fácilmente que la métrica de la semejanza del coseno de un documento consigo mismo es 1, mientras que entre dos documentos que no compartan ningún término es 0. La denominación “semejanza del coseno” procede del hecho de que la fórmula anterior calcula el coseno del ángulo entre dos vectores, cada uno de los cuales representa a uno de los documentos, definido de la manera siguiente. Supóngase que hay n palabras en total en todos los documentos que se vayan a considerar. Se define un espacio n-dimensional, con cada palabra como una de las dimensiones. El documento d se representa mediante un punto de este espacio, con el valor de la coordenada i-ésima del punto igual a r(d, ti ). El vector del documento d conecta el origen (todas las coordenadas iguales a cero) con el punto que representa al documento. El modelo de documentos como puntos y vectores de un espacio n-dimensional se denomina modelo de espacio vectorial. Si el conjunto de documentos semejantes al documento A de la consulta es grande, puede que el sistema sólo presente al usuario unos cuantos documentos semejantes, le permita escoger los más destacados e inicie una nueva búsqueda basada en la semejanza con A y con los documentos seleccionados. Es posible que el conjunto de documentos resultante sea lo que el usuario pretendía hallar. Esta idea se denomina realimentación de la relevancia. La realimentación de la relevancia se puede usar también para ayudar a los usuarios a encontrar los documentos importantes de entre un conjunto grande de documentos que coinciden con las palabras clave de consulta dadas. En esta situación se puede permitir que los usuarios identifiquen uno o varios de los documentos devueltos como importantes; el sistema usará los documentos identificados para hallar otros semejantes. Es probable que el conjunto de documentos resultante sea lo que el usuario pretendía hallar. Una alternativa al enfoque de la realimentación de la relevancia es exigir a los usuarios que modifiquen la consulta añadiendo más palabras clave; la realimentación de la relevancia puede resultar más sencilla de usar, además de dar como respuesta un conjunto final de documentos más adecuado. Para mostrar al usuario un conjunto representativo de documentos cuando el número total es muy grande, el sistema de búsqueda puede agrupar los documentos, basándose en la semejanza del coseno. La agrupación ya se ha descrito en el Apartado 18.4.5, y se han desarrollado varias técnicas para agrupar los conjuntos de documentos. Véanse las notas bibliográficas para hallar referencias sobre más información relativa a la agrupación.

www.detodoprogramacion.com


19.3

Relevancia según los hipervínculos

635

19.3 Relevancia según los hipervínculos

Los primeros motores de búsqueda Web clasificaban los documentos usando sólo medidas de relevancia basadas en TF-IDF como las descritas en el Apartado 19.2. Sin embargo, estas técnicas presentaban algunas limitaciones cuando se usaban sobre conjuntos muy grandes de documentos, como el conjunto de todas las páginas Web. En concreto, muchas páginas Web tienen todas las palabras clave especificadas en las consultas típicas del motor de búsqueda; además, algunas de las páginas que los usuarios desean obtener como respuesta a menudo sólo tienen unas cuantas apariciones de los términos de la consulta y no consiguen una puntuación TF-IDF muy elevada. No obstante, los investigadores pronto se dieron cuenta de que las páginas Web contienen información muy importante de la que carecen los documentos de texto sencillo, por ejemplo, los hipervínculos. Los hipervínculos se pueden aprovechar para obtener una mejor clasificación por relevancia; en concreto, la clasificación de relevancia de una página está muy influida por los hipervínculos que apuntan a esa página. En este apartado se estudia la manera en que se usan los hipervínculos para la clasificación de las páginas Web. 19.3.1 Clasi cación por popularidad

La idea básica de la clasificación por popularidad (también denominada clasificación por prestigio) es hallar páginas que sean populares, y clasificarlas por encima de otras páginas que contengan las palabras clave especificadas. Dado que la mayor parte de las búsquedas pretenden hallar información de las páginas más populares, clasificar esas páginas en posiciones más elevadas suele ser una buena idea. Por ejemplo, el término “google” puede aparecer en gran número de páginas, pero la página google.com es el sitio más popular de entre las páginas que contienen el término “google”. Por tanto, la página google.com debe clasificarse como la respuesta más importante de las consultas que consistan en el término “google”. Las medidas tradicionales de la relevancia de una página, como las basadas en TF-IDF que se vieron en el Apartado 19.2, pueden combinarse con la popularidad de la página para obtener una medida global de la relevancia de la página para la consulta. Las páginas con el valor más elevado de relevancia global se devuelven como primeras respuestas de la consulta. Esto suscita la pregunta del modo de definir y averiguar la popularidad de una página. Una manera es hallar la cantidad de veces que se tiene acceso a la página y usar ese número como medida de la popularidad de ese sitio. Sin embargo, la obtención de esa información es imposible sin la cooperación del sitio, y no les es factible implementarla a los motores de búsqueda Web. Una alternativa muy efectiva es usar los hipervínculos a la página como medida de su popularidad. Mucha gente tiene archivos de marcadores que contienen vínculos a sitios que usan con frecuencia. Se puede deducir que los sitios que aparecen en gran número de archivos de marcadores son muy populares. Los archivos de marcadores se suelen almacenar de manera privada y no suelen ser accesibles en Web. No obstante, muchos usuarios tienen páginas Web con vínculos a sus páginas Web favoritas. Muchos sitios Web también tienen vínculos a otros sitios relacionados, que también se pueden usar para deducir la popularidad de los sitios vinculados. Los motores de búsqueda de Web pueden capturar páginas Web (mediante un proceso denominado batida (crawling), que se describe en el Apartado 19.7) y analizarlas para hallar los vínculos entre unas y otras. Una primera solución para estimar la popularidad de las páginas es usar el número de páginas que enlazan con ellas como medida de su popularidad. Sin embargo, esto en sí mismo tiene el inconveniente de que muchos sitios tienen varias páginas útiles, pero los vínculos externos a menudo sólo apuntan a la página raíz de cada sitio. La página raíz, a su vez, tiene vínculos con otras páginas del sitio. Se puede deducir, entonces, erróneamente, que esas otras páginas no son muy populares y tendrán una clasificación baja en las respuestas a las consultas. Una alternativa es asociar la popularidad con los sitios, en vez de con las páginas. Todas las páginas de un sitio dado tienen la popularidad de ese sitio, y las páginas distintas de la página raíz de los sitios populares se benefician también de la popularidad de esos sitios. Sin embargo, surge la pregunta de qué constituye un sitio. Por lo general, el prefijo de la dirección de Internet del URL de una página constituye el sitio correspondiente a esa página. No obstante, hay muchos sitios que albergan gran número de páginas muy poco relacionadas entre sí, como los servidores de páginas iniciales de las universidades y

www.detodoprogramacion.com


636

Capítulo 19

Recuperación de información

de los portales Web como groups.yahoo.com o tripod.com. Para estos sitios, la popularidad de una parte del sitio no implica la popularidad de otras partes del mismo sitio. Una alternativa más sencilla es permitir la transferencia de prestigio desde las páginas populares a las páginas con las que se vinculan. De acuerdo con este esquema, a diferencia con el principio de “un hombre, un voto” de la democracia, el vínculo desde una página popular x a una página y se considera que confiere más prestigio a la página y que un vínculo desde la página no tan popular z 1 . Esta definición de popularidad es, de hecho, circular, ya que la popularidad de las páginas queda definida por la popularidad de otras páginas, y puede que haya ciclos de vínculos entre las páginas. No obstante, la popularidad de las páginas puede definirse mediante un sistema de ecuaciones lineales simultáneas, que pueden resolverse mediante las técnicas de tratamiento de matrices. Las ecuaciones lineales se definen de manera que tengan una solución única y bien definida. Es interesante destacar que la idea básica subyacente a las clasificaciones de popularidad es, en realidad, bastante antigua y surgió por primera vez en la teoría de redes sociales desarrollada por los sociólogos de los años cincuenta del siglo veinte. En el contexto de las redes sociales el objetivo era definir el prestigio de las personas. Por ejemplo, el rey de España tiene un elevado prestigio, ya que gran cantidad de gente lo conoce. Si alguien es conocido por varias personas de prestigio, también tendrá un prestigio elevado, aunque no sea conocido por un número de personas tan grande. El uso de conjuntos de ecuaciones lineales para definir las medidas de popularidad también procede de estos trabajos.

19.3.2 PageRank

El motor de búsqueda Web Google introdujo PageRank, que es una medida de la popularidad de las páginas basada en la popularidad de las páginas que vinculan con ellas. El uso de la medida de popularidad PageRank para clasificar las respuestas a las consultas de resultados, que mejoran las de las técnicas de clasificación usadas anteriormente, hizo que Google pasara a ser el motor de búsqueda más usado en un periodo de tiempo bastante breve. PageRank se puede comprender de manera intuitiva si se usa un modelo de recorrido aleatorio. Supóngase que una persona que navega por Web lleva a cabo un paseo aleatorio (transversal) de las páginas Web de la manera siguiente: El primer paso parte de una página Web aleatoria y, en cada paso, el paseante aleatorio emprende una de las acciones siguientes. Con una probabilidad δ el paseante salta a una página Web escogida aleatoriamente y, con una probabilidad de 1 − δ, escoge aleatoriamente uno de los vínculos externos de la página Web en la que se halla y sigue ese vínculo. El valor de PageRank de cada página es, por tanto, la probabilidad de que el paseante aleatorio visite la página en cualquier momento dado. Téngase en cuenta que es más probable que se visiten las páginas a las que apuntan muchas páginas Web y, por tanto, tendrán un valor de PageRank más elevado. De manera parecida, las páginas a las que apuntan páginas con un valor de PageRank elevado también tendrán mayor probabilidad de que las visiten y, por tanto, tendrán un valor de PageRank más elevado. PageRank se puede definir mediante un conjunto de ecuaciones lineales, de la manera siguiente. En primer lugar, se otorga a cada página Web un identificador entero. La matriz de las probabilidades de salto T se define con T [i, j] definida como la probabilidad de que un paseante aleatorio que siga un vínculo externo de la página i siga el vínculo a la página j. Suponiendo que cada vínculo de i tiene igual probabilidad de que lo sigan, T [i, j] = 1/Ni , donde Ni es el número de vínculos externos de la página i. La mayor parte de las entradas de of T son 0 y se representa mejor mediante una lista de adyacentes. Por tanto, el valor de PageRank P [j] para cada página j se puede definir como P [j] = δ/N + (1 − δ) ∗

N X

(T [i, j] ∗ P [i])

i=1

donde δ es una constante entre 0 y 1 y N es el número de páginas; δ representa la probabilidad de que cada paso del paseo aleatorio sea un salto. 1. Esto es parecido, en cierto sentido, a conceder un peso extra al aval que personas famosas (como las estrellas de cine) conceden a ciertos productos, por lo que su importancia es discutible, aunque resulta efectivo y en la práctica se usa mucho.

www.detodoprogramacion.com


19.3

Relevancia según los hipervínculos

637

El conjunto de ecuaciones generado de esta manera se suele resolver mediante técnicas iterativas, comenzando con cada P [i] definida como 1/N . Cada paso de la iteración calcula valores nuevos de cada P [i] usando los valores de P de la iteración anterior. La iteración se detiene cuando la variación máxima entre iteraciones de cualquier valor de P [i] queda por debajo de un valor de corte prefijado. 19.3.3 Otras medidas de popularidad

Las medidas básicas de popularidad como PageRank desempeñan un papel importante en la clasificación de las respuestas a las consultas, pero no son, de ningún modo, el único factor. La puntuación TF-IDF de cada página se usa para evaluar su relevancia para las palabras clave de la consulta y se deben combinar con la clasificación de popularidad. También se deben tener en cuenta otros factores, para superar las limitaciones de PageRank y de otras medidas de popularidad relacionadas. Un inconveniente del algoritmo de PageRank es que asigna una medida de popularidad que no tiene en cuenta las palabras clave de la consulta. Por ejemplo, es probable que la página google.com tenga un valor de PageRank muy elevado, ya que muchos sitios contienen vínculos con ella. Supóngase que contiene una palabra mencionada de pasada, como “Stanford” (la página de búsqueda avanzada de Google contenía de hecho la palabra Stanford, al menos hasta principios de 2005). La búsqueda con la palabra clave Stanford devolvería google.com como respuesta mejor clasificada, por delante de respuestas más relevantes, como la página Web de la Universidad de Stanford. Una solución de este problema muy usada es emplear palabras clave en el texto ancla de los vínculos a una página para evaluar para qué temas es importante la página. El texto ancla de los vínculos consiste en el texto que aparece dentro de la etiqueta a href de HTML. Por ejemplo, el texto ancla del vínculo <a href="http://stanford.edu"> Stanford University</a> es “Stanford University”. Si muchos vínculos a stanford.edu contienen la palabra Stanford en su texto ancla, se puede considerar muy importante para la palabra la palabra clave Stanford. El texto cercano al texto ancla también se puede tomar en consideración; por ejemplo, un sitio Web puede contener el texto “Ésta es la página Web de la Universidad de Stanford”, pero puede haber usado sólo la palabra “ésta” como texto ancla en el vínculo al sitio Web de la Universidad de Stanford. La popularidad basada en el texto ancla se combina con otras medidas de la popularidad y con las medidas TF-IDF para obtener una clasificación global de las respuestas a las consultas. Téngase en cuenta que la mayor parte de los motores de búsqueda no revelan la manera en que calculan las clasificaciones de relevancia; consideran que revelar sus técnicas de clasificación permitiría a sus competidores alcanzarlos y facilitaría la labor de “contaminación de los motores de búsqueda”, lo que daría lugar a una menor calidad de los resultados. La contaminación de los motores de búsqueda se describe con más detalle posteriormente en este apartado. Un enfoque alternativo a la toma en cuenta de las palabras clave al definir la popularidad es calcular una medida de la popularidad que use sólo las páginas que contienen las palabras clave de la consulta, en lugar de calcular la popularidad usando todas las páginas Web disponibles. Este enfoque resulta más costoso, ya que el cálculo de las clasificaciones de popularidad tiene que llevarse a cabo de manera dinámica cuando se recibe la consulta, mientras que PageRank se calcula una vez de manera estática y se reutiliza para todas las consultas. Los motores de búsqueda en Web que manejan miles de millones de consultas diarias no se pueden permitir emplear tanto tiempo en contestar cada consulta. En consecuencia, aunque este enfoque puede dar mejores respuestas, no se usa mucho. El algoritmo HITS se basaba en la idea anterior de hallar primero las páginas que contienen las palabras clave de la consulta y calcular luego una medida de la popularidad usando sólo ese conjunto de páginas relacionadas. Además, introdujo el concepto de nodos y de autoridades. Un nodo es una página que almacena vínculos con muchas páginas; no contiene información real sobre el asunto, pero apunta a páginas que sí que la contienen. Por el contrario, una autoridad es una página que contiene información real sobre un asunto, aunque puede que no almacene vínculos con muchas páginas relacionadas. Cada página recibe un valor de prestigio como nodo (prestigio-nodo) y otro valor de prestigio como autoridad (prestigio-autoridad). Las definiciones de prestigio, como ya se ha visto, son cíclicas y vienen dadas por un conjunto de ecuaciones lineales simultáneas. Las páginas obtienen mayor prestigio-nodo si apuntan a muchas páginas con un elevado prestigio-autoridad, mientras que reciben un elevado prestigio-

www.detodoprogramacion.com


638

Capítulo 19

Recuperación de información

autoridad si apuntan a ellas muchas páginas con un elevado prestigio-nodo. Dada una consulta, las páginas con prestigio-autoridad más elevado se clasifican por encima de las demás páginas. Véanse las notas bibliográficas para hallar referencias que ofrezcan más detalles. La contaminación de los motores de búsqueda hace referencia a la práctica de crear páginas Web, o conjuntos de páginas Web, diseñados para obtener una clasificación de relevancia elevada para algunas consultas, aunque los sitios no sean realmente populares. Por ejemplo, puede que un sitio sobre viajes desee obtener una clasificación elevada para las consultas con la palabra clave “viaje”. Puede obtener puntuaciones TF-IDF elevadas mediante la repetición de la palabra “viaje” muchas veces en su página2 . Incluso los sitios sin relación con los viajes, como los sitios pornográficos, pueden hacer lo mismo, y obtener clasificaciones elevadas para las consultas sobre la palabra viaje. De hecho, este tipo de contaminación de TF-IDF era frecuente en los primeros días de la búsqueda en Web, y hubo una batalla constante entre este tipo de sitios y los motores de búsqueda que intentaban detectar la contaminación e impedir que consiguieran clasificaciones elevadas. Los esquemas de clasificación de la popularidad como PageRank hacen más difícil la labor de contaminación de los motores de búsqueda, ya que la mera repetición de palabras para obtener puntuaciones TF-IDF elevada ya no es suficiente. No obstante, incluso estas técnicas se pueden contaminar, mediante la creación de un conjunto de páginas Web que se apunten entre sí, lo que incrementa su clasificación de popularidad. Se han propuesto técnicas como el uso de los sitios en lugar de las páginas como unidad de clasificación (con las probabilidades normalizadas de salto correspondientes) para evitar algunas técnicas de contaminación. La guerra entre los contaminadores de los motores de búsqueda y los motores de búsqueda continúa incluso hoy en día. El enfoque de nodos y autoridades del algoritmo HITS es más susceptible de contaminación. El contaminador puede crear una página Web que contenga vínculos con autoridades auténticas de un asunto dado y obtener en consecuencia una puntuación de nodo elevada. Además, Web del contaminador incluye vínculos a páginas que desea popularizar, que puede que no tengan ninguna relevancia para ese asunto. Como a estas páginas las apunta una página con una puntuación de nodo elevada, obtienen una puntuación de autoridad elevada pero inmerecida.

19.4 Sinónimos, homónimos y ontologías

Considérese el problema de la localización de documentos sobre el mantenimiento de motocicletas, usando la consulta “mantenimiento de motocicletas”. Supóngase que las palabras clave de cada documento son las palabras del título y el nombre de los autores. El documento titulado Reparación de motocicletas no se recuperaría, ya que la palabra “mantenimiento” no aparece en el título. Se puede resolver este problema haciendo uso de los sinónimos. Cada palabra puede tener definido un conjunto de sinónimos, y la aparición de una palabra puede ser sustituida por la disyunción de todos sus sinónimos (incluida la propia palabra). Así, la consulta “motocicleta y reparación” puede sustituirse por “motocicleta y (reparación o mantenimiento)”. Esta consulta sí hallaría el documento deseado. Las consultas basadas en las palabras clave también se ven afectadas por el problema contrario, el de los homónimos, es decir, las palabras con varios significados. Por ejemplo, la palabra “objeto” tiene significados diferentes como nombre y como verbo. La palabra “tabla” puede hacer referencia a una pieza de madera o a una tabla de una base de datos relacional. De hecho, un riesgo de usar los sinónimos para ampliar las consultas es que los sinónimos pueden tener, a su vez, significados diferentes. Por ejemplo, “sustento” es sinónimo de uno de los significados de la palabra “mantenimiento”, pero tiene un significado diferente del pretendido por el usuario en la consulta “mantenimiento de motocicletas”. Se recuperarán los documentos que utilicen un significado implícito alternativo. El usuario se preguntará el motivo de que el sistema considerara que alguno de los documentos recuperados (que, por ejemplo, usa la palabra “sustento”) era importante, si no contiene ni las palabras clave especificadas por el usuario ni palabras cuyo significado implícito en el documento sea 2. Las palabras repetidas en las páginas Web pueden confundir a los usuarios; los contaminadores pueden abordar este problema entregando páginas diferentes a los motores de búsqueda y al resto de los usuarios, para el mismo URL, o haciendo invisibles las palabras repetidas, por ejemplo, aplicando a esas palabras un formato de fuente blanca pequeña sobre fondo blanco.

www.detodoprogramacion.com


19.5

Creación de índices de documentos

639

sinónimo de las palabras clave especificadas. Por tanto, no es buena idea usar sinónimos para ampliar las consultas sin comprobarlos antes con el usuario. Un enfoque mejor del problema anterior es que el sistema comprenda el concepto que representa cada palabra del documento y, de manera parecida, comprenda el concepto que busca el usuario y devuelva los documentos que aborden los conceptos en los que está interesado el usuario. Los sistemas que soportan las consultas basadas en conceptos tienen que analizar cada documento para deshacer la ambigüedad de cada palabra del documento y sustituirla por el concepto que representa; la ruptura de la ambigüedad suele hacerse examinando las palabras circundantes en el documento. Por ejemplo, si el documento contiene palabras como base de datos o consulta, es probable que la palabra tabla sea sustituida por el concepto “tabla: datos”, mientras que, si el documento contiene palabras como muebles, silla o madera cerca de la palabra tabla, ésta sea sustituida por el concepto “tabla: carpintería”. La ruptura de la ambigüedad basada en las palabras cercanas suele ser más difícil con las consultas de los usuarios, ya que las consultas contienen muy pocas palabras, por lo que los sistemas de consultas basadas en los conceptos suelen ofrecer varios conceptos alternativos al usuario, que escoge uno o varios antes de que la búsqueda se reanude. Las consultas basadas en los conceptos tienen varias ventajas; por ejemplo, una consulta en un idioma puede recuperar documentos en otros idiomas, siempre y cuando se hallen relacionados con el mismo concepto. Se pueden usar luego mecanismos de traducción automática si el usuario no comprende el idioma en que está escrito el documento. No obstante, la sobrecarga del procesamiento de los documentos para deshacer la ambigüedad de las palabras es muy elevada si se trabaja con miles de millones de documentos. Por tanto, los motores de búsqueda de Internet no suelen soportar las consultas basadas en los conceptos. No obstante, se han creado sistemas de consultas basadas en los conceptos y se han usado para otros conjuntos documentales de gran tamaño. Las consultas basadas en los conceptos se pueden ampliar aún más aprovechando las jerarquías de conceptos. Por ejemplo, supóngase que alguien formula la consulta “animales voladores”; los documentos que contengan información sobre los “mamíferos voladores” son, ciertamente, importantes, ya que los mamíferos son animales. Sin embargo, los dos conceptos no son iguales y la mera coincidencia de conceptos no permite que se devuelva el documento como respuesta. Los sistemas de consultas basadas en los conceptos pueden soportar la recuperación de documentos basada en las jerarquías de conceptos. Las ontologías son estructuras jerárquicas que reflejan las relaciones entre los conceptos. La más frecuente es la relación es/son; por ejemplo, los leopardos son mamíferos, y los mamíferos son animales. También son posibles otras relaciones, como parte-de; por ejemplo, el ala del avión es parte del avión. El sistema WordNet define gran variedad de conceptos con palabras asociadas (denominadas synset, conjunto de sinónimos — synonym set—, en la terminología WordNet). Las palabras asociadas a un synset son sinónimos del concepto; por supuesto, cada palabra puede ser sinónima de varios conceptos diferentes. Además de los sinónimos, WordNet define homónimos y otras relaciones. En concreto, las relaciones es y parte — de que define conectan conceptos y definen de hecho ontologías. El proyecto Cyc fue otro intento de crear ontologías. Además de las ontologías que abarcan todo el idioma, se han definido ontologías para áreas concretas para tratar la terminología importante para esas áreas. Por ejemplo, se han creado ontologías para normalizar los términos usados en algunos negocios; se trata de un paso importante en la creación de una infraestructura normalizada para el tratamiento del procesamiento de pedidos y otros flujos de datos internos de las organizaciones. También es posible crear ontologías que vinculen varios idiomas. Por ejemplo, se han creado WordNets para diferentes idiomas, y los conceptos comunes entre los diferentes idiomas se pueden vincular entre sí. Este tipo de sistemas se puede usar para la traducción de textos. En el contexto de la recuperación de información, las ontologías multilingües se pueden usar para implementar búsquedas basadas en los conceptos en documentos escritos en varios idiomas. 19.5 Creación de índices de documentos

Una estructura de índices efectiva es importante para el procesamiento eficiente de las consultas en los sistemas de recuperación de información. Se pueden localizar los documentos que contienen las palabras clave especificadas de manera efectiva usando un índice invertido, que relaciona cada palabra

www.detodoprogramacion.com


640

Capítulo 19

Recuperación de información

clave Ci con el conjunto Si de (los identificadores de) los documentos que contienen Ci . Para dar soporte a la clasificación por relevancia basada en la proximidad de las palabras clave estos índices pueden proporcionar no sólo los identificadores de los documentos, sino también una lista de las ubicaciones dentro del documento en las que aparecen las palabras clave. Estos índices hay que almacenarlos en disco, y cada lista Si puede abarcar varias páginas de disco. Para minimizar el número de operaciones de E/S para la recuperación de cada lista Si , el sistema intentará guardar cada lista Si en un conjunto de páginas consecutivas del disco, de modo que toda la lista se pueda recuperar con una sola búsqueda en el disco. Se pueden usar índices de árbol B+ para asignar cada palabra clave Ci a su lista invertida asociada Si . La operación y halla los documentos que contienen todas las palabras clave del conjunto de palabras clave especificado C1 , C2 , . . . , Cn . La operación y se implementa recuperando primero los conjuntos de identificadores de documentos S1 , S2 , . . . , Sn de todos los documentos que contienen las palabras clave respectivas. La intersección S1 ∩ S2 ∩ · · · ∩ Sn , de los conjuntos de documentos da los identificadores de los documentos del conjunto de documentos deseado. La operación o da el conjunto de todos los documentos que contienen al menos una de las palabras clave C1 , C2 , . . . , Cn . La operación o se implementa calculando la unión, S1 ∪ S2 ∪ · · · ∪ Sn , de los conjuntos. La operación no halla los documentos que no contienen la palabra clave especificada Ci . Dado un conjunto de identificadores S, se pueden eliminar los documentos que contienen la palabra clave especificada Ci tomando la diferencia S − Si , donde Si es el conjunto de identificadores de los documentos que contienen la palabra clave Ci . Dado un conjunto de palabras clave de una consulta, muchos sistemas de recuperación de información no insisten en que los documentos recuperados contengan todas las palabras clave (a menos que se utilice de manera explícita una operación y). En ese caso, se recuperan todos los documentos que contienen como mínimo una de las palabras clave (como en la operación o), pero se clasifican de acuerdo con la medida de su relevancia. Para usar para la clasificación la frecuencia de los términos la estructura de índices también debe conservar el número de veces que aparece cada término en cada documento. Para reducir este esfuerzo se puede usar una representación comprimida con sólo unos pocos bits, que aproxima la frecuencia de los términos. El índice también debe almacenar la frecuencia de documentos de cada término (es decir, el número de documentos en que aparece cada término). La lista Si se puede ordenar según la clasificación de popularidad (y, en segundo lugar, para los documentos con la misma clasificación de popularidad, por identificador de documento). Luego se puede usar una simple mezcla para calcular las operaciones y y o. Los resultados con clasificación de popularidad más elevada aparecerán cerca de la cabeza de las listas. En el caso de la operación y, si se ignora la contribución de TF-IDF a la puntuación de relevancia y se exige simplemente que el documento contenga las palabras clave dadas, la mezcla puede detenerse una vez obtenidas C respuestas, si el usuario sólo pide las C primeras respuestas. 19.6 Medida de la efectividad de la recuperación

Cada palabra clave puede estar incluida en gran número de documentos; por tanto, una representación compacta resulta fundamental para mantener bajas las necesidades de espacio del índice. Así, los conjuntos de documentos de cada palabra clave se conservan en forma comprimida. Para ahorrar espacio de almacenamiento a veces se almacena el índice de modo que la recuperación es aproximada; puede que no se recuperen unos pocos documentos de relevancia (lo que se denomina un rechazo falso o un falso negativo), o puede que se recuperen unos pocos documentos sin relevancia (lo que se denomina un falso positivo). Una buena estructura de índice no tiene ningún rechazo falso, pero puede que permita algunos falsos positivos; el sistema puede filtrarlos posteriormente mirando las palabras clave que contienen realmente. En el indexado de Webs los falsos positivos tampoco son deseables, ya que puede que el documento real no sea accesible rápidamente para su filtrado. Se usan dos métricas para medir la calidad con que los sistemas de recuperación de información pueden contestar las consultas. La primera, la precisión, mide el porcentaje de los documentos recuperados que son verdaderamente importantes para la consulta. La segunda, la recuperación (recall), mide el porcentaje de los documentos importantes para la consulta que se ha recuperado. Lo ideal sería que ambas fueran del cien por cien.

www.detodoprogramacion.com


19.7

Motores de búsqueda en Web

641

La precisión y la recuperación también son medidas importantes para la comprensión de la calidad de una determinada estrategia de clasificación de los documentos. Las estrategias de clasificación pueden dar lugar a falsos negativos y a falsos positivos, pero en un sentido más sutil. • Pueden producirse falsos negativos al clasificar los documentos porque los documentos importantes obtengan clasificaciones bajas. Si el sistema capturara todos los documentos hasta incluir los que tienen clasificaciones muy bajas, habría muy pocos falsos negativos. Sin embargo, los usuarios rara vez miran más allá de las primeras decenas de documentos devueltos y, por tanto, puede que pasen por alto documentos importantes porque no estén clasificados entre los primeros. Lo que sea exactamente un falso negativo depende del número de documentos que se examinen. Por tanto, en lugar de tener un solo número como medida de la recuperación, se puede medir la recuperación como función del número de documentos capturados. • Pueden producirse falsos positivos porque documentos sin relevancia obtengan clasificaciones más elevadas que algunos documentos importantes. Esto también depende del número de documentos que se examinen. Una posibilidad es medir la precisión como función del número de documentos extraídos. Una opción mejor y más intuitiva para la medida de la precisión es medirla como función de la recuperación. Con esta medida combinada tanto la precisión como la recuperación pueden calcularse en función del número de documentos, si hace falta. Por ejemplo, se puede decir que con una recuperación del cincuenta por ciento la precisión es del setenta y cinco por ciento, mientras que con una recuperación del setenta y cinco por ciento la precisión ha caído hasta el sesenta por ciento. En general, se puede dibujar una gráfica que relacione la precisión con la recuperación. Estas medidas pueden calcularse para las diferentes consultas y promediarse para un conjunto de consultas en las pruebas de homologación de la calidad de las consultas. Otro problema más de la medida de la precisión y de la recuperación consiste en el modo de definir los documentos que son realmente importantes y los que no lo son. De hecho, decidir si un documento es importante o no lo es exige la comprensión del lenguaje natural y de las pretensiones de la consulta. Los investigadores, por tanto, han creado conjuntos de documentos y de consultas y han marcado manualmente los documentos como importantes o no importantes para las consultas. Se pueden ejecutar diferentes sistemas de clasificación con estos conjuntos de documentos para medir la precisión y la recuperación medias de varias consultas. 19.7 Motores de búsqueda en Web

Los programas denominados Web crawlers (batidores Web) localizan y reúnen información de Web. Siguen de manera recursiva los hipervínculos presentes en los documentos conocidos para hallar otros documentos. Los batidores recuperan los documentos y añaden la información hallada en ellos a índices combinados; generalmente, los documentos no se almacenan, aunque algunos motores de búsqueda guardan en la caché una copia del documento para ofrecer a sus clientes un acceso más rápido a los documentos. Dado que el número de documentos de Web es muy grande, no es posible recorrer toda Web en un periodo corto de tiempo; y, de hecho, todos los motores de búsqueda cubren únicamente algunas partes de Web, no toda ella, y sus batidores pueden tardar semanas o meses en llevar a cabo un solo recorrido de todas las páginas que abarcan. Suele haber muchos procesos que se ejecutan en varias máquinas, implicadas en los recorridos. Una base de datos almacena el conjunto de vínculos (o de sitios) que hay que recorrer; esa base de datos asigna los vínculos que parten de este conjunto a cada proceso batidor. Los vínculos nuevos hallados durante cada recorrido se añaden a la base de datos, y se pueden recorrer posteriormente si no se recorren de manera inmediata. Las páginas halladas durante cada recorrido también se pasan al sistema de cálculo de prestigio y de indexado, que puede que se ejecute en una máquina diferente. Hay que volver a capturar las páginas (es decir, volver a seguir los vínculos) de manera periódica para obtener información actualizada y descartar los sitios que ya no existen, de modo que la información del índice de búsqueda se mantenga razonablemente actualizada. Los propios sistemas de cálculo de prestigio y de indexado se ejecutan en paralelo en varias máquinas. No es buena idea añadir las páginas al mismo índice que se usa para las consultas, ya que eso exige el

www.detodoprogramacion.com


642

Capítulo 19

Recuperación de información

control de concurrencia del índice, y afecta al rendimiento de las consultas y de las actualizaciones. En lugar de eso, se usa una copia del índice para responder a las consultas mientras otra copia se actualiza con las páginas recién recorridas. A intervalos periódicos se intercambian las copias y se actualiza la más antigua mientras la copia nueva se usa para las consultas. Para soportar tasas de consultas muy elevadas se pueden mantener los índices en la memoria principal y usar varias máquinas; el sistema encamina de manera selectiva las consultas a las diferentes máquinas para equilibrar la carga de trabajo entre ellas. Los motores de búsqueda más populares suelen tener decenas de miles de máquinas que llevan a cabo las diferentes tareas de exploración, indexado y respuesta a las consultas de los usuarios. 19.8 Recuperación de información y datos estructurados

Aunque los sistemas de recuperación de información se diseñaron originalmente para hallar documentos de texto relacionados con las consultas, hay una necesidad creciente de sistemas que intenten comprender los documentos (en un grado limitado) y contestar preguntas de acuerdo con esa comprensión (limitada). Un enfoque es la creación de información estructurada a partir de documentos no estructurados y responder a preguntas de acuerdo con esa información estructurada. Otro enfoque aplica las técnicas del lenguaje natural para hallar documentos relacionados con la pregunta (planteada en lenguaje natural) y devolver fragmentos importantes de los documentos como respuesta a esa pregunta. 19.8.1 Extracción de información

Los sistemas de extracción de información pasan la información en forma de texto a otra forma más estructurada. Por ejemplo, un anuncio inmobiliario puede describir los atributos de una casa en forma de texto, como “casa en La Moraleja con dos dormitorios y tres baños, un millón de euros”, de la que el sistema de extracción de la información puede extraer atributos como el número de dormitorios, el de baños, el coste y la zona. Esta información así extraída se puede usar para responder mejor a las consultas. Una organización que mantenga una base de datos de información sobre empresas puede usar un sistema de extracción de la información para extraer de manera automática la información de los artículos de los periódicos; la información extraída se relacionará con las modificaciones en los atributos que interesan, como las renuncias, los ceses o los nombramientos de los ejecutivos de las empresas. Se han creado varios sistemas para la extracción de información para aplicaciones especializadas. Usan técnicas lingüísticas y reglas definidas por los usuarios para dominios concretos (como los anuncios inmobiliarios). 19.8.2 Consulta de datos estructurados

Los datos estructurados se representan sobre todo en forma relacional o mediante XML. Se han creado varios sistemas para soportar la consulta de palabras clave en datos relacionales y de XML. Un problema frecuente en estos sistemas es la búsqueda de nodos (tuplas o elementos de XML) que contengan las palabras clave especificadas y la de caminos que los conecten (o ancestros comunes, en el caso de los datos de XML). Por ejemplo, la consulta “Gómez Castellana” en una base de datos bancaria puede determinar que el nombre Gómez aparezca en una tupla de cliente y el nombre Castellana en una tupla de sucursal, y un camino que pase por la relación impositor que conecte esas dos tuplas. Estas consultas se pueden usar para la exploración y consulta ad hoc de los datos, cuando el usuario no conoce el esquema exacto y no desea realizar el esfuerzo de escribir una consulta de SQL o de XQuery para definir lo que está buscando. En realidad, no resulta razonable suponer que los usuarios legos escriban consultas en lenguajes de consultas estructurados, ya que la búsqueda mediante palabras clave resulta bastante natural. Como las consultas no están completamente definidas, pueden tener muchos tipos diferentes de respuestas, que hay que clasificar. Se han propuesto varias técnicas para clasificar las respuestas en entornos de este tipo, de acuerdo con la longitud de los caminos de conexión y con base en técnicas para la asignación de direcciones y pesos a los bordes. También se han propuesto técnicas para la asignación de clasificaciones de popularidad a las tuplas y a los elementos de XML, de acuerdo con vínculos como

www.detodoprogramacion.com


19.9

Directorios

643

las claves externas y los vĂ­nculos IDREF. VĂŠanse las notas bibliogrĂĄficas para obtener mĂĄs informaciĂłn sobre la bĂşsqueda mediante palabras clave en los datos relacionales y de XML. 19.8.3 Respuesta a las preguntas

Los sistemas de recuperaciĂłn de informaciĂłn se centran en la bĂşsqueda de documentos importantes para cada consulta. Sin embargo, la respuesta a una consulta dada puede hallarse sĂłlo en parte de un documento, o en partes pequeĂąas de varios documentos. Los sistemas de respuesta a las preguntas intentan ofrecer respuestas directas a las preguntas planteadas por los usuarios. Por ejemplo, una pregunta de la forma â€œÂżQuiĂŠn matĂł a CĂĄnovas?â€? se responde mejor con una lĂ­nea que diga “Antonio CĂĄnovas del Castillo fue asesinado por el anarquista Angiolillo en 1897â€?. TĂŠngase en cuenta que la respuesta no contiene realmente las palabras “matĂłâ€? ni “quiĂŠnâ€?, pero el sistema deduce que “quiĂŠnâ€? puede responderse con un nombre, y “matĂłâ€? estĂĄ relacionado con “asesinĂłâ€?. Los sistemas de respuesta a las preguntas que se centran en la informaciĂłn de Web suelen generar una o mĂĄs consultas de palabras clave a partir de la pregunta formulada, formulan las consultas de palabras clave a los motores de bĂşsqueda por Web y analizan los documentos devueltos para hallar fragmentos de esos documentos que respondan la pregunta. Se usan varias tĂŠcnicas lingßísticas y heurĂ­sticas para generar las consultas de palabras clave y para hallar los fragmentos importantes de los documentos. El motor de bĂşsqueda MSN de Microsoft soporta la respuesta a preguntas y usa la enciclopedia Encarta como fuente de informaciĂłn principal. Los sistemas de respuesta a las preguntas de la generaciĂłn actual tienen una potencia limitada, ya que no comprenden realmente ni la pregunta ni los documentos usados para responderla. No obstante, resultan Ăştiles para cierto tipo de tareas de respuesta a preguntas sencillas. 19.9 Directorios

El usuario tĂ­pico de una biblioteca puede usar un catĂĄlogo para hallar el libro que busca. Cuando recupera el libro del estante, no obstante, es probable que hojee otros libros que se hallen cerca. Las bibliotecas organizan los libros de modo que los tĂ­tulos relacionados se guarden cerca unos de otros. Por tanto, puede que un libro que estĂŠ fĂ­sicamente cerca del libro deseado tambiĂŠn sea interesante, lo que hace que merezca la pena para los usuarios hojear esos libros. Para guardar cerca unos de otros los libros relacionados las bibliotecas usan una jerarquĂ­a de clasificaciĂłn. Los libros de ciencia se clasifican juntos. Dentro de este conjunto de libros hay una clasificaciĂłn mĂĄs detallada, que organiza por un lado los libros de informĂĄtica, por otro los de matemĂĄticas, etc. Dado que hay una relaciĂłn entre las matemĂĄticas y la informĂĄtica, hay conjuntos importantes de libros que se guardan fĂ­sicamente cerca. En otro nivel diferente de la jerarquĂ­a de la clasificaciĂłn los libros de informĂĄtica se dividen en subĂĄreas, como los sistemas operativos, los lenguajes y los algoritmos. La Figura 19.1

Figura 19.1

JerarquĂ­a de clasificaciĂłn para el sistema de una biblioteca.

www.detodoprogramacion.com


644

Capítulo 19

Recuperación de información

libros

ciencia

matemáticas

ingeniería

informática

Figura 19.2

algoritmos

algoritmos de grafos

ficción

GAD de clasificación del sistema de recuperación de información de una biblioteca.

muestra una jerarquía de clasificación que pueden usar las bibliotecas. Como los libros sólo se pueden guardar en un sitio, cada libro de la biblioteca se clasifica exactamente en un punto de la jerarquía de clasificación. En los sistemas de recuperación de información no hace falta almacenar cerca los documentos relacionados. No obstante, estos sistemas necesitan organizar lógicamente los documentos para permitir su exploración. Por tanto, estos sistemas pueden usar una jerarquía de clasificación parecida a la que usan las bibliotecas y, al mostrar un documento concreto, también pueden mostrar una breve descripción de los documentos que se hallan cercanos en la jerarquía. En los sistemas de recuperación de información no hace falta guardar cada documento en un solo punto de la jerarquía. Los documentos que traten de matemáticas para informáticos pueden clasificarse en matemáticas y en informática. Lo que se guarda en cada punto es un identificador del documento (es decir, un puntero hacia el documento), y resulta fácil capturar el contenido del documento mediante su identificador. Como consecuencia de esa flexibilidad, no sólo se puede clasificar cada documento en dos posiciones, sino que también puede aparecer una subárea de la jerarquía de la clasificación en dos áreas diferentes. La clase de documento “algoritmo de grafos” puede aparecer tanto en matemáticas como en informática. Por tanto, la jerarquía de clasificación es ahora un grafo acíclico dirigido (GAD), como puede verse en la Figura 19.2. Los documentos de algoritmos de grafos pueden aparecer en una sola posición del GAD, pero se puede llegar a ellos por varios caminos. Un directorio no es más que una estructura de clasificación GAD. Cada hoja del directorio almacena vínculos con documentos del tema representado por la hoja. Los nodos internos también pueden contener vínculos, por ejemplo, con documentos que no se pueden clasificar en ninguno de los nodos hijo. Para hallar información sobre un asunto los usuarios empiezan en la raíz del directorio y siguen los caminos por el GAD hasta alcanzar el nodo que representa el asunto deseado. Mientras avanzan por el directorio los usuarios no sólo pueden hallar documentos sobre el asunto en el que están interesados, sino que también pueden hallar documentos relacionados y clases relacionadas en la jerarquía de clasificación. Los usuarios pueden conseguir información nueva explorando los documentos (o las subclases) de las clases relacionadas. La organización de la enorme cantidad de información disponible en Web en una estructura de directorio es una enorme tarea. • El primer problema es la determinación de cuál debe ser exactamente la jerarquía del directorio. • El segundo problema es, dado un documento, decidir los nodos del directorio que son categorías importantes para el documento.

www.detodoprogramacion.com


19.10

Resumen

645

Para afrontar el primer problema los portales como Yahoo tienen equipos de “bibliotecarios de Internet” que sugieren la jerarquía de la clasificación y la perfeccionan continuamente. El proyecto de directorio abierto (Open Directory Project) es un gran esfuerzo cooperativo con diferentes voluntarios que son responsables de organizar las diferentes ramas del directorio. El segundo problema también puede afrontarse manualmente con bibliotecarios, o bien los conservadores del sitio Web pueden ser responsables de decidir el lugar de la jerarquía en que deben ubicarse sus sitios. También hay técnicas para decidir de manera automática la ubicación de los documentos de acuerdo con el cálculo de su semejanza con documentos que ya se hayan clasificado.

19.10 Resumen

• Los sistemas de recuperación de información se usan para almacenar y consultar datos de texto como los documentos. Usan un modelo de datos más sencillo que el de los sistemas de bases de datos, pero ofrecen posibilidades de búsqueda más potentes dentro de ese modelo restringido. Las consultas intentan localizar los documentos de interés especificando, por ejemplo, conjuntos de palabras clave. La consulta que el usuario tiene en mente no se suele poder formular de manera precisa; por tanto, los sistemas de recuperación de información ordenan las respuestas con base en su posible relevancia. • La clasificación por relevancia emplea varios tipos de información como: ¤ Frecuencia de los términos: la relevancia de cada término para cada documento. ¤ Frecuencia inversa de los documentos. ¤ Clasificación por popularidad. • La semejanza de los documentos se usa para recuperar documentos parecidos a un documento de ejemplo. La métrica del coseno se usa para definir la semejanza y se basa en el modelo del espacio vectorial. • PageRank y la clasificación de nodos y autoridades son dos maneras de asignar prestigio a las páginas con base en los vínculos de cada página. La medida de PageRank se puede comprender de manera intuitiva usando un modelo de recorrido aleatorio. La información del texto ancla también se usa para calcular un concepto de popularidad por palabra clave. • La contaminación de los motores de búsqueda intenta conseguir una clasificación elevada (no merecida). • Los sinónimos y los homónimos complican la tarea de recuperación de información. Las consultas basadas en los conceptos intentan hallar los documentos que contienen los conceptos especificados, independientemente de las palabras exactas (o del idioma) en que se especifiquen. Las ontologías se usan para relacionar los conceptos entre sí, usando relaciones como es o parte-de. • Los índices invertidos se usan para responder a las consultas de palabras clave. • La precisión y la recuperación son dos medidas de la efectividad de los sistemas de recuperación de información. • Los motores de búsqueda Web la recorren para hallar páginas, analizarlas para calcular las medidas de prestigio e indexarlas. • Se han desarrollado técnicas para extraer información estructurada de los datos de texto, para llevar a cabo consultas basadas en palabras clave sobre datos estructurados y para dar respuestas directas a preguntas sencillas planteadas en lenguaje natural. • Las estructuras de directorio se usan para clasificar los documentos con otros documentos semejantes.

www.detodoprogramacion.com


646

Recuperación de información

Capítulo 19

Términos de repaso

• • • • •

Sistemas de recuperación de información. Búsqueda por palabras clave. Recuperación de texto completo. Término. Clasificación por relevancia. ¤ Frecuencia de los términos. ¤ Frecuencia inversa de los documentos. ¤ Relevancia. ¤ Proximidad.

• Contaminación de los índices de búsqueda. • Sinónimos. • Homónimos. • Conceptos. • Consultas basadas en conceptos. • Ontologías. • WordNet. • Índice invertido.

• Recuperación basada en la semejanza. ¤ Modelo del espacio vectorial. ¤ Métrica de semejanza del coseno. ¤ Realimentación de la relevancia. • Palabras de parada. • Relevancia cuando se usan hipervínculos. ¤ Popularidad y prestigio. ¤ Transferencia del prestigio.

• Falso rechazo.

• PageRank. ¤ Modelo de recorrido aleatorio. • Relevancia basada en el texto ancla. • Clasificación de nodos y autoridades.

• Consulta de datos estructurados.

• Falso negativo. • Falso positivo. • Precisión. • Recuperación. • Batidores Web. • Extracción de información. • Respuesta a preguntas. • Directorios. • Jerarquía de clasificación.

Ejercicios prácticos

19.1 Calcúlese la relevancia (mediante las definiciones correspondientes de la frecuencia de los términos y de la frecuencia inversa de los documentos) de cada una de los Ejercicios prácticos de este capítulo para la consulta “relación SQL”. 19.2 Supóngase que se desea hallar documentos que contengan como mínimo c palabras clave de un conjunto dado de n. Supóngase también que se dispone de un índice de palabras clave que da una lista (ordenada) de identificadores de los documentos que contienen una palabra clave dada. Dese un algoritmo eficiente para hallar el conjunto de documentos deseado. 19.3 Sugiérase la manera de implementar la técnica iterativa para el cálculo de PageRank dado que la matriz T (incluso en la representación de lista de adyacentes) no cabe en la memoria. 19.4 Sugiérase la manera en que se puede indexar un documento que contiene una palabra (como “leopardo”) de modo que las consultas que utilicen un concepto más general (como “carnívoro” o “mamífero”) lo recuperen de manera eficiente. Se puede suponer que la jerarquía de conceptos no es muy profunda, por lo que cada concepto sólo tiene unas cuantas generalizaciones (cada concepto, no obstante, puede tener gran número de generalizaciones). También se puede suponer que se dispone de una función que devuelve el concepto de cada palabra del documento. Sugiérase también la manera de que las consultas que utilicen conceptos especializados puedan recuperar conceptos más generales. 19.5 Supóngase que se mantienen en bloques listas invertidas, donde cada bloque denota la mejor clasificación de popularidad y las puntuaciones de TF-IDF de los documentos de los demás bloques. Sugiérase la manera en que la mezcla de las listas invertidas puede detenerse de manera temprana si el usuario sólo desea las primeras C respuestas.

www.detodoprogramacion.com


Notas bibliográficas

647

Ejercicios

19.6 Usando una definición sencilla de la frecuencia de cada término como número de apariciones de cada término en el documento, dense las puntuaciones TF-IDF de cada término del conjunto de documentos que consiste en este ejercicio y en el siguiente. 19.7 Créese un pequeño ejemplo de cuatro documentos de pequeño tamaño, cada uno con su valor de PageRank, y créense cuatro listas invertidas de los documentos ordenados por PageRank. No hace falta calcular PageRank, basta con suponer un valor para cada página. 19.8 Supóngase que se desea llevar a cabo una consulta mediante palabras clave sobre un conjunto de tuplas de una base de datos, donde cada tupla tiene unos pocos atributos, cada uno de los cuales sólo contiene unas cuantas palabras. ¿El concepto de frecuencia de los términos tiene sentido en este contexto? ¿Y el de frecuencia inversa de los documentos? Explíquense las respuestas. Sugiérase también la manera en que se puede definir la semejanza de dos tuplas usando los conceptos de TF-IDF. 19.9 Los sitios Web que desean conseguir publicidad pueden unirse a un anillo de Webs, en los que crean vínculos con otros sitios del anillo, a cambio de que otros sitios del anillo creen vínculos con ellos. ¿Cuál es el efecto de estos anillos en las técnicas de clasificación por popularidad como PageRank? 19.10 El motor de búsqueda Google ofrece una característica por la cual los sitios Web pueden mostrar anuncios proporcionados por Google. Los anuncios proporcionados se basan en el contenido de cada página. Sugiérase la manera en que Google puede escoger los anuncios que debe proporcionar a cada página, dado el contenido de la página. 19.11 Una manera de crear una versión de PageRank específica para palabras clave es modificar el salto aleatorio de modo que sólo sean posibles los saltos a páginas que contengan la palabra clave deseada. Por tanto, las páginas que no contengan esa palabra clave pero estén cercanas (en términos de vínculos) a las que sí la contienen obtendrán también una clasificación no nula para esa palabra clave. a. Dense las ecuaciones que definen esta versión específica para palabras clave de PageRank. b. Dese una fórmula para calcular la relevancia de cada página para una consulta que contenga varias palabras clave. 19.12 La idea de clasificación por popularidad mediante hipervínculos se puede ampliar a los datos relacionales y de XML, usando las claves externas y los bordes IDREF en lugar de los hipervínculos. Sugiérase la manera de que este esquema de clasificación resulte útil para las aplicaciones siguientes: a. Una base de datos bibliográfica, que tiene vínculos de los artículos con sus autores y de cada artículo con los artículos a los que hace referencia. b. Una base de datos de ventas que tiene vínculos de cada registro de ventas con los productos que se han vendido. Sugiérase también el motivo de que la clasificación por prestigio pueda dar resultados menos significativos en bases de datos de películas que registran los actores que trabajaron en cada película. 19.13 Explíquese la diferencia entre un falso positivo y un rechazo falso. Si es fundamental que las consultas de recuperación de información no pasen por alto ninguna información importante, explicar si es aceptable tener falsos positivos o falsos rechazos. Explicar el motivo. Notas bibliográ cas

Chakrabarti [2002], Grossman y Frieder [2004], Witten et al. [1999], y Baeza-Yates y Ribeiro-Neto [1999] ofrecen descripciones propias de libros de texto de la recuperación de información. Chakrabarti [2002] ofrece un tratamiento detallado de las batidas Web, de las técnicas de clasificación y de la agrupación y otras técnicas de obtención de datos relacionadas con la recuperación de información. El indexado

www.detodoprogramacion.com


648

Capítulo 19

Recuperación de información

de los documentos se trata con detalle en Witten et al. [1999]. Jones y Willet [1997] es una colección de artículos sobre recuperación de información. Salton [1989] es uno de los primeros libros de texto sobre los sistemas de recuperación de información. Brin y Page [1998] describen la anatomía del motor de búsqueda de Google, incluida la técnica PageRank, mientras que una técnica de clasificación basada en nodos y autoridades denominada HITS se describe en Kleinberg [1999]. Bharat y Henzinger [1998] presentan una mejora de la técnica de clasificación HITS. Estas técnicas, así como otras técnicas de clasificación basadas en la popularidad (y técnicas para evitar la contaminación de los motores de búsqueda) se describen con detalle en Chakrabarti [2002]. Chakrabarti et al. [1999] abordan el recorrido enfocado de Web para hallar páginas relacionadas con un asunto concreto. Chakrabarti [1999] ofrece un resumen del descubrimiento de recursos Web. El sistema Citeseer (citeseer.ist.psu.edu) mantiene una base de datos de gran tamaño de publicaciones (artículos), con vínculos de citas entre las publicaciones, y usa estas citas para clasificar las publicaciones. Incluye una técnica para ajustar la clasificación por citas de acuerdo con la antigüedad de la publicación, para compensar el hecho de que las citas a una publicación dada aumentan a medida que pasa el tiempo; sin ese ajuste, los documentos más antiguos tienden a obtener clasificaciones más elevadas de las que merecen realmente. La extracción de información y la respuesta a preguntas tienen una historia bastante larga en la comunidad de la inteligencia artificial. Jackson y Moulinier [2002] ofrecen un tratamiento de libro de texto de la técnica de procesamiento del lenguaje natural con énfasis en la extracción de la información. Soderland [1999] describe la extracción de la información mediante el sistema WHISK, mientras que Appelt y Israel [1999] ofrecen un tutorial sobre la extracción de información. La Conferencia anual de Recuperacion de Texto (Text Retrieval Conference, TREC) tiene varios temas, incluida la recuperación de documentos, la respuesta a preguntas, la búsqueda genómica, etc. Cada tema define un problema y la infraestructura para comprobar la calidad de las soluciones a ese problema. Los detalles sobre TREC se pueden hallar en trec.nist.gov. La información sobre el tema de las respuestas a preguntas se puede hallar en trec.nist.gov/data/qa.html. Se puede hallar más información sobre WordNet en wordnet.princeton.edu y en globalwordnet.org. El objetivo del sistema Cyc era la representación formal de grandes cantidades de conocimiento humano. Su base de conocimiento contiene gran número de términos, y de asertos sobre cada término. Cyc incluye también soporte para la comprensión del lenguaje natural y para la ruptura de la ambigüedad. La información sobre el sistema Cyc pueden hallarse en cyc.com y en opencyc.org. Agrawal et al. [2002], Bhalotia et al. [2002] y Hristidis y Papakonstantinou [2002] tratan la consulta por palabras clave de los datos relacionales. La consulta por palabras clave de los datos de XML se aborda en Florescu et al. [2000] y Guo et al. [2003], entre otros. Herramientas

Google (www.google.com) es actualmente el motor de búsqueda más popular, pero hay otros motores de búsqueda, como MSN Search (search.msn.com) y Yahoo Search (search.yahoo.com). El sitio searchenginewatch.com ofrece gran variedad de información sobre los motores de búsqueda. Yahoo (www.yahoo.com) y el Proyecto de Directorio Abierto (Open Directory Project, dmoz.org) ofrecen jerarquías de clasificación para los sitios Web.

www.detodoprogramacion.com


P

A

R

T

E

7

Arquitectura de sistemas

La arquitectura de los sistemas de bases de datos está enormemente influida por el sistema informático subyacente en el que se ejecuta el sistema de bases de datos. Los sistemas de bases de datos pueden ser centralizados, o cliente-servidor, donde una máquina que hace de servidor ejecuta trabajos de múltiples máquinas clientes. Los sistemas de bases de datos también pueden diseñarse para explotar las arquitecturas paralelas de computadoras. Las bases de datos distribuidas abarcan muchas máquinas separadas geográficamente. En el Capítulo 20 se empieza tratando las arquitecturas de los sistemas de bases de datos que se ejecutan en sistemas servidores, los cuales se utilizan en arquitecturas centralizadas y cliente-servidor. En este capítulo se tratan los diferentes procesos que juntos implementan la funcionalidad de la base de datos. Después, se estudian las arquitecturas paralelas de computadoras y las arquitecturas paralelas de bases de datos diseñadas para diferentes tipos de computadoras paralelas. Finalmente, el capítulo trata asuntos arquitectónicos para la construcción de un sistema distribuido de bases de datos. En el Capítulo 21 se describe la forma en que varias acciones de una base de datos, en particular el procesamiento de consultas, se pueden implementar para explotar el procesamiento paralelo. En el Capítulo 22 se presentan varias cuestiones que surgen en una base de datos distribuida, y se describe cómo tratar cada cuestión. Estas cuestiones incluyen cómo almacenar datos, cómo asegurar la atomicidad de las transacciones que se ejecutan en varios emplazamientos, cómo realizar el control de concurrencia y cómo proporcionar alta disponibilidad ante la presencia de fallos. En este capítulo también se estudian el procesamiento distribuido de consultas y los sistemas de directorio.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

20

Arquitecturas de los sistemas de bases de datos

La arquitectura de un sistema de bases de datos está influida en gran medida por el sistema informático subyacente en el que se ejecuta, en concreto por aspectos de la arquitectura de la computadora como la conexión en red, el paralelismo y la distribución: • La conexión en red de varias computadoras permite que algunas tareas se ejecuten en un sistema servidor y que otras se ejecuten en los sistemas clientes. Esta división de trabajo ha conducido al desarrollo de sistemas de bases de datos cliente–servidor. • El procesamiento paralelo dentro de una computadora permite acelerar las actividades del sistema de base de datos, proporcionando a las transacciones unas respuestas más rápidas, así como la capacidad de ejecutar más transacciones por segundo. Las consultas pueden procesarse de manera que se explote el paralelismo ofrecido por el sistema informático subyacente. La necesidad del procesamiento paralelo de consultas ha conducido al desarrollo de los sistemas de bases de datos paralelos. • La distribución de datos a través de las distintas sedes de una organización permite que estos datos residan donde han sido generados o donde son más necesarios, pero continuar siendo accesibles desde otros lugares o departamentos diferentes. El hecho de guardar varias copias de la base de datos en diferentes sitios permite que puedan continuar las operaciones sobre la base de datos aunque algún sitio se vea afectado por algún desastre natural como una inundación, un incendio o un terremoto. Se han desarrollado los sistemas distribuidos de bases de datos para manejar datos distribuidos geográfica o administrativamente a lo largo de múltiples sistemas de bases de datos. En este capítulo se estudia la arquitectura de los sistemas de bases de datos comenzando con los tradicionales sistemas centralizados y tratando, más adelante, los sistemas de bases de datos cliente– servidor, paralelos y distribuidos.

20.1 Arquitecturas centralizadas y cliente servidor

Los sistemas de bases de datos centralizados son aquellos que se ejecutan en un único sistema informático sin interaccionar con ninguna otra computadora. Tales sistemas comprenden el rango desde los sistemas de bases de datos monousuario ejecutándose en computadoras personales hasta los sistemas de bases de datos de alto rendimiento ejecutándose en grandes sistemas. Por otro lado, los sistemas cliente –servidor tienen su funcionalidad dividida entre el sistema servidor y múltiples sistemas clientes. 651

www.detodoprogramacion.com


652

Capítulo 20

Arquitecturas de los sistemas de bases de datos

20.1.1 Sistemas centralizados

Una computadora moderna de propósito general consiste en una o unas pocas unidades centrales de procesamiento y un número determinado de controladores para los dispositivos que se encuentran conectados a través de un bus común, el cual proporciona acceso a la memoria compartida (Figura 20.1). Las CPU (unidades centrales de procesamiento) poseen memorias caché locales donde se almacenan copias de ciertas partes de la memoria para acelerar el acceso a los datos. Cada controlador de dispositivo se encarga de un tipo específico de dispositivos (por ejemplo, una unidad de disco, una tarjeta de sonido o un monitor). Las CPU y los controladores de dispositivos pueden ejecutarse concurrentemente compitiendo así por el acceso a la memoria. La memoria caché reduce la disputa por el acceso a la memoria ya que la CPU necesita acceder a la memoria compartida un número de veces menor. Se distinguen dos formas de utilizar las computadoras: como sistemas monousuario o multiusuario. En la primera categoría se encuentran las computadoras personales y las estaciones de trabajo. Un sistema monousuario típico es una unidad de sobremesa utilizada por una única persona que dispone de una sola CPU, de uno o dos discos fijos y que trabaja con un sistema operativo que sólo permite un único usuario. Por el contrario, un sistema multiusuario típico tiene más discos y más memoria, puede disponer de varias CPU y trabaja con un sistema operativo multiusuario. Se encarga de dar servicio a un gran número de usuarios que están conectados al sistema a través de terminales. Normalmente, los sistemas de bases de datos diseñados para funcionar sobre sistemas monousuario no suelen proporcionar muchas de las facilidades que ofrecen los sistemas multiusuario. En particular no tienen control de concurrencia, el cual no es necesario cuando solamente un usuario puede generar modificaciones. Las facilidades de recuperación en estos sistemas o no existen o son primitivas; por ejemplo, realizar una copia de seguridad de la base de datos antes de cualquier modificación. La mayoría de estos sistemas no admiten SQL y proporcionan un lenguaje de consulta muy simple que, en algunos casos, es una variante de QBE. En cambio, los sistemas de bases de datos diseñados para sistemas multiusuario soportan todas las características de las transacciones que se han estudiado antes. Aunque hoy en día las computadoras de propósito general disponen de varios procesadores, utilizan paralelismo de grano grueso, disponiendo de unos pocos procesadores (normalmente dos o cuatro) que comparten la misma memoria principal. Las bases de datos que se ejecutan en tales máquinas habitualmente no intentan dividir una consulta simple entre los distintos procesadores, sino que ejecutan cada consulta en un único procesador posibilitando la concurrencia de varias consultas. Así, estos sistemas soportan una mayor productividad, es decir, permiten ejecutar un mayor número de transacciones por segundo, a pesar de que cada transacción individualmente no se ejecute más rápido. Las bases de datos diseñadas para las máquinas monoprocesador ya disponen de multitarea permitiendo que varios procesos se ejecuten a la vez en el mismo procesador, usando tiempo compartido, mientras que de cara al usuario parece que los procesos se están ejecutando en paralelo. De esta manera,

discos

UCP

ratón

teclado

impresora en línea

controlador de disco

controlador USB

memoria

Figura 20.1

monitor

Un sistema centralizado.

www.detodoprogramacion.com

adaptador gráfico


20.2

Arquitecturas de sistemas servidores

653

desde un punto de vista lógico, las máquinas paralelas de grano grueso parecen ser idénticas a las máquinas monoprocesador, y pueden adaptarse fácilmente los sistemas de bases de datos diseñados para máquinas de tiempo compartido para que puedan ejecutarse sobre máquinas paralelas de grano grueso. Por el contrario, las máquinas paralelas de grano fino disponen de un gran número de procesadores y los sistemas de bases de datos que se ejecutan sobre ellas intentan hacer paralelas las tareas simples (consultas, por ejemplo) que solicitan los usuarios. En el Apartado 20.3 se estudia la arquitectura de los sistemas de bases de datos paralelos.

20.1.2 Sistemas cliente servidor

Como las computadoras personales son cada vez más rápidas, más potentes y más baratas, los sistemas se han ido distanciando de la arquitectura centralizada. Los terminales conectados a un sistema central han sido suplantados por computadoras personales. De igual forma, la interfaz de usuario, que solía estar gestionada directamente por el sistema central, está pasando a ser gestionada, cada vez más, por las computadoras personales. Como consecuencia, los sistemas centralizados actúan hoy como sistemas servidores que satisfacen las peticiones generadas por los sistemas clientes. En la Figura 20.2 se representa la estructura general de un sistema cliente–servidor. La funcionalidad proporcionada por los sistemas de bases de datos se puede dividir a grandes rasgos en dos partes: la fachada y el sistema subyacente. El sistema subyacente gestiona el acceso a las estructuras, la evaluación y optimización de consultas, el control de concurrencia y la recuperación. La fachada de un sistema de base de datos está formado por herramientas como la interfaz de usuario con SQL, interfaces de formularios, diseñadores de informes y herramientas para la recopilación y análisis de datos. La interfaz entre la fachada y el sistema subyacente puede ser SQL o una aplicación. Las normas como ODBC y JDBC, que se estudiaron en el Capítulo 3, se desarrollaron para hacer de interfaz entre clientes y servidores. Cualquier cliente que utilice interfaces ODBC o JDBC puede conectarse a cualquier servidor que proporcione esta interfaz. Ciertas aplicaciones como las hojas de cálculo y los paquetes de análisis estadístico utilizan la interfaz cliente– servidor directamente para acceder a los datos del servidor subyacente. De hecho, proporcionan interfaces visibles especiales para diferentes tareas. Los sistemas que trabajan con una gran cantidad de usuarios adoptan una arquitectura de tres capas, que se vio anteriormente en la Figura 1.7 (Capítulo 1), donde la fachada es el explorador Web que se comunica con un servidor de aplicaciones. El servidor de aplicaciones actúa como cliente del servidor de bases de datos. Algunos sistemas de procesamiento de transacciones proporcionan una interfaz de llamada a procedimientos remotos para transacciones para conectar los clientes con el servidor. Estas llamadas aparecen para el programador como llamadas normales a procedimientos, pero todas las llamadas a procedimientos remotos hechas desde un cliente se engloban en una única transacción al servidor final. De este modo, si la transacción se cancela, el servidor puede deshacer los efectos de las llamadas a procedimientos remotos individuales.

20.2 Arquitecturas de sistemas servidores

Los sistemas servidores pueden dividirse en servidores de transacciones y servidores de datos.

cliente

cliente

cliente

cliente red

servidor Figura 20.2

Estructura general de un sistema cliente–servidor.

www.detodoprogramacion.com


654

Capítulo 20

Arquitecturas de los sistemas de bases de datos

interfaz de usuario SQL

interfaz de formularios

herramientas de generación de informes

herramientas de minería y análisis de datos

fachada

interfaz (SQL + API)

motor SQL

Figura 20.3

sistema subyacente

Funcionalidades de la fachada y del sistema subyacente.

• Los sistemas servidores de transacciones, también llamados sistemas servidores de consultas, proporcionan una interfaz a través de la cual los clientes pueden enviar peticiones para realizar una acción que el servidor ejecutará y cuyos resultados se devolverán al cliente. Normalmente, las máquinas cliente envían las transacciones a los sistemas servidores, lugar en el que estas transacciones se ejecutan, y los resultados se devuelven a los clientes que son los encargados de visualizar los datos. Las peticiones se pueden especificar utilizando SQL o mediante la interfaz de una aplicación especializada. • Los sistemas servidores de datos permiten a los clientes interaccionar con los servidores realizando peticiones de lectura o modificación de datos en unidades tales como archivos o páginas. Por ejemplo, los servidores de archivos proporcionan una interfaz de sistema de archivos a través de la cual los clientes pueden crear, modificar, leer y borrar archivos. Los servidores de datos de los sistemas de bases de datos ofrecen muchas más funcionalidades; soportan unidades de datos de menor tamaño que los archivos—como páginas, tuplas u objetos. Proporcionan facilidades de indexación de los datos así como facilidades de transacción de modo que los datos nunca se quedan en un estado inconsistente si falla una máquina cliente o un proceso. De éstas, la arquitectura del servidor de transacciones es, con mucho, la arquitectura más ampliamente utilizada. En los Apartados 20.2.1 y 20.2.2 se desarrollarán las arquitecturas de los servidores de transacciones y de los servidores de datos. 20.2.1 Estructura de procesos del servidor de transacciones

Hoy en día, un sistema servidor de transacciones típico consiste en múltiples procesos accediendo a los datos en una memoria compartida, como en la Figura 20.4. Los procesos que forman parte del sistema de bases de datos incluyen: • Proceso servidor. Son procesos que reciben consultas del usuario (transacciones), las ejecutan, y devuelven los resultados. Las consultas deben enviarse a los procesos servidor desde la interfaz de usuario, o desde un proceso de usuario que ejecuta SQL incorporado, o a través de JDBC, ODBC o protocolos similares. Algunos sistemas de bases de datos utilizan un proceso distinto para cada sesión de usuario, y otros utilizan un único proceso de la base de datos para todas las sesiones del usuario, pero con múltiples hebras de forma que se pueden ejecutar concurrentemente múltiples consultas (una hebra es parecida a un proceso; sin embargo, varias hebras se pueden ejecutar concurrentemente como parte de un mismo proceso, y todas ellas en el mismo espacio de memoria virtual). Algunos sistemas de bases de datos utilizan una arquitectura híbrida, con procesos múltiples, cada uno de ellos con varias hebras. • Proceso gestor de bloqueos. Este proceso implementa una función de gestión de bloqueos que incluye concesión de bloqueos, liberación de bloqueos y detección de interbloqueos. • Proceso escritor de bases de datos. Existe uno o más procesos que vuelcan al disco los bloques de memoria intermedia modificados de forma continua.

www.detodoprogramacion.com


Arquitecturas de sistemas servidores

20.2

proceso de usuario

proceso de usuario ODBC

proceso de usuario

JDBC proceso de servidor

proceso de servidor

proceso de servidor

proceso monitor de procesos

grupo de memorias intermedias

memoria compartida

caché de planes de consulta tabla memoria intermedia de bloqueos del registro

proceso escritor del registro

proceso punto de revisión

discos de registro

Figura 20.4

655

proceso gestor de bloqueos

proceso escritor de bases de datos

discos de datos

Estructura de la memoria compartida y de los procesos.

• Proceso escritor del registro. Este proceso genera entradas del registro en el almacenamiento estable a partir de la memoria intermedia del registro. Los procesos servidor simplifican la adición de entradas a la memoria intermedia del registro en memoria compartida y, si es necesario forzar la escritura del registro, le piden al proceso escritor del registro que vuelque las entradas del registro. • Proceso punto de revisión. Este proceso realiza periódicamente puntos de revisión. • Proceso monitor de procesos. Este proceso observa otros procesos y, si cualquiera de ellos falla, realiza acciones de recuperación para el proceso, tales como cancelar cualquier transacción que estuviera ejecutando el proceso fallido, y reinicia el proceso. La memoria compartida contiene todos los datos compartidos, como: • Grupo de memorias intermedias. • Tabla de bloqueos. • Memoria intermedia del registro, que contiene las entradas del registro que esperan a ser volcadas en el almacenamiento estable. • Planes de consulta en caché, que se pueden reutilizar si se envía de nuevo la misma consulta. Todos los procesos de la base de datos pueden acceder a los datos de la memoria compartida. Ya que múltiples procesos pueden leer o realizar actualizaciones en las estructuras de datos en memoria compartida, debe haber un mecanismo que asegure que sólo uno de ellos está modificando una estructura de datos en un momento dado, y que ningún proceso está leyendo una estructura de datos mientras otros la escriben. Tal exclusión mutua se puede implementar por medio de funciones del sistema operativo llamadas semáforos. Implementaciones alternativas, con menos sobrecargas, utilizan instrucciones atómicas especiales soportadas por el hardware de la computadora; un tipo de instrucción atómica comprueba una posición de la memoria y la establece a uno automáticamente. Se pueden encontrar más detalles sobre la excusión mutua en cualquier libro de texto de un sistema operativo estándar. Los mecanismos de exclusión mutua también se utilizan para implementar pestillos.

www.detodoprogramacion.com


656

Capítulo 20

Arquitecturas de los sistemas de bases de datos

Para evitar la sobrecarga del paso de mensajes, en muchos sistemas de bases de datos los procesos servidor implementan el bloqueo actualizando directamente la tabla de bloqueos (que está en memoria compartida), en lugar de enviar mensajes de solicitud de bloqueo a un proceso administrador de bloqueos. El procedimiento de solicitud de bloqueos ejecuta las acciones que realizaría el proceso administrador de bloqueos para procesar una solicitud de bloqueo. Las acciones de la solicitud y la liberación de bloqueos son como las del Apartado 16.1.4, pero con dos diferencias significativas: • Dado que varios procesos servidor pueden acceder a la memoria compartida, se asegurará la exclusión mutua en la tabla de bloqueos. • Si no se puede obtener un bloqueo inmediatamente a causa de un conflicto de bloqueos, el código de la solicitud de bloqueo sigue observando la tabla de bloqueos hasta percatarse de que se ha concedido el bloqueo. El código de liberación de bloqueo actualiza la tabla de bloqueos para indicar a qué proceso se le ha concedido el bloqueo. Para evitar repetidas comprobaciones de la tabla de bloqueos, el código de solicitud de bloqueo puede utilizar los semáforos del sistema operativo para esperar una notificación de una concesión de bloqueo. El código de liberación de bloqueo debe utilizar entonces el mecanismo de semáforos para notificar a las transacciones que están esperando que sus bloqueos hayan sido concedidos. Incluso si el sistema gestiona las solicitudes de bloqueo por medio de memoria compartida, aún utiliza el proceso administrador de bloqueos para la detección de interbloqueos. 20.2.2 Servidores de datos

Los sistemas servidores de datos se utilizan en redes de área local en las cuales se alcanza una alta velocidad de conexión entre los clientes y el servidor. Las máquinas clientes son comparables al servidor en cuanto a poder de procesamiento y ejecutan tareas de cómputo intensivo. En este entorno tiene sentido enviar los datos a las máquinas clientes, realizar allí todo el procesamiento (que puede durar un tiempo) y después enviar los datos de vuelta al servidor. Obsérvese que esta arquitectura necesita que los clientes posean todas las funcionalidades del sistema subyacente. Las arquitecturas de los servidores de datos se han hecho particularmente populares en los sistemas de bases de datos orientadas a objetos. En esta arquitectura surgen algunos aspectos interesantes, ya que el coste en tiempo de comunicación entre el cliente y el servidor es alto comparado al de acceso a una memoria local (milisegundos frente a menos de 100 nanosegundos). • Envío de páginas o envío de elementos. La unidad de comunicación de datos puede ser de grano grueso, como una página, o de grano fino, como una tupla (o, en el contexto de los sistemas de bases de datos orientados a objetos, un objeto). Se empleará el término elemento para referirse tanto a tuplas como a objetos. Si la unidad de comunicación de datos es un único elemento, la sobrecarga por la transferencia de mensajes es alta comparada con el número de datos transmitidos. En lugar de ello, cuando se necesita un elemento, cobra sentido la idea de enviar junto a él otros que probablemente vayan a emplearse en un futuro próximo. Se denomina preextracción a la acción de buscar y enviar elementos antes de que sea estrictamente necesario. Si varios elementos residen en un página, el envío de páginas puede considerarse como una forma de preextracción ya que, cuando un proceso desee acceder a un único elemento de la página, se enviarán todos los elementos de esa página. • Bloqueo. La concesión del bloqueo de los elementos de datos que el servidor envía a los clientes la realiza habitualmente el propio servidor. Un inconveniente del envío de páginas es que los clientes pueden recibir bloqueos de grano grueso—el bloqueo de una página bloquea implícitamente todos los elementos que residen en ella. El cliente adquiere implícitamente bloqueos sobre todos los elementos preextraídos incluso aunque no esté accediendo a algunos de ellos. De esta forma, es posible que se detenega innecesariamente el procesamiento de otros clientes que necesiten bloquear estos elementos. Se han propuesto algunas técnicas para la liberación de

www.detodoprogramacion.com


20.3

Sistemas paralelos

657

bloqueos en las que el servidor puede pedir a los clientes que le devuelvan el control sobre los bloqueos de los elementos preextraídos. Si el cliente no necesita el elemento preextraído puede devolver los bloqueos sobre ese elemento al servidor para que éstos puedan ser asignados a otros clientes. • Caché de datos. Los datos que se envían al cliente en favor de una transacción se pueden alojar en una caché del cliente incluso una vez completada la transacción, si dispone de suficiente espacio de almacenamiento libre. Las transacciones sucesivas en el mismo cliente pueden hacer uso de los datos en caché. Sin embargo, se presenta el problema de la coherencia de caché: si una transacción encuentra los datos en la caché, debe asegurarse de que esos datos están al día ya que, después de haber sido almacenados en la caché, pueden haber sido modificados por otro cliente. Así, debe establecerse una comunicación con el servidor para comprobar la validez de los datos y poder adquirir un bloqueo sobre ellos. • Caché de bloqueos. Los bloqueos también pueden ser almacenados en la memoria caché del cliente si los datos están prácticamente divididos entre los clientes, de manera que un cliente rara vez necesite los datos de otros clientes. Supóngase que se encuentran en la memoria caché tanto el elemento de datos que se busca como el bloqueo requerido para acceder al mismo. Entonces, el cliente puede acceder al elemento de datos sin necesidad de comunicar nada al servidor. No obstante, el servidor debe seguir el rastro de los bloqueos en caché; si un cliente solicita un bloqueo al servidor, éste debe comunicar a todos los bloqueos sobre el elemento de datos que se encuentren en las memorias caché de otros clientes. La tarea se vuelve más complicada cuando se tienen en cuenta los posibles fallos de la máquina. Esta técnica se diferencia de la liberación de bloqueos en que la caché de bloqueo se realiza a través de transacciones; de otra forma, las dos técnicas serían similares. Las referencias bibliográficas proporcionan más información sobre los sistemas cliente–servidor de bases de datos.

20.3 Sistemas paralelos

Los sistemas paralelos mejoran la velocidad de procesamiento y de E/S porque la CPU y los discos funcionan en paralelo. Cada vez son más comunes las máquinas paralelas, lo que hace que cada vez sea más importante el estudio de los sistemas paralelos de bases de datos. La fuerza que ha impulsado a los sistemas paralelos de bases de datos ha sido la demanda de aplicaciones que han de manejar bases de datos extremadamente grandes (del orden de terabytes—esto es, 1012 bytes) o que tienen que procesar un número enorme de transacciones por segundo (del orden de miles de transacciones por segundo). Los sistemas de bases de datos centralizados o cliente–servidor no son suficientemente potentes para soportar tales aplicaciones. En el procesamiento paralelo se realizan muchas operaciones simultáneamente mientras que en el procesamiento secuencial, los distintos pasos computacionales han de ejecutarse en serie. Una máquina paralela de grano grueso consiste en un pequeño número de potentes procesadores; una máquina masivamente paralela o de grano fino utiliza miles de procesadores más pequeños. Hoy en día, la mayoría de las máquinas de gama alta ofrecen un cierto grado de paralelismo de grano grueso: son comunes las máquinas con dos o cuatro procesadores. Las computadoras masivamente paralelas se distinguen de las máquinas paralelas de grano grueso porque son capaces de soportar un grado de paralelismo mucho mayor. Ya se encuentran en el mercado computadoras paralelas con cientos de CPU y discos. Para evaluar el rendimiento de los sistemas de bases de datos existen dos medidas principales: (1) la productividad, número de tareas que pueden completarse en un intervalo de tiempo determinado, y (2) el tiempo de respuesta, cantidad de tiempo que necesita para completar una única tarea a partir del momento en que se envíe. Un sistema que procese un gran número de pequeñas transacciones puede mejorar la productividad realizando muchas transacciones en paralelo. Un sistema que procese transacciones largas puede mejorar el tiempo de respuesta y la productividad realizando en paralelo las distintas subtareas de cada transacción.

www.detodoprogramacion.com


658

CapĂ­tulo 20

Arquitecturas de los sistemas de bases de datos

20.3.1 Ganancia de velocidad y ampliabilidad

La ganancia de velocidad y la ampliabilidad son dos aspectos importantes en el estudio del paralelismo. La ganancia de velocidad se refiere a la ejecución en menos tiempo de una tarea dada mediante el incremento del grado de paralelismo. La ampliabilidad se refiere al manejo de transacciones mås largas mediante el incremento del grado de paralelismo. ConsidÊrese un sistema paralelo con un cierto número de procesadores y discos que estå ejecutando una aplicación de base de datos. Supóngase ahora que se incrementa el tamaùo del sistema aùadiÊndole mås procesadores, discos y otros componentes. El objetivo es realizar el procesamiento de la tarea en un tiempo inversamente proporcional al número de procesadores y discos del sistema. Supóngase que el tiempo de ejecución de una tarea en la måquina mås grande es TG y que el tiempo de ejecución de la misma tarea en la måquina mås pequeùa es TP . La ganancia de velocidad debida al paralelismo se define como TP /TG . Se dice que un sistema paralelo tiene una ganancia de velocidad lineal si la ganancia de velocidad es N cuando el sistema mås grande tiene N veces mås recursos (CPU, discos, etc.) que el sistema mås pequeùo. Si la ganancia de velocidad es menor que N se dice que el sistema tiene una ganancia de velocidad sublineal. En la Figura 20.5 se muestra la ganancia de velocidad lineal y sublineal. La ampliabilidad estå relacionada con la capacidad para procesar tareas mås largas en el mismo tiempo mediante el incremento de los recursos del sistema. Sea Q una tarea y sea QN una tarea N veces mås grande que Q. Supóngase que TP es el tiempo de ejecución de la tarea Q en una måquina dada MP y que TG es el tiempo de ejecución de la tarea QN en una måquina paralela MG, la cual es N veces mås grande que MP . La ampliabilidad se define como TP /TG . Se dice que el sistema paralelo MG tiene una ampliabilidad lineal sobre la tarea Q si TG = TP . Si TG > TP se dice que el sistema tiene una ampliabilidad sublineal. En la Figura 20.6 se muestra la ampliabilidad lineal y sublineal (donde los recursos aumentan proporcionalmente al tamaùo del problema). La manera de medir el tamaùo de las tareas da lugar a dos tipos de ampliabilidad relevantes en los sistemas paralelos de bases de datos: • En la ampliabilidad por lotes aumenta el tamaùo de la base de datos, y las tareas son trabajos mås largos cuyos tiempos de ejecución dependen del tamaùo de la base de datos. Recorrer una relación cuyo tamaùo es proporcional al tamaùo de la base de datos sería un ejemplo de tales tareas. Así, la medida del tamaùo del problema es el tamaùo de la base de datos. La ampliabilidad por lotes tambiÊn se utiliza en aplicaciones científicas tales como la ejecución de una consulta con una resolución N veces mayor o la realización de una simulación N veces mås larga. • En la ampliabilidad de transacciones aumenta la velocidad con la que se envían las transacciones a la base de datos y el tamaùo de la base de datos crece proporcionalmente a la tasa de transacciones. Este tipo de ampliabilidad es el relevante en los sistemas de procesamiento de transacciones en los que las transacciones son modificaciones pequeùas—por ejemplo, un abono o retirada de fondos de una cuenta—y cuantas mås cuentas se creen, mås crece la tasa de transacciones. Este procesamiento de transacciones se adapta especialmente bien a la ejecución en paralelo, ya que

Figura 20.5

Ganancia de velocidad respecto al incremento de los recursos.

www.detodoprogramacion.com


20.3

Sistemas paralelos

659

Figura 20.6

Ampliabilidad respecto al crecimiento del tamaĂąo del problema y de los recursos.

las transacciones pueden ejecutarse concurrente e independientemente en procesadores distintos y cada transacción dura mås o menos el mismo tiempo, aunque crezca la base de datos. La ampliabilidad es normalmente el factor mås importante para medir la eficiencia de un sistema paralelo de bases de datos. El objetivo del paralelismo en los sistemas de bases de datos suele ser asegurar que la ejecución del sistema continuarå realizåndose a una velocidad aceptable, incluso en el caso de que aumente el tamaùo de la base de datos o el número de transacciones. El incremento de la capacidad del sistema mediante el incremento del paralelismo proporciona a una empresa un modo de crecimiento mås suave que el de reemplazar un sistema centralizado por una måquina mås råpida (suponiendo incluso que esta måquina existiera). Sin embargo, cuando se utiliza la ampliabilidad debe atenderse tambiÊn a los valores del rendimiento absoluto; una måquina con un ampliabilidad lineal puede tener un rendimiento mås bajo que otra con ampliabilidad sublineal simplemente porque la última sea mucho mås råpida que la primera. Existen algunos factores que trabajan en contra de la eficiencia del paralelismo y pueden atenuar tanto la ganancia de velocidad como la ampliabilidad. • Costes de inicio. El inicio de un único proceso lleva asociado un coste. En una operación paralela compuesta por miles de procesos el tiempo de inicio puede llegar a ser mucho mayor que el tiempo real de procesamiento, lo que influye negativamente en la ganancia de velocidad. • Interferencia. Como los procesos que se ejecutan en un sistema paralelo acceden con frecuencia a recursos compartidos, pueden sufrir un cierto retardo como consecuencia de la interferencia de cada nuevo proceso en la competencia con los procesos existentes por el acceso a los recursos mås comunes, como el bus del sistema, los discos compartidos o incluso los bloqueos. Este fenómeno afecta tanto a la ganancia de velocidad como a la ampliabilidad. • Sesgo. Al dividir cada tarea en un cierto número de pasos paralelos se reduce el tamaùo del paso medio. Es mås, el tiempo de servicio de la tarea completa vendrå determinado por el tiempo de servicio del paso mås lento. Normalmente es difícil dividir una tarea en partes exactamente iguales, entonces se dice que la forma de distribución de los tamaùos es sesgada. Por ejemplo, si se divide una tarea de tamaùo 100 en 10 partes y la división estå sesgada, puede haber algunas tareas de tamaùo menor que 10 y otras de tamaùo superior a 10; si el tamaùo de una tarea fuera 20, la ganancia de velocidad que se obtendría al ejecutar las tareas en paralelo sólo valdría 5 en vez de lo que cabría esperarse, 10.

20.3.2 Redes de interconexiĂłn

Los sistemas paralelos estĂĄn constituidos por un conjunto de componentes (procesadores, memoria y discos) que pueden comunicarse entre sĂ­ a travĂŠs de una red de interconexiĂłn. La Figura 20.7 muestra tres tipos de redes de interconexiĂłn utilizados frecuentemente:

www.detodoprogramacion.com


660

Capítulo 20

Arquitecturas de los sistemas de bases de datos

011

111 101

001 110

010 000 (a) bus

(b) malla Figura 20.7

100 (c) hipercubo

Redes de interconexión.

• Bus. Todos los componentes del sistema pueden enviar o recibir datos de un único bus de comunicaciones. Este tipo de interconexión se muestra en la Figura 20.7a. El bus puede ser una red Ethernet o una interconexión paralela. Las arquitecturas de bus trabajan bien para un pequeño número de procesadores. Sin embargo, como el bus sólo puede gestionar la comunicación de un único componente en cada momento, las arquitecturas de bus son menos apropiadas según aumenta el paralelismo. • Malla. Los componentes se organizan como los nodos de una retícula de modo que cada componente está conectado con todos los nodos adyacentes. En una malla bidimensional cada nodo está conectado con cuatro nodos adyacentes, mientras que una malla tridimensional cada nodo está conectado con seis nodos adyacentes. La Figura 20.7b muestra una malla bidimensional. Los nodos entre los que no existe una conexión directa pueden comunicarse mediante el envío de mensajes a través de una secuencia de nodos intermedios que sí dispongan de conexión directa. A medida que aumenta el número de componentes también aumenta el número de enlaces de comunicación por lo que la capacidad de comunicación de una malla es mejor cuanto mayor es el paralelismo. • Hipercubo. Se asigna a cada componente un número binario de modo que dos componentes tienen una conexión directa si sus correspondientes representaciones binarias difieren en un sólo bit. Así, cada uno de los n componentes está conectado con otros log(n) componentes. La Figura 20.7c muestra un hipercubo con 8 vértices. Puede demostrarse que, en un hipercubo, un mensaje de un componente puede llegar a cualquier otro componente de la red de interconexión atravesando a lo sumo log(n) enlaces. Por el contrario, en una malla un componente puede estar √ √ a 2( n − 1) enlaces de otros componentes (o a n enlaces de distancia si la malla de interconexión conecta entre sí los bordes opuestos). De esta manera, el retardo de la comunicación en un hipercubo es significativamente menor que en una malla.

20.3.3 Arquitecturas paralelas de bases de datos

Existen varios modelos de arquitecturas para las máquinas paralelas. En la Figura 20.8 se muestran algunos de los más importantes (en la figura, M quiere decir memoria, P procesador y los discos se dibujan como cilindros): • Memoria compartida. Todos los procesadores comparten una memoria común (Figura 20.8a). • Disco compartido. Todos los procesadores comparten un conjunto de discos común (Figura 20.8b). Algunas veces los sistemas de disco compartido se denominan agrupaciones. • Sin compartimiento. Los procesadores no comparten ni memoria ni disco (Figura 20.8c). • Jerárquica. Este modelo es un híbrido de las arquitecturas anteriores (Figura 20.8d). En los Apartados 20.3.3.1 hasta el 20.3.3.4 se abordará cada uno de estos modelos.

www.detodoprogramacion.com


20.3

P

M

P

P

M

P

P

M

P

P

M

P

P

M

P

Sistemas paralelos

661

M

(a) memoria compartida M

P P

M

M

P P

P P

M

(b) disco compartido

M

P

M

P

M

P P

P

P

P

P

P

P

P

P

P

(c) sin compartimiento Figura 20.8

P

M

(d) jerárquica Arquitecturas paralelas de bases de datos.

Las técnicas utilizadas para acelerar el procesamiento de transacciones en sistemas servidores de datos, como la caché de datos y bloqueos y la liberación de bloqueos, tratadas en el Apartado 20.2.2, también se pueden utilizar en bases de datos paralelas de discos compartidos además de en bases de datos paralelas sin compartimiento. De hecho, son muy importantes para el procesamiento eficiente de transacciones en tales sistemas.

20.3.3.1 Memoria compartida

En una arquitectura de memoria compartida los procesadores y los discos tienen acceso a una memoria común, normalmente a través de un bus o de una red de interconexión. El beneficio de la memoria compartida es la extremada eficiencia en cuanto a la comunicación entre procesadores—cualquier procesador puede acceder a los datos de la memoria compartida sin necesidad de la intervención del software. Un procesador puede enviar mensajes a otros procesadores utilizando escrituras en la memoria de modo que la velocidad de envío es mucho mayor (normalmente es inferior a un microsegundo) que la que se alcanza con un mecanismo de comunicación. El inconveniente de las máquinas con memoria compartida es que la arquitectura no puede ir más allá de 32 o 64 procesadores porque el bus o la red de interconexión se convertirían en un cuello de botella (ya que está compartido por todos los procesadores). Llega un momento en el que no sirve de nada añadir más procesadores ya que éstos emplean la mayoría de su tiempo esperando su turno para utilizar el bus y así poder acceder a la memoria. Las arquitecturas de memoria compartida suelen dotar a cada procesador de una memoria caché muy grande para evitar las referencias a la memoria compartida siempre que sea posible. No obstante, en la caché no podrán estar todos los datos y no podrá evitarse el acceso a la memoria compartida. Además, las cachés necesitan mantener la coherencia; esto es, si un procesador realiza una escritura en una posición de memoria, los datos de dicha posición de memoria se deberían actualizar en o eliminar de cualquier procesador donde estuvieran los datos en caché. El mantenimiento de la coherencia de la caché aumenta la sobrecarga cuando aumenta el número de procesadores. Por estas razones las máquinas con memoria compartida no pueden extenderse llegado un punto; las máquinas actuales con memoria compartida no pueden soportar más de 64 procesadores.

www.detodoprogramacion.com


662

Capítulo 20

Arquitecturas de los sistemas de bases de datos

20.3.3.2 Disco compartido

En el modelo de disco compartido todos los procesadores pueden acceder directamente a todos los discos a través de una red de interconexión, pero los procesadores tienen memorias privadas. Las arquitecturas de disco compartido ofrecen dos ventajas respecto de las de memoria compartida. Primero, el bus de la memoria deja de ser un cuello de botella ya que cada procesador dispone de memoria propia. Segundo, esta arquitectura ofrece una forma barata para proporcionar una cierta tolerancia ante fallos: si falla un procesador (o su memoria) los demás procesadores pueden hacerse cargo de sus tareas ya que la base de datos reside en los discos, a los cuales tienen acceso todos los procesadores. Como se describía en el Capítulo 11, utilizando una arquitectura RAID también puede conseguirse que el subsistema de discos sea tolerante ante fallos por sí mismo. La arquitectura de disco compartido tiene aceptación en bastantes aplicaciones. El problema principal de los sistemas de discos compartidos es, de nuevo, la ampliabilidad. Aunque el bus de la memoria no es un cuello de botella muy grande, la interconexión con el subsistema de discos es ahora el nuevo cuello de botella; esto es especialmente grave en situaciones en las que la base de datos realiza un gran número de accesos a los discos. Los sistemas de discos compartidos pueden soportar un mayor número de procesadores en comparación con los sistemas de memoria compartida, pero la comunicación entre los procesadores es más lenta (hasta unos pocos milisegundos si se carece de un hardware de propósito especial para comunicaciones) ya que se realiza a través de una red de interconexión. 20.3.3.3 Sin compartimiento

En un sistema sin compartimiento cada nodo de la máquina consta de un procesador, memoria y uno o más discos. Los procesadores de un nodo pueden comunicarse con un procesador de otro nodo utilizando una red de interconexión de alta velocidad. Un nodo funciona como el servidor de los datos almacenados en los discos que posee. El modelo sin compartimiento salva el inconveniente de requerir que todas las operaciones de E/S vayan a través de una única red de interconexión, ya que las referencias a los discos locales son servidas por los discos locales de cada procesador; solamente van por la red las peticiones, los accesos a discos remotos y las relaciones de resultados. Es más, habitualmente las redes de interconexión para los sistemas sin compartimiento se diseñan para ser ampliables por lo que su capacidad de transmisión crece a medida que se añaden nuevos nodos. Como consecuencia, las arquitecturas sin compartimiento son más ampliables y pueden soportar con facilidad un gran número de procesadores. El principal inconveniente de los sistemas sin compartimiento es el coste de comunicación y de acceso a discos remotos, coste que es mayor que el que se produce en las arquitecturas de memoria o disco compartido, ya que el envío de datos provoca la intervención del software en ambos extremos. 20.3.3.4 Jerárquica

La arquitectura jerárquica combina las características de las arquitecturas de memoria compartida, de disco compartido y sin compartimiento. A alto nivel el sistema está formado por nodos que están conectados mediante una red de interconexión y que no comparten ni memoria ni discos. Así, el nivel más alto es una arquitectura sin compartimiento. Cada nodo del sistema podría ser en realidad un sistema de memoria compartida con algunos procesadores. Alternativamente, cada nodo podría ser un sistema de disco compartido y cada uno de estos sistemas de disco compartido podría ser a su vez un sistema de memoria compartida. De esta manera, un sistema podría construirse como una jerarquía con una arquitectura de memoria compartida con pocos procesadores en la base, en lo más alto una arquitectura sin compartimiento y quizá una arquitectura de disco compartido en el medio. En la Figura 20.8d se muestra una arquitectura jerárquica con nodos de memoria compartida conectados entre sí con una arquitectura sin compartimiento. Hoy en día los sistemas paralelos comerciales de bases de datos pueden ejecutarse sobre varias de estas arquitecturas. Los intentos de reducción de complejidad de programación de estos sistemas han dado lugar a las arquitecturas de memoria virtual distribuida, en las que hay una única memoria compartida desde el punto de vista lógico, pero hay varios sistemas de memoria disjuntos desde el punto de vista físico; se

www.detodoprogramacion.com


20.4

sitio A

Sistemas distribuidos

663

sitio C

red

comunicación a través de la red

sitio B Figura 20.9

Un sistema distribuido.

obtiene una única vista del área de memoria virtual de estas memorias disjuntas mediante un hardware de asignación de memoria virtual en conjunción con un software extra. Dado que las velocidades de acceso son diferentes, dependiendo de si la página está disponible localmente o no, esta arquitectura también se denomina arquitectura de memoria no uniforme (NUMA, Nonuniform Memory Architecture).

20.4 Sistemas distribuidos

En un sistema distribuido de bases de datos se almacena la base de datos en varias computadoras. Los medios de comunicación como las redes de alta velocidad o las líneas telefónicas pueden poner en contacto las distintas computadoras de un sistema distribuido. No comparten ni memoria ni discos. Las computadoras de un sistema distribuido pueden variar en tamaño y función pudiendo abarcar desde las estaciones de trabajo a los grandes sistemas. Dependiendo del contexto en el que se mencionen existen diferentes nombres para referirse a las computadoras que forman parte de un sistema distribuido, tales como sitios o nodos. Para enfatizar la distribución física de estos sistemas se emplean principalmente el término sitio. En la Figura 20.9 se muestra la estructura general de un sistema distribuido. Las principales diferencias entre las bases de datos paralelas sin compartimientos y las bases de datos distribuidas son que las bases de datos distribuidas normalmente se encuentran en varios lugares geográficos distintos, se administran de forma separada y poseen una interconexión más lenta. Otra gran diferencia es que en un sistema distribuido existen dos tipos de transacciones: locales y globales. Una transacción local es aquella que accede a los datos del único sitio en el cual se inició la transacción. Por otra parte, una transacción global es la que, o bien accede a los datos situados en un sitio diferente de aquél en el que se inició la transacción, o bien accede a datos de varios sitios distintos. Existen varias razones para construir sistemas distribuidos de bases de datos, incluyendo el compartimiento de los datos, la autonomía y la disponibilidad. • Datos compartidos. La principal ventaja de construir un sistema distribuido de bases de datos es poder disponer de un entorno donde los usuarios puedan acceder desde una única ubicación a los datos que residen en otras ubicaciones. Por ejemplo, en un sistema de banca distribuida, donde cada sucursal almacena datos relacionados con dicha sucursal, es posible que un usuario de una de las sucursales acceda a los datos de otra sucursal. Sin esta capacidad, un usuario que quisiera transferir fondos de una sucursal a otra tendría que recurrir a algún mecanismo externo que pudiera enlazar los sistemas existentes.

www.detodoprogramacion.com


664

Capítulo 20

Arquitecturas de los sistemas de bases de datos

• Autonomía. La principal ventaja de compartir datos por medio de distribución de datos es que cada ubicación es capaz de mantener un grado de control sobre los datos que se almacenan localmente. En un sistema centralizado, el administrador de bases de datos de la ubicación central controla la base de datos. En un sistema distribuido, existe un administrador de bases de datos global responsable de todo el sistema. Una parte de estas responsabilidades se delegan al administrador de bases de datos local de cada sitio. Dependiendo del diseño del sistema distribuido de bases de datos, cada administrador puede tener un grado diferente de autonomía local. La posibilidad de autonomía local es a menudo una de las grandes ventajas de las bases de datos distribuidas. • Disponibilidad. Si un sitio de un sistema distribuido falla, los sitios restantes pueden seguir trabajando. En particular, si los elementos de datos están replicados en varios sitios, una transacción que necesite un elemento de datos en particular puede encontrarlo en varios sitios. De este modo, el fallo de un sitio no implica necesariamente la caída del sistema. El sistema puede detectar el fallo de un sitio y es posible que sea necesario aplicar acciones apropiadas para la recuperación del fallo. El sistema no debe seguir utilizando los servicios del sitio que falló. Finalmente, cuando el sitio que falló se recupera o se repara, debe haber mecanismos disponibles para integrarlo sin problemas de nuevo en el sistema. Aunque la recuperación ante un fallo es más compleja en los sistemas distribuidos que en los sistemas centralizados, la capacidad que tienen muchos sistemas de continuar trabajando a pesar del fallo en uno de los sitios produce una mayor disponibilidad. La disponibilidad es crucial para los sistemas de bases de datos que se utilizan en aplicaciones de tiempo real. Que, por ejemplo, una línea aérea pierda el acceso a los datos puede provocar la pérdida de potenciales compradores de billetes en favor de la competencia. 20.4.1 Un ejemplo de una base de datos distribuida

Considérese un sistema bancario compuesto por cuatro sucursales situadas en cuatro ciudades diferentes. Cada sucursal posee su propia computadora con una base de datos que alberga todas las cuentas abiertas en dicha sucursal. Así, cada una de estas instalaciones se considera un sitio. También hay un único sitio que mantiene la información relativa a todas las sucursales del banco. Cada sucursal dispone (entre otras) de una relación cuenta(Esquema_cuenta), donde Esquema_cuenta = (número_cuenta, nombre_sucursal, saldo) El sitio que contiene información acerca de las cuatro sucursales mantiene la relación sucursal(Esquema _sucursal), donde Esquema_sucursal = (nombre_sucursal, ciudad_sucursal, activos) Existen otras relaciones en los distintos sitios que serán ignoradas para los propósitos del ejemplo. Para ilustrar la diferencia entre los dos tipos de transacciones considérese la transacción que suma 50 e a la cuenta C-177 situada en la sucursal de Cercedilla. La transacción se considera local si ésta comenzó en la sucursal de Cercedilla; en otro caso, se considera global. Una transacción que transfiere 50 e desde la cuenta C-177 a la cuenta C-305, que se encuentra en la sucursal de Guadarrama, es una transacción global ya que como resultado de su ejecución se accede a datos de dos sitios diferentes. En un sistema distribuido de bases de datos ideal, los sitios deberían compartir un esquema global común (aunque algunas relaciones se puedan almacenar sólo en algunos sitios), todos los sitios deberían ejecutar el mismo software de gestión de bases de datos distribuidas, y los sitios deberían conocer la existencia de los demás. Si una base de datos distribuida se construye partiendo de cero, realmente debería ser posible lograr los objetivos anteriores. Sin embargo, en la realidad, una base de datos distribuida se tiene que construir enlazando múltiples sistemas de bases de datos que ya existen, cada uno con su propio esquema y posiblemente ejecutando diferente software de gestión de bases de datos. A veces, tales sistemas reciben el nombre de sistemas de bases de datos múltiples o sistemas de bases de datos distribuidos y heterogéneos. En el Apartado 22.8 se estudian dichos sistemas y se muestra cómo conseguir un cierto grado de control global a pesar de la heterogeneidad de los sistemas que lo componen.

www.detodoprogramacion.com


20.4

Sistemas distribuidos

665

20.4.2 Aspectos de la implementación

La atomicidad de las transacciones es un aspecto importante de la construcción de un sistema distribuido de bases de datos. Si una transacción se ejecuta a lo largo de dos sitios, a menos que los diseñadores del sistema sean cuidadosos, puede comprometerse en un sitio y cancelarse en otro, lo que conduciría a un estado de inconsistencia. Los protocolos de compromiso de transacciones aseguran que tales situaciones no se produzcan. El protocolo de compromiso de dos fases (C2F) es el más utilizado de estos protocolos. La idea básica de C2F es que cada sitio ejecuta la transacción justo hasta antes del compromiso, y entonces deja la decisión del compromiso a un único sitio coordinador; se dice que en ese punto la transacción está en estado preparada en el sitio. El coordinador decide comprometer la transacción sólo si la transacción alcanza el estado preparada en cada sitio donde se ejecutó; en otro caso (por ejemplo, si la transacción se canceló en algún sitio), el coordinador decide cancelar la transacción. Todos los sitios donde la transacción se ejecutó deben acatar la decisión del coordinador. Si un sitio falla cuando una transacción se encuentra en estado preparada, cuando el sitio se recupere del fallo debería estar en posición de comprometer o cancelar la transacción dependiendo de la decisión del coordinador. El protocolo C2F se describe en detalle en el Apartado 22.4.1. El control de concurrencia es otra característica de una base de datos distribuida. Como una transacción puede acceder a elementos de datos de varios sitios, los administradores de transacciones de varios sitios pueden necesitar coordinarse para implementar el control de concurrencia. Si se utiliza bloqueo (como casi siempre sucede en la práctica), el bloqueo se puede realizar de forma local en los sitios que contienen los elementos de datos accedidos, pero también existe posibilidad de un interbloqueo que involucre a transacciones originadas en múltiples sitios. Por lo tanto, es necesario llevar la detección de interbloqueos a lo largo de múltiples sitios. Los fallos son más comunes en los sistemas distribuidos dado que no sólo las computadoras pueden fallar, sino que también pueden fallar los enlaces de comunicaciones. La réplica de los elementos de datos, que es la clave para el funcionamiento continuado de las bases de datos distribuidas cuando ocurren fallos, complica aún más el control de concurrencia. El Apartado 22.5 proporciona más detalles sobre el control de concurrencia en bases de datos distribuidas. Los modelos estándar de transacciones, basados en múltiples acciones llevadas a cabo por una única unidad de programa, son a menudo inapropiadas para realizar tareas que cruzan los límites de las bases de datos que no pueden o no cooperarán para implementar protocolos como C2F. Para estas tareas se utilizan generalmente técnicas alternativas, basadas en mensajería persistente para las comunicaciones. Los modelos estándar de transacciones, basados en múltiples acciones llevadas a cabo por una única unidad de programa, son a menudo inapropiadas para realizar tareas que cruzan los límites de las bases de datos que no pueden o no cooperarán para implementar protocolos como el C2F. Para estas tareas se utilizan generalmente técnicas alternativas, basadas en mensajería persistente para las comunicaciones. Cuando las tareas a realizar son complejas, involucrando múltiples bases de datos y múltiples interacciones con humanos, la coordinación de las tareas y asegurar las propiedades de las transacciones para las tareas se vuelve más complicado. Los sistemas de gestión de flujos de trabajo son sistemas diseñados para ayudar en la realización de dichas tareas. El Apartado 22.4.3 describe la mensajería persistente, mientras que el Apartado 25.2 describe los sistemas de gestión de flujos de trabajo. En caso de que una empresa tenga que escoger entre una arquitectura distribuida y una arquitectura centralizada para implementar una aplicación, el arquitecto del sistema debe sopesar las ventajas frente a las desventajas de la distribución de datos. Ya se han examinado las ventajas de utilizar bases de datos distribuidas. El principal inconveniente de los sistemas distribuidos de bases de datos es la complejidad añadida que es necesaria para garantizar la coordinación apropiada entre los sitios. Esta creciente complejidad tiene varias facetas: • Coste de desarrollo del software. La implementación de un sistema distribuido de bases de datos es más difícil y, por tanto, más costoso. • Mayor probabilidad de errores. Como los sitios que constituyen el sistema distribuido operan en paralelo es más difícil asegurarse de la corrección de los algoritmos, del funcionamiento especial durante los fallos de parte del sistema así como de la recuperación. Son probables errores extremadamente sutiles.

www.detodoprogramacion.com


666

Capítulo 20

Arquitecturas de los sistemas de bases de datos

• Mayor sobrecarga de procesamiento. El intercambio de mensajes y el cómputo adicional necesario para conseguir la coordinación entre los distintos sitios constituyen una forma de sobrecarga que no surge en los sistemas centralizados. Existen varios enfoques acerca del diseño de las bases de datos distribuidas que abarcan desde los diseños completamente distribuidos hasta los que incluyen un alto grado de centralización. Se estudiarán en el Capítulo 22. 20.5 Tipos de redes

Las bases de datos distribuidas y los sistemas cliente–servidor se construyen en torno a las redes de comunicación. Existen básicamente dos clases de redes: las redes de área local y las redes de área amplia. La diferencia principal entre ambas es la forma en que están distribuidas geográficamente. Las redes de área local están compuestas por procesadores distribuidos en áreas geográficas pequeñas tales como un único edificio o varios edificios adyacentes. Por su parte, las redes de área amplia se componen de un número determinado de procesadores autónomos que están distribuidos a lo largo de una extensa área geográfica (como puede ser España o el mundo entero). Estas diferencias implican importantes variaciones en la velocidad y en la fiabilidad de la red de comunicación y quedan reflejadas en el diseño del sistema operativo distribuido. 20.5.1 Redes de área local

Las redes de área local (LAN, Local Area Network) (Figura 20.10) surgen a principios de los 70 como una forma de comunicación y de compartimiento de datos entre varias computadoras. La gente se dio cuenta de que en muchas empresas era más económico tener muchas computadoras pequeñas, cada una de ellas con sus propias aplicaciones, que un enorme y único sistema. La conexión de estas pequeñas computadoras formando una red parece un paso natural porque, probablemente, cada pequeña computadora necesite acceder a un conjunto complementario de dispositivos periféricos (como discos e impresoras) y porque en una empresa suele ser necesaria el compartimiento de algunos datos. Las LAN se utilizan generalmente en un entorno de oficina. Todos los puestos de estos sistemas están próximos entre sí por lo que los enlaces de comunicación suelen poseer una mayor velocidad y una tasa de errores más baja que la que se da en las redes de área amplia. Los enlaces más comunes en una red de área local son el par trenzado, el cable coaxial, la fibra óptica y, cada vez más, las conexiones inalámbricas. La velocidad de comunicación varía entre unos pocos megabits por segundo (en las redes de área

servidor de aplicaciones estación de trabajo estación de trabajo estación de trabajo

pasarela

impresora

portátil

Figura 20.10

servidor de archivos

Red de área local.

www.detodoprogramacion.com


20.5

Tipos de redes

667

cliente servidor cliente

conjunto de almacenamiento

conjunto de almacenamiento

LAN/WAN servidor

SAN

biblioteca de cintas

Figura 20.11

cliente

centro de procesamiento de datos proveedor de contenidos Web

Red de área de almacenamiento.

local inalámbricas), a un gigabit por segundo para Gigabit Ethernet. La Ethernet estándar funciona a 10 megabits por segundo, mientras que Fast Ethernet llega a 100 megabits por segundo. Una red de área de almacenamiento (SAN, Storage Area Network) es un tipo especial de red de área local de alta velocidad destinada a conectar numerosos bancos de dispositivos de almacenamiento (discos) a las computadoras que utilizan los datos (véase la Figura 20.11). Así, las redes de área de almacenamiento ayudan a construir sistemas de discos compartidos a gran escala. El motivo para utilizar redes de área de almacenamiento para conectar múltiples computadoras a grandes bancos de dispositivos de almacenamiento es esencialmente el mismo que para las bases de datos de disco compartido: • Ampliabilidad añadiendo más computadoras. • Alta disponibilidad, ya que los datos son accesibles incluso si falla alguna computadora. Las organizaciones RAID se utilizan en dispositivos de almacenamiento para asegurar la alta disponibilidad de los datos, permitiendo continuar al procesamiento incluso si falla algún disco. Las redes de área de almacenamiento se construyen normalmente con redundancia, como múltiples caminos entre nodos, así si un componente como un enlace o una conexión a la red falla, la red continúa funcionando. 20.5.2 Redes de área amplia

Las redes de área amplia (WAN, Wide Area Networks) surgen a finales de los 60 principalmente como un proyecto de investigación académica para proporcionar una comunicación eficiente entre varios lugares permitiendo que una gran comunidad de usuarios pudiera compartir hardware y software de una manera conveniente y económica. A principios de los años 60 se desarrollaron sistemas que permitían que terminales remotos se conectaran a una computadora central a través de la línea telefónica, pero no eran verdaderas WAN. Arpanet fue la primera WAN que se diseñó y se desarrolló. El trabajo en Arpanet comenzó en 1968. Arpanet ha crecido de tal forma que ha pasado de ser una red experimental de cuatro puestos a una red de redes extendida por todo el mundo, Internet, abarcando a cientos de millones de sistemas de computación. Los enlaces típicos de Internet son las líneas de fibra óptica y, a veces, los canales vía satélite. Las transferencias de datos para los enlaces de área amplia varían normalmente entre los pocos megabits por segundo y los cientos de gigabits por segundo. El último enlace, hasta el puesto del usuario, se basa a menudo en la tecnología de línea de suscriptor digital (DSL, Digital Subscriber Line) (que soporta unos pocos megabits por segundo), o módem de cable (que soporta 10 megabits por segundo) o conexiones de módem telefónico sobre líneas telefónicas (que soportan hasta 56 kilobits por segundo). Las redes WAN pueden pertenecer a dos tipos: • En las WAN de conexión discontinua, como las basadas en conexiones por radio, las computadoras están conectadas a la red sólo durante intervalos del tiempo. • En las WAN de conexión continua, como Internet, las computadoras están conectadas a la red continuamente.

www.detodoprogramacion.com


668

Capítulo 20

Arquitecturas de los sistemas de bases de datos

Las redes que no están continuamente conectadas no suelen permitir las transacciones entre distintos sitios, pero pueden almacenar copias locales de los datos remotos y actualizarlas periódicamente (por ejemplo, todas las noches). Para las aplicaciones en las que la consistencia no es un factor crítico, como ocurre en el compartimiento de documentos, los sistemas de software de grupo como Lotus Notes permiten realizar localmente las actualizaciones de los datos remotos y propagar más tarde dichas actualizaciones al sitio remoto. Debe detectarse y resolverse el riesgo potencial de conflicto entre varias actualizaciones realizadas en sitios diferentes. Más adelante, en el Apartado 24.5.4, se describe un mecanismo para detectar actualizaciones conflictivas; el mecanismo de resolución de actualizaciones conflictivas es, sin embargo, dependiente de la aplicación. 20.6 Resumen

• Los sistemas centralizados de bases de datos se ejecutan completamente en una única computadora. Con el crecimiento de las computadoras personales y las redes de área local, se ha ido desplazando hacia el lado del cliente la funcionalidad de la fachada de la base de datos de modo que los sistemas servidores provean la funcionalidad del sistema subyacente. Los protocolos de interfaz cliente – servidor han ayudado al crecimiento de los sistemas de bases de datos cliente– servidor. • Los servidores pueden ser servidores de transacciones o servidores de datos, aunque el uso de los servidores de transacciones excede ampliamente el uso de los servidores de datos para proporcionar servicios de bases de datos. ¤ Los servidores de transacciones tienen múltiples procesos, ejecutándose posiblemente en múltiples procesadores. Dado que estos procesos tienen acceso a los datos comunes, como la memoria intermedia de la base de datos, los sistemas almacenan dichos datos en memoria compartida. Además de los procesos que gestionan consultas, hay procesos del sistema que realizan tareas como la gestión de los bloqueos y del registro y los puntos de revisión. ¤ Los sistemas servidores de datos suministran datos sin formato a los clientes. Tales sistemas se esfuerzan en minimizar la comunicación entre clientes y servidores usando caché de datos y de bloqueos en los clientes. Los sistemas paralelos de bases de datos utilizan optimizaciones similares. • Los sistemas paralelos de bases de datos consisten en varios procesadores y varios discos conectados a través de una red de interconexión de alta velocidad. La ganancia de velocidad mide cuánto puede incrementarse la velocidad de procesamiento al incrementarse el paralelismo dada una transacción. La ampliabilidad mide lo bien que se gestiona un mayor número de transacciones cuando se incrementa el paralelismo. La interferencia, el sesgo y los costes de inicio actúan como barreras para obtener la ganancia de velocidad y la ampliabilidad ideales. • Las arquitecturas paralelas de bases de datos pueden clasificarse en arquitecturas de memoria compartida, de disco compartido, sin compartimiento o jerárquicas. Estas arquitecturas tienen distintos compromisos entre la ampliabilidad y la velocidad de comunicación. • Un sistema de bases de datos distribuido es un conjunto de bases de datos parcialmente independientes que (idealmente) comparten un esquema común y coordinan el procesamiento de transacciones que acceden a datos remotos. Los sistemas se comunican entre sí a través de una red de comunicación que gestiona el encaminamiento y las estrategias de conexión. • Existen dos tipos principales de redes de comunicación: las redes de área local y las de área amplia. Las redes de área local conectan nodos que están distribuidos sobre áreas geográficas pequeñas tales como un único edificio o varios edificios adyacentes. Las redes de área amplia conectan nodos a lo largo de una extensa área geográfica. Actualmente, la red de área amplia más extensa que se utiliza es Internet. Las redes de área de almacenamiento son un tipo especial de redes de área local diseñadas para proporcionar interconexión rápida entre grandes bancos de dispositivos de almacenamiento y múltiples computadoras.

www.detodoprogramacion.com


Ejercicios prácticos

669

Términos de repaso

¤ ¤ ¤ ¤

• Sistemas centralizados. • Sistemas servidores. • Paralelismo de grano grueso.

Lineal. Sublineal. Por lotes. De transacciones.

• Paralelismo de grano fino.

• Costes de inicio.

• Estructura de proceso de la base de datos.

• Interferencia.

• Exclusión mutua.

• Sesgo.

• Hebra.

• Redes de interconexión. ¤ Bus. ¤ Malla. ¤ Hipercubo.

• Procesos del servidor: ¤ ¤ ¤ ¤ ¤

Proceso administrador de bloqueos. Proceso escritor de bases de datos. Proceso escritor del registro. Proceso punto de revisión. Proceso monitor de procesos.

• Servidor de consultas.

• Arquitecturas paralelas de bases de datos. ¤ Memoria compartida. ¤ Disco compartido (agrupaciones). ¤ Sin compartimiento. ¤ Jerárquica. • Tolerancia ante fallos.

• Servidor de datos.

• Memoria virtual distribuida.

• Sistemas cliente – servidor. • Servidor de transacciones.

¤ ¤ ¤ ¤ ¤ ¤

Preextracción. Liberación de bloqueos. Caché de datos. Coherencia de caché. Caché de bloqueos. Comunicar.

• Arquitectura de memoria no uniforme. • Sistemas distribuidos. • Bases de datos distribuidas. ¤ ¤ ¤ ¤

• Sistemas paralelos. • Productividad.

Sitios (nodos). Transacción local. Transacción global. Autonomía local.

• Sistema con múltiples bases de datos.

• Tiempo de respuesta.

• Tipos de redes.

• Ganancia de velocidad:

¤ Redes de área local (LAN). ¤ Redes de área amplia (WAN). ¤ Redes de área de almacenamiento (SAN).

¤ Lineal. ¤ Sublineal. • Ampliabilidad:

Ejercicios prácticos

20.1 En lugar de almacenar estructuras compartidas en memoria compartida, una arquitectura alternativa podría ser almacenarlas en la memoria local de un proceso especial, y acceder a los datos compartidos mediante comunicación entre procesos con el proceso. ¿Cuál sería la desventaja de dicha arquitectura? 20.2 La máquina que hace de servidor en los sistemas cliente–servidor típicos es mucho más potente que los clientes, es decir, su procesador es más rápido, puede tener varios procesadores, tiene más memoria y tiene discos de mayor capacidad. En vez de esto, considérese el caso en el que los clientes y el servidor tuvieran exactamente la misma potencia. ¿Tendría sentido construir un sistema cliente – servidor en ese caso? ¿Por qué? ¿Qué caso se ajustaría mejor a una arquitectura servidora de datos? 20.3 Considérese un sistema de base de datos orientada a objetos sobre una arquitectura cliente–servidor en la que el servidor actúa como servidor de datos.

www.detodoprogramacion.com


670

Capítulo 20

Arquitecturas de los sistemas de bases de datos

a. ¿Cuál es el efecto de la velocidad de interconexión entre el cliente y el servidor en los casos de envío de páginas y de objetos? b. Si se utiliza envío de páginas, la caché de datos en el cliente puede organizarse como una caché de objetos o una caché de páginas. La caché de páginas almacena los datos en unidades de páginas mientras que la caché de objetos almacena los datos en unidades de objetos. Supóngase que los objetos son más pequeños que una página. Descríbase una ventaja de la caché de objetos frente a la caché de páginas. 20.4 Supóngase una transacción escrita en C con código SQL incorporado que ocupa el 80 % del tiempo en ejecutar el código SQL y sólo el 20 % restante en el código C. ¿Qué ganancia de velocidad puede esperarse si sólo se hace paralelo el código SQL? Justifíquese la respuesta. 20.5 Considérese una red basada en líneas de acceso telefónico en la que los sitios se comunican periódicamente, por ejemplo, todas las noches. Estas redes suelen tener un servidor y varios clientes. Los sitios que actúan como clientes están conectados sólo con el servidor e intercambian los datos con el resto de clientes almacenándolos en el servidor y recuperando los almacenados por otros clientes en el servidor. ¿Cuál es la ventaja de tal arquitectura frente a una en la que un sitio pueda intercambiar datos con otro mediante acceso telefónico directo? Ejercicios

20.6 ¿Por qué es relativamente fácil trasladar una base de datos desde una máquina con un único procesador a otra con varios procesadores si no es necesario hacer paralelas las consultas individuales? 20.7 Las arquitecturas servidoras de transacciones son populares entre las bases de datos relacionales cliente– servidor, en las que las transacciones son cortas. Por el contrario, las arquitecturas servidoras de datos son populares entre los sistemas cliente–servidor de bases de datos orientadas a objetos, donde las transacciones son relativamente largas. Dense dos razones por las que los servidores de datos puedan ser populares entre las bases de datos orientadas a objetos y no los sean entre las bases de datos relacionales. 20.8 ¿Qué es la liberación de bloqueos y bajo qué condiciones es necesaria? ¿Por qué no es necesario si la unidad de envío de datos es un elemento? 20.9 Supóngase una persona a cargo de las operaciones de la base de datos de una empresa cuyo trabajo principal es el de procesar transacciones. Supóngase además que la empresa crece rápidamente cada año y que el sistema informático actual se ha quedado pequeño. Cuando se escoja una nueva computadora paralela, ¿qué factor será más importante: la ganancia de velocidad, la ampliabilidad por lotes o la ampliabilidad de transacciones? ¿Por qué? 20.10 Los sistemas de bases de datos se implementan normalmente como un conjunto de procesos (o hebras) que comparten un área de memoria. a. ¿Cómo se controla el acceso a la memoria compartida? b. ¿Es apropiado el bloqueo de dos fases para secuenciar el acceso a las estructuras de datos en la memoria compartida? Explíquese la respuesta. 20.11 En un sistema de procesamiento de transacciones, ¿cuáles son los factores que trabajan en contra de la ampliabilidad lineal? ¿Cuál de esos factores es probablemente el más importante en cada una de estas arquitecturas: memoria compartida, disco compartido y sin compartimiento? 20.12 La velocidad de los procesadores se ha incrementado mucho más rápidamente que las velocidades de acceso a memoria. ¿Qué impacto tiene esto sobre el número de procesadores que pueden compartir de modo efectivo una memoria común? 20.13 Considérese un banco que dispone de un conjunto de sitios en los que se ejecuta un sistema de base de datos. Supóngase que la transferencia electrónica de dinero entre ellos es el único modo de interacción de las bases de datos. ¿Puede tal sistema ser calificado como distribuido? ¿Por qué?

www.detodoprogramacion.com


Notas bibliográficas

671

Notas bibliográ cas

Hennessy et al. [2002] proporcionan una excelente introducción al área de la arquitectura de computadoras. Gray y Reuter [1993] dan una descripción en su libro del procesamiento de transacciones incluyendo la arquitectura de cliente – servidor y los sistemas distribuidos. Las notas bibliográficas del Capítulo 4 proporcionan referencias a más infomración sobre ODBC, JDBC y otras interfaces de programación para aplicaciones. Carey et al. [1991] y Franklin et al. [1993] describen técnicas de caché de datos para los sistemas de bases de datos cliente – servidor. Biliris y Orenstein [1994] tratan los sistemas de gestión de almacenamiento de objetos incluyendo aspectos relacionados con los sistemas cliente–servidor. En Franklin et al. [1992] y Mohan y Narang [1994] pueden encontrarse algunas técnicas para la recuperación en sistemas cliente– servidor. DeWitt y Gray [1992] describen los sistemas paralelos de bases de datos incluyendo sus propias arquitecturas y medidas de rendimiento. Duncan [1990] introduce una vista de las arquitecturas paralelas de computadoras. Dubois y Thakkar [1992] es una colección de artículos sobre las arquitecturas ampliables de memoria compartida. Las agrupaciones DEC con Rdb constituyen uno de los primeros usuarios comerciales de la arquitectura de bases de datos de disco compartido Rdb ahora es propiedad de Oracle y se denomina Oracle Rdb. Digital Equipment Corporation (DEC) es ahora propiedad de Compaq. La máquina de base de datos Teradata fue uno de los primeros sistemas comerciales que utilizaron la arquitectura sin compartimiento de bases de datos. También se construyeron sobre arquitecturas sin compartimiento los prototipos de investigación Grace y Gamma. El libro de texto de Ozsu y Valduriez [1999] trata los sistemas distribuidos de bases de datos. Se pueden encontrar más referencias sobre los sistemas de bases de datos paralelos y distribuidos en las notas bibliográficas de los Capítulos 21 y 22, respectivamente. Comer y Droms [2003] y Thomas [1996] describen las redes de computadoras e Internet. Tanenbaum [2002] y Halsall [1996] proporcionan revisiones generales de las redes de computadoras.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

21

Bases de datos paralelas

En este capítulo se estudian los algoritmos fundamentales de los sistemas paralelos de bases de datos basados en el modelo de datos relacional. En concreto, este capítulo se centra en la ubicación de los datos en varios discos y en la evaluación en paralelo de las operaciones relacionales, dos conceptos que han sido esenciales para el éxito de las bases de datos paralelas. 21.1 Introducción

Quince años atrás los sistemas paralelos de bases de datos habían sido casi descartados, incluso por algunos de sus más firmes partidarios. Actualmente los venden con éxito casi todas las marcas de bases de datos. Este cambio ha sido impulsado por varios desafíos: • Los requisitos transaccionales de las empresas han aumentado con el creciente empleo de las computadoras. Además, el crecimiento de Web ha creado muchos sitios con millones de visitantes, y la creciente cantidad de datos obtenidos de esos visitantes ha generado en muchas empresas bases de datos enormes. • Las empresas utilizan volúmenes crecientes de datos—como los relativos a lo que se compra, los enlaces Web que se pulsan o la hora a la que se realizan las llamadas telefónicas—para planificar sus actividades y sus tarifas. Las consultas utilizadas para estos fines se denominan consultas de ayuda a la toma de decisiones y pueden llegar a necesitar varios terabytes de datos. Los sistemas con un solo procesador no son capaces de tratar tales volúmenes de datos a la velocidad necesaria. • La naturaleza orientada a conjuntos de las consultas a las bases de datos se presta de modo natural a la paralelización. Diferentes sistemas comerciales y experimentales han demostrado la potencia y la dimensionabilidad del procesamiento paralelo de las consultas. • Al abaratarse los microprocesadores, las máquinas paralelas se han popularizado y se han vuelto relativamente baratas. Como se ha estudiado en el Capítulo 20, el paralelismo se utiliza para mejorar la velocidad, pues las consultas se ejecutan más rápido debido a que disponen de más recursos, como procesadores y discos. El paralelismo también se utiliza para proporcionar dimensionabilidad, pues la creciente carga de trabajo se trata sin incrementar el tiempo de respuesta, mediante un aumento del grado de paralelismo. En el Capítulo 20 se esbozaron las diferentes arquitecturas de los sistemas paralelos de bases de datos: de memoria compartida, de discos compartidos, sin compartimiento y arquitecturas jerárquicas. En resumen, en las arquitecturas de memoria compartida todos los procesadores comparten memoria y discos; en las arquitecturas de disco compartido los procesadores tienen memorias independientes 673

www.detodoprogramacion.com


674

Capítulo 21

Bases de datos paralelas

pero comparten los discos; en las arquitecturas sin compartimiento los procesadores no comparten ni la memoria ni los discos; y las arquitecturas jerárquicas tienen nodos que no comparten entre sí ni la memoria ni los discos, pero cada nodo tiene internamente una arquitectura de memoria o de disco compartido. 21.2 Paralelismo de E/S

En su forma más sencilla, el término paralelismo de E/S se refiere a la división de las relaciones entre varios discos para reducir el tiempo necesario de su recuperación. La forma más habitual de división de datos en un entorno de bases de datos paralelas es la división horizontal. En la división horizontal, las tuplas de cada relación se dividen (o desagrupan) entre varios discos, de modo que cada tupla resida en uno distinto. Se han propuesto varias estrategias de división. 21.2.1 Técnicas de división

Se presentan tres estrategias básicas para la división de datos. Supóngase que hay n discos, D0 , D1 , . . . , Dn−1 , entre los cuales se van a dividir los datos. • Turno rotatorio. La relación se explora en un orden cualquiera y la i-ésima tupla se envía al disco numerado Di mod n . El esquema de turno rotatorio asegura una distribución homogénea de las tuplas entre los discos; es decir, cada disco tiene aproximadamente el mismo número de tuplas que los demás. • División por asociación. En esta estrategia de desagrupación uno o varios atributos del esquema de la relación dada se designan como atributos de la división. Se escoge una función de asociación cuyo rango sea {0, 1, . . . , n − 1}. Cada tupla de la relación original se asocia en términos de los atributos de la división. Si la función de asociación devuelve i, la tupla se ubica en el disco Di . • División por rangos. Esta estrategia distribuye rangos contiguos de valores de los atributos a cada disco. Se escoge un atributo de división, A, como vector de división. La relación se divide de la manera siguiente. Sea [v0 , v1 , . . . , vn−2 ] el vector de división, tal que , si i < j, entonces vi < vj . Considérese una tupla t tal que t[A] = x. Si x < v0 entonces t se ubica en el disco D0 . Si x ≥ vn−2 , entonces t se ubica en el disco Dn−1 . Si vi ≤ x < vi+1 , entonces t se ubica en el disco Di+1 . Por ejemplo, en una división por rangos con tres discos numerados del cero al dos se pueden asignar las tuplas con valores menores que cinco al disco cero, las de valores entre cinco y cuarenta al disco uno, y las que tienen valores mayores que cuarenta al disco dos. 21.2.2 Comparación de las técnicas de división

Una vez dividida una relación entre varios discos, se puede recuperar en paralelo utilizándolos todos. De modo parecido, cuando se está dividiendo una relación, se puede escribir en paralelo en varios discos. De esta manera, las velocidades de transferencia de lectura o de escritura de la relación completa son mucho mayores con paralelismo de E/S que sin él. Sin embargo, la lectura de la relación completa, o exploración de la relación es sólo uno de los tipos de acceso a los datos. El acceso a los datos puede clasificarse de la manera siguiente: 1. Exploración de la relación completa. 2. Localización de tuplas de manera asociativa, (por ejemplo, nombre_empleado = “García”); estas consultas, denominadas consultas concretas, buscan tuplas que tengan un valor concreto para un atributo determinado. 3. Localización de todas las tuplas cuyo valor de un atributo dado se halle en un rango especificado (por ejemplo, 10.000 < sueldo < 20.000); estas consultas se denominan consultas de rango. Las diferentes técnicas de división permiten estos tipos de acceso con diferentes niveles de eficacia:

www.detodoprogramacion.com


21.2

Paralelismo de E/S

675

• Turno rotatorio. El esquema se adapta perfectamente a las aplicaciones que desean leer secuencialmente la relación completa en cada consulta. Con este esquema tanto las consultas concretas como las de rango son difíciles de procesar, ya que se deben emplear en la búsqueda todos y cada uno de los n discos. • División por asociación. Este esquema se adapta mejor a las consultas concretas basadas en el atributo de división. Por ejemplo, si se divide una relación en términos del atributo número _teléfono, se puede responder a la consulta “Buscar el registro del empleado con número_teléfono = 5553333” aplicando la función de división por asociación a 5553333 y buscando luego en ese disco. Dirigir la consulta a un solo disco ahorra el coste inicial de comenzar una consulta en varios discos y deja a los demás discos libres para procesar otras consultas. La división por asociación también resulta útil para las exploraciones secuenciales de toda la relación. Si la función de asociación es una buena función aleatoria y los atributos de división constituyen una clave de la relación, el número de tuplas en cada uno de los discos es aproximadamente el mismo, sin mucha varianza. Por tanto, el tiempo empleado para explorar la relación es aproximadamente 1/n del necesario para explorar la relación en un sistema de disco único. El esquema, sin embargo, no se adapta bien a las búsquedas concretas en términos de atributos que no sean de división. La división basada en asociación tampoco resulta muy adecuada para las respuestas a consultas de rangos, dado que, generalmente, las funciones de asociación no conservan la proximidad dentro de ellos. Por tanto, hace falta explorar todos los discos para responder a las consultas de rango. • División por rangos. Este esquema se adapta bien a las consultas concretas y de rango basadas en el atributo de división. Para las consultas concretas se puede analizar el vector de división para encontrar el disco en el que reside la tupla. En las consultas de rango se consulta el vector de división para hallar el rango de discos en que pueden residir las tuplas. En ambos casos la búsqueda se limita exactamente a aquellos discos que pueden tener tuplas de interés. Una ventaja es que, si sólo hay unas cuantas tuplas en el rango consultado, la consulta se suele enviar a un solo disco, en vez de a todos. Dado que se pueden utilizar otros discos para responder a otras consultas, la división por rangos da lugar a una mayor productividad de consultas al tiempo que se mantiene un buen tiempo de respuesta. Por otro lado, si hay muchas tuplas en el rango consultado (como ocurre cuando el rango consultado es una fracción mayor del dominio de la relación), es necesario recuperar muchas tuplas de pocos discos, lo que origina un cuello de botella de E/S (punto caliente) en esos discos. En este ejemplo de sesgo de ejecución todo el procesamiento tiene lugar en una partición (o en sólo unas pocas). Por el contrario, la división por asociación y la de turno rotatorio emplearían todos los discos para esas consultas, lo que proporcionaría un tiempo de respuesta menor para aproximadamente la misma productividad. El tipo de división también afecta a otras operaciones relacionales, como las reuniones (véase el Apartado 21.5). De este modo, la elección de la técnica de división también depende de las operaciones que haya que ejecutar. En general, se prefieren las divisiones por asociación y en rangos al turno rotatorio. En un sistema con muchos discos, el número de discos en los que se divide una relación puede escogerse de la manera siguiente. Si una relación sólo contiene unas pocas tuplas que caben en un solo bloque de disco, es mejor asignarla a un solo disco. Las relaciones grandes se dividen preferiblemente entre todos los discos disponibles. Si una relación consta de m bloques de disco y hay n discos disponibles en el sistema, se deberán asignar a la relación min(m, n) discos. 21.2.3 Tratamiento del sesgo

La distribución de las tuplas al dividir una relación (excepto mediante el turno rotatorio) puede estar sesgada, con un porcentaje alto de tuplas ubicado en algunas divisiones y porcentajes menores en otras. Los diferentes tipos de sesgo se clasifican como: • Sesgo de los valores de los atributos. • Sesgo de la división.

www.detodoprogramacion.com


676

CapĂ­tulo 21

Bases de datos paralelas

El sesgo de los valores de los atributos se refiere al hecho de que algunos valores aparezcan en los atributos de divisiĂłn de muchas tuplas. Todas las tuplas con el mismo valor del atributo de divisiĂłn terminan en la misma particiĂłn, lo que da lugar al sesgo. El sesgo de la divisiĂłn se refiere al hecho de que puede haber un desequilibrio de carga en la divisiĂłn, aunque no haya sesgo en los atributos. El sesgo de los valores de los atributos puede dar lugar a una divisiĂłn sesgada independientemente de que se utilice divisiĂłn por rangos o por asociaciĂłn. Si no se escoge cuidadosamente el vector de divisiĂłn, la divisiĂłn por rangos puede dar lugar a sesgo de divisiĂłn. El sesgo de divisiĂłn es menos probable en la divisiĂłn por asociaciĂłn, si se ha escogido una buena funciĂłn de asociaciĂłn. Como se indicĂł en el Apartado 20.3.1, incluso un sesgo pequeĂąo puede dar lugar a una disminuciĂłn significativa del rendimiento. El sesgo es un problema que se agrava al aumentar el grado de paralelismo. Por ejemplo, si una relaciĂłn de mil tuplas se divide en diez partes y la divisiĂłn estĂĄ sesgada, puede haber algunas particiones de tamaĂąo menor que cien y otras de tamaĂąo mayor que cien; incluso si una particiĂłn llega a tener tamaĂąo doscientos, la aceleraciĂłn que se obtendrĂ­a al acceder en paralelo a las particiones sĂłlo serĂ­a de cinco, en lugar del valor de diez que cabrĂ­a esperar. Si la misma relaciĂłn tiene que dividirse en cien partes, cada particiĂłn tendrĂĄ de media diez tuplas. Si una particiĂłn llega a tener cuarenta tuplas (lo que es posible dado el gran nĂşmero de particiones) el aumento de velocidad que se obtendrĂ­a al acceder a ellas en paralelo serĂ­a de veinticinco, en vez de cien. Por tanto, se puede ver que la pĂŠrdida de aceleraciĂłn debida al sesgo aumenta con el paralelismo. Se puede construir un vector de divisiĂłn por rangos equilibrado mediante ordenaciĂłn. La relaciĂłn primero se ordena segĂşn los atributos de divisiĂłn. A continuaciĂłn se explora de forma ordenada. DespuĂŠs de que se haya leĂ­do cada 1/n de la relaciĂłn, se aĂąade el valor del atributo de divisiĂłn de la siguiente tupla al vector de divisiĂłn. En este caso, n denota el nĂşmero de particiones que hay que crear. En caso de que haya muchas tuplas con el mismo valor para el atributo de divisiĂłn, la tĂŠcnica puede seguir generando algo de sesgo. El inconveniente principal de este mĂŠtodo es la sobrecarga de E/S debida a la ordenaciĂłn inicial. La sobrecarga de E/S debida a la construcciĂłn de vectores de divisiĂłn por rangos equilibrados se puede reducir creando y almacenando una tabla de frecuencias, o histograma, de los valores de los atributos para todos los atributos de cada relaciĂłn. La Figura 21.1 muestra un ejemplo de un histograma para un atributo de tipo entero que toma valores en el rango de uno a veinticinco. Los histogramas ocupan poco espacio, por lo que en el catĂĄlogo se pueden almacenar histogramas de varios atributos diferentes. Resulta sencillo crear una funciĂłn de divisiĂłn por rangos equilibrada dado un histograma de los atributos de divisiĂłn. Si no se almacena el histograma es posible calcularlo de manera aproximada tomando muestras de la relaciĂłn. Estas muestras son las tuplas de un subconjunto de los bloques de disco elegido aleatoriamente. Otro enfoque para minimizar el efecto del sesgo, especialmente con la divisiĂłn por rangos, es el empleo de procesadores virtuales. En el enfoque de los procesadores virtuales se simula que el nĂşmero de procesadores virtuales es mĂşltiplo del nĂşmero de procesadores reales. Se puede usar cualquiera de las tĂŠcnicas de divisiĂłn y de evaluaciĂłn de consultas que se estudiarĂĄn posteriormente en este capĂ­tulo, sin embargo asignando las tuplas a los procesadores virtuales en lugar de a los reales. Los procesadores vir-

Figura 21.1

Ejemplo de histograma.

www.detodoprogramacion.com


21.3

Paralelismo entre consultas

677

tuales, a su vez, se hacen corresponder con los procesadores reales, generalmente mediante una división por turno rotatorio. La idea es que, incluso si uno de los rangos tuviera muchas más tuplas que los otros debido al sesgo, éstas se podrían repartir entre varios rangos de procesadores virtuales. La asignación por turno rotatorio de los procesadores virtuales a procesadores reales distribuiría el trabajo adicional entre varios procesadores reales, de forma que ningún procesador tuviera que asumir toda la carga.

21.3 Paralelismo entre consultas

En el paralelismo entre consultas se ejecutan en paralelo entre sí diferentes consultas o transacciones. La productividad de las transacciones puede aumentarse con esta forma de paralelismo. Sin embargo, el tiempo de respuesta de cada transacción no es menor que si se ejecutara aisladamente. Por ello, la aplicación principal del paralelismo entre consultas es la ampliación de los sistemas de procesamiento de transacciones para permitir un número mayor de transacciones por segundo. El paralelismo entre consultas es la forma más sencilla de paralelismo que se permite en los sistemas de bases de datos — especialmente en los sistemas paralelos de memoria compartida. Los sistemas de bases de datos diseñados para sistemas con un único procesador pueden utilizarse en arquitecturas paralelas de memoria compartida con pocos cambios o con ninguno, dado que incluso los sistemas secuenciales de bases de datos permiten el procesamiento concurrente. Las transacciones que se habrían realizado de manera concurrente en tiempo compartido en una máquina secuencial se realizan en paralelo en la arquitectura paralela de memoria compartida. Permitir el paralelismo entre consultas es más complicado en las arquitecturas de disco compartido y sin compartimiento. Los procesadores tienen que realizar algunas tareas, como los bloqueos y el registro histórico, de forma coordinada, y eso exige que se intercambien mensajes. Los sistemas de bases de datos con arquitectura paralela también deben asegurarse de que dos procesadores no actualicen simultáneamente los mismos datos de manera independiente. Además, cuando un procesador accede a los datos o los actualiza, el sistema de bases de datos debe garantizar que tenga su última versión en la memoria intermedia. El problema de asegurar que la versión sea la última disponible se denomina problema de coherencia de caché. Se dispone de varios protocolos para garantizar la coherencia caché; a menudo los protocolos de coherencia de la caché se integran con los de control de concurrencia de modo que se reduce la sobrecarga. Los protocolos de este tipo para sistemas de disco compartido son de la manera siguiente: 1. Antes de cualquier acceso de lectura o de escritura a una página, la transacción la bloquea en modo compartido o exclusivo, según corresponda. Inmediatamente después de obtener el bloqueo compartido o exclusivo de la página, la transacción lee también su copia más reciente del disco compartido. 2. Antes de que una transacción libere el bloqueo exclusivo de una página, la traslada al disco compartido; posteriormente libera el bloqueo. Este protocolo garantiza que, cuando una transacción establece un bloqueo compartido o exclusivo sobre una página, obtenga la copia correcta de la página. Otros protocolos más complejos evitan la lectura y escritura reiteradas del disco exigidas por el protocolo anterior. Estos protocolos no escriben las páginas en el disco cuando se liberan los bloqueos exclusivos. Cuando se obtiene un bloqueo compartido o exclusivo, si la versión más reciente de la página se halla en la memoria intermedia de algún procesador, se obtiene de allí. Hay que diseñar los protocolos para tratar peticiones concurrentes. Los protocolos de disco compartido pueden extenderse a las arquitecturas sin compartimiento mediante este esquema. Cada página tiene un procesador local Pi y se almacena en el disco Di . Cuando otros procesadores desean leer la página o escribir en ella, envían las peticiones a su procesador local Pi , dado que no pueden comunicarse directamente con el disco. Las otras acciones son iguales que en los protocolos de disco compartido. Los sistemas Oracle y Oracle Rdb son ejemplos de sistemas paralelos de bases de datos de disco compartido que permiten el paralelismo entre consultas.

www.detodoprogramacion.com


678

Capítulo 21

Bases de datos paralelas

21.4 Paralelismo en consultas

El paralelismo en consultas se refiere a la ejecución en paralelo de una única consulta en varios procesadores y discos. El empleo del paralelismo en consultas es importante para acelerar las consultas de ejecución prolongada. El paralelismo entre consultas no ayuda en esta tarea, dado que cada consulta se ejecuta de manera secuencial. Para ilustrar la evaluación en paralelo de una consulta, considérese una que exija que se ordene una relación. Supóngase que la relación se ha dividido entre varios discos mediante la división por rangos basada en algún atributo y que se solicita la ordenación basada en el atributo de división. La operación de ordenación se puede implementar ordenando cada partición en paralelo y luego se concatenan las particiones ordenadas para obtener la relación ordenada final. Por tanto, se pueden hacer paralelas las consultas haciendo paralelas las operaciones que las forman. Hay otra fuente de paralelismo para la evaluación de las consultas: el árbol de operadores de la consulta puede contener varias operaciones. La evaluación del árbol de operadores se puede hacer paralela evaluando en paralelo las operaciones que no tengan ninguna dependencia entre sí. Además, como se mencionó en el Capítulo 13, puede que se logre encauzar el resultado de una operación hacia otra. Las dos operaciones pueden ejecutarse en paralelo en procesadores separados, uno que genera el resultado que consume el otro, incluso simultáneamente con su generación. En resumen, hay dos maneras de ejecutar en paralelo una sola consulta: • Paralelismo en operaciones. Se puede acelerar el procesamiento de la consulta haciendo paralela la ejecución de cada una de sus operaciones individuales ordenación, selección, proyección y reunión. El paralelismo en operaciones se considera en el Apartado 21.5. • Paralelismo entre operaciones. Se puede acelerar el procesamiento de la consulta ejecutando en paralelo las diferentes operaciones de las expresiones de las consultas. Esta forma de paralelismo se considera en el Apartado 21.6. Las dos formas de paralelismo son complementarias y pueden utilizarse simultáneamente en una misma consulta. Dado que el número de operaciones de una consulta típica es pequeño comparado con el número de tuplas procesado por cada operación, la primera modalidad puede adaptarse mejor a un aumento del paralelismo. Sin embargo, con el número relativamente pequeño de procesadores de los sistemas paralelos típicos de hoy en día, ambas formas de paralelismo son importantes. En la siguiente discusión sobre la paralelización de las consultas se da por supuesto que éstas son sólo de lectura. La elección de los algoritmos para la evaluación de las consultas en paralelo depende de la arquitectura de la máquina. En lugar de presentar por separado los algoritmos para cada arquitectura se utilizará en la descripción un modelo de arquitectura sin compartimiento. Por tanto, se describirá explícitamente el momento en que se deben transferir los datos de un procesador a otro. Este modelo se puede simular con facilidad utilizando las otras arquitecturas, dado que la transferencia de los datos puede realizarse mediante la memoria compartida en las arquitecturas de memoria compartida y mediante los discos compartidos en las arquitecturas de discos compartidos. Por tanto, los algoritmos para las arquitecturas sin compartimiento también pueden utilizarse en las demás arquitecturas. Ocasionalmente se menciona la manera en que se pueden optimizar aún más los algoritmos para los sistemas de memoria o de discos compartidos. Para simplificar la exposición de los algoritmos se supone que existen n procesadores, P0 , P1 , . . . , Pn−1 y n discos, D0 , D1 , . . . , Dn−1 , donde el disco Di está asociado con el procesador Pi . Los sistemas reales pueden tener varios discos por cada procesador. No es difícil extender los algoritmos para que permitan varios discos por procesador: basta con permitir que Di sea un conjunto de discos. Sin embargo, en aras de la sencillez de la exposición, aquí se supondrá que Di es un solo disco. 21.5 Paralelismo en operaciones

Dado que las operaciones relacionales trabajan con relaciones que contienen grandes conjuntos de tuplas, las operaciones se pueden paralelizar ejecutándolas sobre subconjuntos diferentes de las relaciones en paralelo. Dado que el número de tuplas de cada relación puede ser grande, el grado de paralelismo

www.detodoprogramacion.com


21.5

Paralelismo en operaciones

679

es potencialmente enorme. Por tanto, el paralelismo en operaciones resulta natural en los sistemas de bases de datos. Las versiones paralelas de algunas operaciones relacionales frecuentes se estudiarán en los Apartados 21.5.1 a 21.5.3. 21.5.1 Ordenación paralela

Supóngase que se desea ordenar una relación que reside en n discos, D0 , D1 , . . . , Dn−1 . Si la relación se ha dividido por rangos basándose en los atributos por los que se va a ordenar, entonces, como se indicó en el Apartado 21.2.2, se puede ordenar cada partición por separado y concatenar los resultados para obtener la relación completa ordenada. Dado que las tuplas se hallan divididas en n discos, el tiempo necesario para leer la relación completa se reduce gracias al acceso en paralelo. Si la relación se ha dividido siguiendo algún otro método, se puede ordenar de una de estas dos maneras: 1. Se puede dividir en rangos de acuerdo con los atributos de ordenación y luego ordenar cada partición por separado. 2. Se puede utilizar una versión paralela del algoritmo externo de ordenación–mezcla. 21.5.1.1 Ordenación con división por rangos

La ordenación con división por rangos tiene dos etapas: primero, se divide por rangos la relación y, después, se ordena cada una de las particiones. Cuando la relación se ordena mediante división por rangos, no hace falta realizar la división en los mismos procesadores o discos en los que se almacena la relación. Supóngase que se escogen los procesadores P0 , P1 , . . . , Pm , donde m < n, para ordenar la relación. Esta operación se divide en dos fases: 1. Redistribuir las tuplas de la relación utilizando una estrategia de división por rangos, de manera que todas las tuplas que se hallen dentro del rango i-ésimo se envíen al procesador Pi , que almacena temporalmente la relación en el disco Di . Para implementar en paralelo la división por rangos cada procesador lee las tuplas de su disco y las envía al procesador de destino. Cada procesador P0 , P1 , . . . , Pm también recibe las tuplas correspondientes a su partición y las almacena localmente. Esta fase necesita una sobrecarga en la E/S de disco y en las comunicaciones. 2. Cada uno de los procesadores ordena localmente su partición de la relación sin interactuar con los demás procesadores. Cada procesador ejecuta la misma operación—por ejemplo, ordenar— sobre un conjunto de datos diferente (la ejecución de la misma acción en paralelo sobre conjuntos diferentes de datos se denomina paralelismo de datos). La operación final de mezcla es trivial, ya que la división por rangos de la primera etapa asegura que, para 1 ≤ i < j ≤ m, los valores de la clave del procesador Pi son todos menores que los de Pj . La división por rangos se debe llevar a cabo empleando un buen vector de división por rangos, de manera que cada partición tenga aproximadamente el mismo número de tuplas. Los procesadores virtuales también se pueden utilizar para reducir el sesgo. 21.5.1.2 Ordenación y mezcla externas paralelas

La ordenación y mezcla externas paralelas son una alternativa a la división por rangos. Supóngase que la relación ya se ha dividido entre los discos D0 , D1 , . . . , Dn−1 (no importa la manera en que se haya dividido la relación). La ordenación y mezcla externas paralelas funcionan de la siguiente manera: 1. Cada procesador Pi ordena localmente los datos del disco Di . 2. El sistema mezcla las partes ordenadas por cada procesador para obtener el resultado ordenado final.

www.detodoprogramacion.com


680

Capítulo 21

Bases de datos paralelas

La mezcla de las partes ordenadas del paso 2 puede paralelizarse mediante esta secuencia de acciones: 1. El sistema divide en rangos las particiones ordenadas en cada procesador Pi (utilizando el mismo vector de división) entre los procesadores P0 , P1 , . . . , Pm−1 . Envía las tuplas de acuerdo con el orden establecido, por lo que cada procesador recibe las tuplas en corrientes ordenadas. 2. Cada procesador Pi realiza una mezcla de las corrientes según las recibe para obtener una sola parte ordenada. 3. Las partes ordenadas de los procesadores P0 , P1 , . . . , Pm−1 se concatenan para obtener el resultado final. Como ya se ha descrito, esta secuencia de acciones da lugar a una variedad interesante del sesgo de ejecución, ya que, al principio cada procesador envía todos los bloques de la división 0 a P0 , después cada procesador envía todos los bloques de la partición 1 a P1 , etc. Así, mientras que el envío se produce en paralelo, la recepción de las tuplas es secuencial: primero sólo P0 recibe tuplas, luego sólo lo hace P1 , y así, sucesivamente. Para evitar este problema, cada procesador envía repetidamente un bloque de datos a cada partición. En otras palabras, cada procesador envía el primer bloque de cada partición, luego envía el segundo bloque de cada partición, etc. En consecuencia, todos los procesadores reciben los datos en paralelo. Algunas máquinas, como las de la serie DBC de Teradata, utilizan hardware especializado en realizar mezclas. La red de interconexión Y-net de las máquinas DBC de Teradata puede mezclar los resultados de varios procesadores para ofrecer un solo resultado ordenado. 21.5.2 Reunión paralela

La operación reunión exige que el sistema compare pares de tuplas para ver si satisfacen la condición de reunión; si la cumplen, añade el par al resultado de la reunión. Los algoritmos de reunión paralela intentan repartir entre varios procesadores los pares que hay que comparar. Cada procesador procesa luego localmente parte de la reunión. Después, el sistema reúne los resultados de cada procesador para producir el resultado final. 21.5.2.1 Reunión por división

Para ciertos tipos de reuniones, como las equirreuniones y las reuniones naturales, es posible dividir las dos relaciones de entrada entre los procesadores y procesar localmente la reunión en cada uno de ellos. Supóngase que se utilizan n procesadores y que las relaciones que hay que reunir son r y s. La reunión por división funciona de esta forma: el sistema divide las relaciones en n particiones, denominadas r0 , r1 , . . . , rn−1 y s0 , s1 , . . . , sn−1 . Envía las particiones ri y si al procesador Pi , donde la reunión se procesa localmente. La técnica anterior sólo funciona correctamente si la reunión es una equirreunión (por ejemplo, r 1r.A=s.B s) y se dividen r y s utilizando la misma función de división para sus atributos de reunión. La idea de la división es exactamente la misma que subyace a la fase de división de la reunión por asociación. Sin embargo, en la reunión por división hay dos maneras diferentes de dividir r y s: • División por rangos de los atributos de reunión. • División por asociación de los atributos de reunión. En ambos casos se debe utilizar la misma función de división para las dos relaciones. Para la división por rangos, el mismo vector de división. En el caso de la división por asociación, la misma función de asociación. La Figura 21.2 muestra la división utilizada en una reunión por división paralela. Una vez divididas las relaciones, se puede utilizar localmente cualquier técnica de reunión en cada procesador Pi para calcular la reunión de ri y si . Por ejemplo, se puede emplear la reunión por asociación, por mezcla o con bucles anidados. Por tanto, se puede utilizar la división para paralelizar cualquier técnica de reunión.

www.detodoprogramacion.com


Paralelismo en operaciones

21.5

. . . .

r0

P0

s0

r1

P1

s1

r2

P2

s2

r3

P3

s3

. . .

. . .

. . .

681

. . . .

s

r Figura 21.2

Reunión por división paralela.

Si alguna de las relaciones r y s, o las dos, ya están divididas basándose en los atributos de reunión (mediante división por asociación o por rangos) el trabajo necesario para la división se reduce mucho. Si las relaciones no están divididas, o lo están de acuerdo con atributos distintos de los de la reunión, hay que volver a dividir las tuplas. Cada procesador Pi lee las tuplas del disco Di, procesa para cada tupla t la partición j a la que pertenece i y la envía al procesador Pj . El procesador Pj almacena las tuplas en el disco Dj . Se puede optimizar el algoritmo de reunión utilizado localmente en cada procesador para reducir E/S guardando en la memoria intermedia algunas de las tuplas, en lugar de escribirlas en el disco. Estas optimizaciones se describen en el Apartado 21.5.2.3. El sesgo representa un problema especial cuando se utiliza la división por rangos, dado que un vector de división que divida una relación de la reunión en particiones de igual tamaño puede dividir las demás relaciones en particiones de tamaño muy variable. El vector de división debe ser tal que |ri | + |si | (es decir, la suma de los tamaños de ri y si ) sea aproximadamente igual para todo i = 0, 1, . . . , n − 1. Con una buena función de asociación, la división por asociación probablemente tenga menos sesgo, excepto cuando haya muchas tuplas con los mismos valores de los atributos de reunión. 21.5.2.2 Reunión con fragmentos y réplicas

La división no es aplicable a todos los tipos de reuniones. Por ejemplo, si la condición de reunión es una desigualdad, como r 1r.a<s.b s, es posible que todas las tuplas de r se reúnan con alguna tupla de s (y viceversa). Por tanto, puede que no haya un medio sencillo de dividir r y s de modo que las tuplas de la partición ri sólo se reúnan con tuplas de la partición si . Esas reuniones pueden paralelizarse utilizando una técnica denominada fragmentos y réplicas. En primer lugar se considerará un caso especial de fragmentos y réplicas—la reunión con fragmentos y réplicas asimétricos —que funciona de la manera siguiente: 1. El sistema divide una de las relaciones (por ejemplo, r). Se puede utilizar en r cualquier técnica de división, incluida la división por turno rotatorio. 2. El sistema replica la otra relación, s, en todos los procesadores. 3. El procesador Pi procesa localmente la reunión de r i con toda s, utilizando cualquier técnica de reunión. El esquema asimétrico de fragmentos y réplicas se muestra en la Figura 21.3a. Si r ya está almacenada por particiones no es necesario dividirla más en la primera fase. Todo lo que hace falta es replicar s en todos los procesadores.

www.detodoprogramacion.com


682

CapĂ­tulo 21

Bases de datos paralelas

El caso general de reuniĂłn con fragmentos y rĂŠplicas se muestra en la Figura 21.3b; funciona de la manera siguiente. El sistema divide la relaciĂłn r en n particiones, r0 , r1 , . . . , rn−1 y s en otras m, s0 , s1 , . . . , sm−1 . Al igual que antes, se puede utilizar cualquier tĂŠcnica de divisiĂłn para r y para s. No es necesario que los valores de m y de n sean iguales, pero deben escogerse de modo que haya al menos m ∗ n procesadores. El esquema asimĂŠtrico de fragmentos y rĂŠplicas sĂłlo es un caso especial de fragmentos y rĂŠplicas, en el que m = 1. El esquema de fragmentos y rĂŠplicas reduce el tamaĂąo de las relaciones en cada procesador en comparaciĂłn con el caso asimĂŠtrico. Sean los procesadores P0,0 , P0,1 , . . . , P0,m−1 , P1,0 , . . . , Pn−1,m−1 . El procesador Pi,j procesa la reuniĂłn de ri con sj . Cada procesador debe obtener las tuplas de las particiones sobre las que trabaja. Para ello, el sistema replica ri en los procesadores Pi,0 , Pi,1 , . . . , Pi,m−1 (que forman una fila en la Figura 21.3b) y si en los procesadores P0,i , P1,i , . . . , Pn−1,i (que forman una columna en la Figura 21.3b). Se puede utilizar la tĂŠcnica de reuniĂłn que se prefiera en cada procesador Pi,j . El esquema de fragmentos y rĂŠplicas funciona con cualquier condiciĂłn de reuniĂłn, ya que cada tupla de r puede compararse con cada una de las de s. Por tanto, puede utilizarse cuando no pueda emplearse la divisiĂłn. El esquema de fragmentos y rĂŠplicas suele tener un mayor coste que la divisiĂłn cuando ambas relaciones son aproximadamente del mismo tamaĂąo, ya que hay que replicar, como mĂ­nimo, una de las relaciones. Sin embargo, si una de las relaciones (por ejemplo, s) es pequeĂąa, puede resultar mĂĄs barato replicar s en todos los procesadores que volver a dividir r y s basĂĄndose en los atributos de reuniĂłn. En tal caso, el esquema asimĂŠtrico de fragmentos y rĂŠplicas es preferible, aunque pueda utilizarse la divisiĂłn. 21.5.2.3 ReuniĂłn por asociaciĂłn dividida en paralelo

La reuniĂłn por asociaciĂłn dividida del Apartado 13.5.5 puede hacerse en paralelo. SupĂłngase que se tienen n procesadores, P0 , P1 , . . . , Pn−1 y dos relaciones, r y s, que se encuentran divididas entre varios discos. RecuĂŠrdese del Apartado 12.6 que se debe escoger la relaciĂłn de menor tamaĂąo como relaciĂłn

Figura 21.3

Esquemas de fragmentos y rĂŠplicas.

www.detodoprogramacion.com


21.5

Paralelismo en operaciones

683

de construcción. Si el tamaño de s es menor que el de r, el algoritmo de reunión por asociación paralela procede de la manera siguiente: 1. Se escoge una función de asociación (por ejemplo, h1 ) que tome el valor del atributo de reunión de cada tupla de r y de s y asigne esa tupla a uno de los n procesadores. Sean r i las tuplas de la relación r asignadas al procesador Pi ; análogamente, sean si las tuplas de la relación s asignadas al procesador Pi . Cada procesador Pi lee las tuplas de s que están en el disco Di y envía cada tupla al procesador apropiado basándose en la función de asociación h1 . 2. A medida que el procesador de destino Pi recibe las tuplas de si , las vuelve a dividir de acuerdo con otra función de asociación, h2 , que utiliza para procesar localmente la reunión por asociación. La división en esta etapa es exactamente la misma que en la fase de división del algoritmo secuencial de reunión por asociación. Cada procesador Pi ejecuta esta fase independientemente de los demás procesadores. 3. Una vez que se han distribuido las tuplas de s, el sistema redistribuye la relación de mayor tamaño, r, entre los n procesadores de acuerdo con la función de asociación h1 del mismo modo que anteriormente. A medida que recibe cada tupla, el procesador de destino la divide según la función h2 , igual que la relación de exploración se divide en el algoritmo secuencial de reunión por asociación. 4. Cada procesador Pi ejecuta las fases de construcción y exploración del algoritmo de reunión por asociación en las particiones locales ri y si para generar una división del resultado final de la reunión por asociación. La reunión por asociación realizada en cada procesador es independiente de las realizadas en los demás, y recibir las tuplas de ri y de si es parecido a leerlas del disco. Por tanto, también se puede aplicar cualquiera de las optimizaciones de la reunión por asociación descritas en el Capítulo 13 al caso paralelo. En concreto, se puede utilizar el algoritmo híbrido de reunión por asociación para almacenar en caché algunas de las tuplas entrantes en la memoria, y evitar así el coste de escribirlas y volver a leerlas. 21.5.2.4 Reuniones con bucles anidados en paralelo

Para ilustrar el empleo de la paralelización basada en fragmentos y réplicas se considera el caso en que la relación s sea mucho menor que r. Supóngase que la relación r se almacena por división; el atributo de acuerdo con el cual se divide es irrelevante. Supóngase también que hay un índice basado en un atributo de reunión de la relación r en cada una de las particiones de la relación r. Se utiliza el esquema asimétrico de fragmentos y réplicas mientras se replica la relación s y se emplea la división ya existente de la relación r. Cada procesador Pj en que se almacena una partición de la relación s lee las tuplas de la relación s almacenadas en Dj y las replica en el resto de procesadores Pi . Al final de esta fase, la relación s está replicada en todos los puntos de almacenamiento de las tuplas de la relación r. A continuación cada procesador Pi realiza una reunión indexada con bucles anidados de la relación s con la partición i-ésima de la relación r. Se puede solapar la reunión indexada con bucles anidados con la distribución de las tuplas de la relación s para reducir el coste de escribir en el disco las tuplas de la relación s y volver a leerlas. Sin embargo, la réplica de la relación s debe sincronizarse con la reunión para que haya espacio suficiente en las memorias intermedias de la memoria principal de cada procesador Pi para albergar las tuplas de la relación s que se hayan recibido, pero que todavía no se hayan utilizado en la reunión. 21.5.3 Otras operaciones relacionales

También se puede realizar en paralelo la evaluación de otras operaciones relacionales: • Selección. Sea la selección σθ (r). Considérese en primer lugar el caso en el que θ es de la forma ai = v, donde ai es un atributo y v es un valor. Si la relación r se divide de acuerdo con ai , la

www.detodoprogramacion.com


684

Capítulo 21

Bases de datos paralelas

selección se lleva a cabo en un solo procesador. Si θ es de la forma l ≤ ai ≤ u (es decir, que θ es una selección de rango) y la relación se ha dividido por rangos según ai , entonces la selección se lleva a cabo en cada procesador cuya partición se solape con el rango de valores especificado. En el resto de los casos, la selección se lleva a cabo en todos los procesadores en paralelo. • Eliminación de duplicados. Los duplicados se pueden eliminar por ordenación; para ellos puede utilizarse cualquiera de las técnicas de ordenación en paralelo, optimizada para eliminar los duplicados durante la ordenación en cuanto aparezcan. También se puede paralelizar la eliminación de duplicados dividiendo las tuplas (por rangos o por asociación) y eliminado los duplicados localmente en cada procesador. • Proyección. Se puede llevar a cabo la proyección sin eliminación de duplicados a medida que se leen en paralelo las tuplas del disco. Si se van a eliminar los duplicados, se puede utilizar cualquiera de las técnicas que se acaban de describir. • Agregación. Considérese una operación de agregación. Se puede paralelizar dividiendo la relación de acuerdo con los atributos de agrupación y procesando localmente los valores de agregación en cada procesador. Se puede dividir por rangos o por asociación. Si la relación ya está dividida según los atributos de agrupación, se puede omitir la primera fase. Se puede reducir el coste de transferir las tuplas durante la división calculando parcialmente los valores de agregación antes de la división, al menos para las funciones de agregación utilizadas habitualmente. Considérese una operación de agregación sobre la relación r, que utiliza la función de agregación sum en el atributo B y la agrupación basada en el atributo A. El sistema puede llevar a cabo la operación en cada procesador Pi sobre las tuplas de r almacenadas en el disco Di . Este cálculo da lugar en cada procesador a tuplas con sumas parciales; hay una tupla en Pi para cada valor del atributo A presente en las tuplas de r almacenadas en Di . El sistema divide el resultado de la agregación local de acuerdo con el atributo de agrupación A y vuelve a llevar a cabo la agregación (sobre las tuplas con sumas parciales) en cada procesador Pi para obtener el resultado final. A consecuencia de esta optimización no es necesario enviar tantas tuplas a los demás procesadores durante la división. Esta idea puede extenderse fácilmente a las funciones de agregación min y max. Las extensiones para las funciones de agregación count y avg se proponen al lector en el Ejercicio 21.10. La paralelización de otras operaciones se trata en varios ejercicios. 21.5.4 Coste de la evaluación paralela de las operaciones

El paralelismo se obtiene dividiendo la E/S entre varios discos y el trabajo de la CPU entre varios procesadores. Si se logra un reparto así sin sobrecarga y no hay sesgo en el reparto del trabajo, las operaciones en paralelo que utilicen n procesadores tardarán 1/n lo que tardarían en un solo procesador. Ya se sabe cómo estimar el coste de operaciones como la reunión o la selección. El coste en tiempo del procesamiento paralelo sería entonces 1/n el del procesamiento secuencial de esa operación. También hay que tener en cuenta los costes siguientes: • Los costes iniciales de comenzar la operación en varios procesadores. • El sesgo en la distribución del trabajo entre los procesadores, con algunos procesadores con mayor número de tuplas que otros. • La competencia por los recursos—como la memoria, los discos y la red de comunicaciones— que dan lugar a retrasos. • El coste de construir el resultado final mediante la transmisión de los resultados parciales desde cada procesador. El tiempo empleado por una operación en paralelo puede estimarse como Tpart + Tasm + m´ax(T0 , T1 , . . . , Tn−1 )

www.detodoprogramacion.com


21.6

Paralelismo entre operaciones

685

donde Tpart es el tiempo necesario para dividir las relaciones, Tasm es el tiempo empleado en construir los resultados y Ti el tiempo utilizado por la operación en el procesador Pi . Suponiendo que las tuplas se distribuyen sin sesgo, el número de tuplas enviadas a cada procesador puede estimarse como 1/n del número total de tuplas. Ignorando la competencia, el coste Ti de las operaciones en cada procesador Pi , puede estimarse mediante las técnicas descritas en el Capítulo 13. La estimación precedente es optimista, dado que el sesgo es habitual. Aunque dividir una sola consulta en varias fases paralelas reduce el tamaño de la fase promedio, es el tiempo de procesamiento del paso más lento el que determina el tiempo empleado en procesar la consulta en su conjunto. Una evaluación en paralelo dividida, por ejemplo, no puede ser más rápida que la más lenta de sus ejecuciones en paralelo. Por tanto, cualquier sesgo en la distribución del trabajo entre los procesadores afecta mucho al rendimiento. El problema del sesgo de la división está íntimamente relacionado con el del desbordamiento de las divisiones en las reuniones secuenciales por asociación (Capítulo 13). Se puede utilizar la resolución del desbordamiento y las técnicas de evitación desarrolladas para las reuniones por asociación para tratar el sesgo cuando se utilice la división por asociación. Se puede utilizar la división equilibrada por rangos y la división con procesadores virtuales para minimizar el sesgo debido a la división por rangos, como en el Apartado 21.2.3.

21.6 Paralelismo entre operaciones

Existen dos formas de paralelismo entre operaciones: el paralelismo de encauzamiento y el paralelismo independiente. 21.6.1 Paralelismo de encauzamiento

Como se estudió en el Capítulo 13, el encauzamiento supone una importante fuente de economía de cálculo para el procesamiento de las consultas de bases de datos. Hay que recordar que, en el encauzamiento, las tuplas resultado de una operación, A, las consume una segunda operación, B, incluso antes de que la primera operación haya producido todo el conjunto de tuplas de su resultado. La ventaja principal de la ejecución encauzada de las evaluaciones secuenciales es que se puede ejecutar una secuencia de operaciones de ese tipo sin escribir en el disco ninguno de los resultados intermedios. Los sistemas paralelos utilizan el encauzamiento principalmente por la misma razón que los sistemas secuenciales. Sin embargo, el encauzamiento también es una fuente de paralelismo, del mismo modo que el encauzamiento de instrucciones se utiliza como fuente de paralelismo en el diseño de hardware. Es posible ejecutar simultáneamente A y B en procesadores diferentes de modo que B consuma las tuplas en paralelo con su producción por A. Esta forma de paralelismo se denomina paralelismo de encauzamiento. Considérese una reunión de cuatro relaciones: r1 1 r2 1 r3 1 r4 Se puede configurar un cauce que permita que las tres reuniones se calculen en paralelo. Supóngase que se asigna al procesador P1 el cálculo detemp1 ← r1 1 r2 y al procesador P2 el cálculo de r3 1 temp1 . A medida que P1 procesa las tuplas de r1 1 r2 , las pone a disposición del procesador P2 . Por tanto, P2 tiene a su disposición algunas de las tuplas de r1 1 r2 antes de que P1 haya finalizado su cálculo. P2 puede utilizar esas tuplas que están disponibles para comenzar el cálculo de temp1 1 r3 , incluso antes de que P1 haya calculado completamente r1 1 r2 . Análogamente, a medida que P2 procesa las tuplas de (r1 1 r2 ) 1 r3 , las pone a disposición de P3 , que calcula su reunión con r4 . El paralelismo encauzado resulta útil con un número pequeño de procesadores, pero no puede extenderse bien. En primer lugar, las cadenas del cauce no suelen lograr la longitud suficiente para proporcionar un alto grado de paralelismo. En segundo lugar, no es posible encauzar los operadores relacionales que no producen resultados hasta que han accedido a todos los datos, como la operación diferencia de conjuntos. En tercer lugar, sólo se obtiene una aceleración marginal en el caso frecuente de que el coste de ejecución de un operador sea mucho mayor que el de los demás.

www.detodoprogramacion.com


686

Capítulo 21

Bases de datos paralelas

Por consiguiente, cuando el grado de paralelismo es elevado, el encauzamiento es una fuente de paralelismo menos importante que la división. El verdadero motivo del empleo del encauzamiento es que las ejecuciones encauzadas pueden evitar escribir en el disco los resultados intermedios. 21.6.2 Paralelismo independiente

Las operaciones en las expresiones de las consultas que son independientes entre sí pueden ejecutarse en paralelo. Esta forma de paralelismo se denomina paralelismo independiente. Considérese la reunión r1 1 r2 1 r3 1 r4 . Evidentemente, se puede procesar temp1 ← r1 1 r2 en paralelo con temp2 ← r3 1 r4 . Cuando se completen esos dos cálculos se calculará temp1 1 temp2 Para obtener más paralelismo se pueden encauzar las tuplas de temp1 y temp2 al cálculo de temp1 1 temp2 , que se ejecuta mediante una reunión encauzada (Apartado 13.7.2.2). Como ocurre con el paralelismo encauzado, el paralelismo independiente no proporciona un alto grado de paralelismo y resulta menos útil en sistemas con un elevado nivel de paralelismo, aunque es útil con un grado menor de paralelismo. 21.6.3 Optimización de consultas

Los optimizadores de consultas son responsables de gran parte del éxito de la tecnología relacional. Recuérdese que los optimizadores de consultas toman una consulta y hallan el plan de ejecución más económico de entre todos los que proporcionan la misma respuesta. Los optimizadores de consultas para la evaluación en paralelo de las consultas son más complicados que los correspondientes a la evaluación secuencial de consultas. En primer lugar, los modelos de costes son más complicados, ya que hay que tener en cuenta los costes de división y aspectos como el sesgo y la competencia por los recursos. Más importante aún es la manera de paralelizar las consultas. Supóngase que, de algún modo, se ha escogido una expresión (de entre las equivalentes a la consulta) para utilizarla para evaluar la consulta. La expresión puede representarse mediante un árbol de operadores, como en el Apartado 13.1. Para evaluar un árbol de operadores en un sistema paralelo hay que tomar las decisiones siguientes: • El modo de paralelizar cada operación y el número de procesadores que se emplearán para ello. • Las operaciones que se encauzarán entre los diferentes procesadores, las operaciones que se ejecutarán independientemente en paralelo y las que lo harán secuencialmente, una tras otra. Estas decisiones constituyen la tarea de planificación del árbol de ejecución. Determinar los recursos de cada clase—como procesadores, discos y memoria—que se deben asignar a cada operación del árbol es otro aspecto del problema de la optimización. Por ejemplo, puede que parezca conveniente utilizar la máxima cantidad disponible de paralelismo, pero es buena idea no ejecutar ciertas operaciones en paralelo. Las operaciones cuyos requisitos de cálculo sean significativamente menores que la sobrecarga de comunicaciones deben agruparse con una de sus vecinas. En caso contrario, la ventaja del paralelismo se anula debido a la sobrecarga en las comunicaciones. Un problema es que los cauces largos no se prestan a un buen empleo de los recursos. A menos que las operaciones tengan grano grueso, puede que la operación final del encauzamiento espere mucho tiempo para obtener sus datos, mientras retiene recursos preciosos, como la memoria. Por tanto, deben evitarse los cauces largos. El número de planes de evaluación en paralelo entre los que se puede escoger es mucho mayor que el de los secuenciales. Optimizar las consultas en paralelo teniendo en cuenta todas las alternativas es, por tanto, mucho más costoso que optimizar las consultas secuenciales. Por tanto, se suelen adoptar enfoques heurísticos para reducir el número de planes de ejecución en paralelo que se deben tomar en consideración. A continuación se describen dos heurísticas muy conocidas. La primera heurística es considerar únicamente los planes de evaluación que paralelizan todas las operaciones de todos los procesadores y que no utilizan encauzamiento. Este enfoque se utiliza en las máquinas de la serie DBC de Teradata. Buscar el mejor plan de ejecución de este tipo es parecido a

www.detodoprogramacion.com


21.7

Diseño de sistemas paralelos

687

realizar la optimización de consultas en sistemas secuenciales. Las principales diferencias radican en la manera de llevar a cabo la división y en la fórmula de estimación de costes utilizada. La segunda heurística es escoger el plan de evaluación secuencial más eficiente y luego paralelizar sus operaciones. El sistema paralelo de bases de datos Volcano ha popularizado el modelo de paralelización denominado intercambio de operadores. Este modelo utiliza implementaciones ya existentes de las operaciones, que actúan sobre copias locales de los datos, acopladas con una operación de intercambio que traslada los datos entre los diferentes procesadores. Se pueden introducir los operadores de intercambio en el plan de evaluación para transformarlo en un plan de evaluación en paralelo. Otra dimensión más de la optimización es el diseño de la organización del almacenamiento físico para acelerar las consultas. La organización física óptima es diferente para las diferentes consultas. El administrador de la base de datos debe escoger la organización física que considere adecuada para la combinación esperada de consultas a la base de datos. Por tanto, el área de la optimización de consultas en paralelo es compleja y sigue siendo un campo de investigación activa.

21.7 Diseño de sistemas paralelos

Hasta ahora, este capítulo se ha concentrado en la paralelización del almacenamiento de los datos y del procesamiento de las consultas. Dado que los sistemas paralelos de bases de datos de gran escala se utilizan principalmente para almacenar grandes volúmenes de datos y para procesar consultas de ayuda a las decisiones basadas en esos datos, estos aspectos son los más importantes de los sistemas paralelos de bases de datos. La carga de los datos en paralelo desde fuentes externas es un requisito importante si se van a tratar grandes volúmenes de datos entrantes. Los grandes sistemas paralelos de bases de datos deben abordar también los siguientes aspectos de disponibilidad: • El poder de recuperación frente a fallos de algunos procesadores o discos. • La reorganización interactiva de los datos y los cambios interactivos de los esquemas. Estos temas se tratan a continuación. Con un gran número de procesadores y de discos la probabilidad de que, al menos, un procesador o un disco funcionen mal es significativamente mayor que en sistemas con un único procesador y un solo disco. Un sistema paralelo mal diseñado dejará de funcionar si cualquier componente (procesador o disco) falla. Suponiendo que la probabilidad de fallo de cada procesador o disco sea pequeña, la probabilidad de fallo del sistema aumenta linealmente con el número de procesadores y de discos. Si un solo procesador o disco falla una vez cada cinco años, un sistema con cien procesadores tendrá un fallo cada dieciocho días. Por tanto, los sistemas paralelos de bases de datos de gran escala, como las máquinas Himalaya de Compaq, las de Teradata y las XPS de Informix (ahora una división de IBM) se diseñan para operar aunque falle un procesador o un disco. Los datos se replican en, al menos, dos procesadores. Si falla un procesador, se puede seguir accediendo desde los demás procesadores a los datos que almacenaba. El sistema hace un seguimiento de los procesadores averiados y distribuye el trabajo entre los que funcionan. Las peticiones de datos que estaban almacenados en el emplazamiento estropeado se desvían automáticamente a los emplazamientos de respaldo, que almacenan una réplica. Si todos los datos del procesador A se replican en un solo procesador B, B tendrá que procesar todas las peticiones formuladas a A, así como las propias, y eso hará que B se transforme en un cuello de botella. Por tanto, las réplicas de los datos de cada procesador se dividen entre varios procesadores. Cuando se manejan grandes volúmenes de datos (del orden de terabytes), las operaciones sencillas, como la creación de índices, y los cambios en los esquemas, como añadir una columna a una relación, pueden tardar mucho tiempo—quizás horas o, incluso, días. Por tanto, no resulta aceptable que los sistemas de bases de datos no estén disponibles mientras se llevan a cabo esas operaciones. Muchos sistemas paralelos de bases de datos, como los sistemas Himalaya de Compaq, permiten que tales operaciones se lleven a cabo interactivamente, es decir, mientras el sistema ejecuta otras transacciones.

www.detodoprogramacion.com


688

Capítulo 21

Bases de datos paralelas

Considérese, por ejemplo, la generación interactiva de índices. Los sistemas que tienen esta característica permiten que se realicen inserciones, borrados y actualizaciones en una relación aunque se esté generando un índice de la misma. La operación de generación de índices, por tanto, no puede bloquear toda la relación en modo compartido, como habría hecho en caso contrario. Por el contrario, el proceso hace un seguimiento de las actualizaciones que tienen lugar mientras está activo e incorpora los cambios en el índice que se está generando.

21.8 Resumen

• Las bases de datos en paralelo han logrado una aceptación comercial significativa en los últimos veinte años. • En el paralelismo de E/S las relaciones se dividen entre los discos disponibles para poder recuperarlas más rápidamente. Tres técnicas de división utilizadas frecuentemente son la división por turno rotatorio, la división por asociación y la división por rangos. • El sesgo es un problema importante, especialmente con grados elevados de paralelismo. Los vectores de división equilibrados, que utilizan histogramas, y la división con procesadores virtuales son algunas técnicas usadas para reducir el sesgo. • En el paralelismo entre consultas se ejecutan concurrentemente diferentes consultas para aumentar la productividad. • El paralelismo en las consultas intenta reducir el coste de ejecución de las consultas. Existen dos tipos de paralelismo en las consultas: el paralelismo en operaciones y el paralelismo entre operaciones. • El paralelismo en operaciones se utiliza para ejecutar operaciones relacionales, como las ordenaciones y las reuniones, en paralelo. El paralelismo en operaciones es algo natural en las operaciones relacionales, ya que están orientadas a conjuntos. • Existen dos enfoques básicos en la paralelización de las operaciones binarias como las reuniones. ¤ En el paralelismo de divisiones las relaciones se dividen en varias partes y las tuplas de ri sólo se reúnen con las tuplas de si . El paralelismo de divisiones sólo se puede usar para las reuniones naturales y para las equirreuniones. ¤ En el esquema de fragmentos y réplicas las dos relaciones se dividen y cada división se duplica. En el esquema asimétrico de fragmentos y réplicas una de las relaciones se replica mientras la otra se divide. A diferencia del paralelismo de divisiones, el esquema de fragmentos y réplicas, tanto simétrico como asimétrico, puede utilizarse con cualquier condición de reunión. Ambas técnicas de paralelismo pueden utilizarse en combinación con cualquiera de las técnicas de reunión. • En el paralelismo independiente, las diferentes operaciones que son independientes entre sí se ejecutan en paralelo. • En el paralelismo encauzado, los procesadores envían los resultados de una operación a otra a medida que los van calculando, sin esperar a que concluya toda la operación. • La optimización de consultas en las bases de datos paralelas es significativamente más compleja que su equivalente en las bases de datos secuenciales.

www.detodoprogramacion.com


Ejercicios prácticos

689

Términos de repaso

• • • •

• • • • •

Consultas de ayuda a la toma de decisiones. Paralelismo de E/S. División horizontal. Técnicas de división: ¤ Turno rotatorio. ¤ División por asociación. ¤ División por rangos. Atributo de división. Vector de división. Consulta concreta. Consulta de rango. Sesgo: ¤ De ejecución. ¤ De los valores de los atributos. ¤ De la división.

• Manejo del sesgo. ¤ Vector de división por rangos equilibrado. ¤ Histograma. ¤ Procesadores virtuales. • Paralelismo entre consultas. • Coherencia de la caché. • Paralelismo en consultas. ¤ Paralelismo en operaciones. ¤ Paralelismo entre operaciones.

• Ordenación paralela. ¤ Ordenación con división por rangos ¤ Ordenación y mezcla externas paralelas. • Paralelismo de datos. • Reunión paralela: ¤ Por división. ¤ Con fragmentos y réplicas. ¤ Con esquema asimétrico de fragmentos y réplicas. ¤ Por asociación dividida en paralelo. ¤ Con bucles anidados en paralelo. • Selección paralela. • Eliminación de duplicados en paralelo. • Proyección paralela. • Agregación paralela. • Coste de la evaluación paralela. • Paralelismo entre operaciones: ¤ De encauzamiento. ¤ Independiente. • Optimización de consultas. • Planificación. • Modelo del operador de intercambio. • Diseño de sistemas paralelos. • Creación interactiva de índices.

Ejercicios prácticos

21.1 En una selección de rango sobre un atributo dividido por rangos es posible que sólo haga falta acceder a un disco. Descríbanse las ventajas y los inconvenientes de esta propiedad. 21.2 Indíquese la forma de paralelismo (entre consultas, entre operaciones o en operaciones) que puede resultar más importante para cada una de las tareas siguientes. a. Incrementar la productividad de un sistema con muchas consultas pequeñas. b. Incrementar la productividad de un sistema con unas pocas consultas de gran tamaño cuando el número de discos y de procesadores es elevado. 21.3 Con el paralelismo de encauzamiento suele resultar conveniente llevar a cabo varias operaciones de un cauce en un mismo procesador, aunque haya disponibles varios procesadores. a. Explíquese el motivo. b. ¿Serían válidos los argumentos anteriores si la máquina tuviera una arquitectura de memoria compartida? Explíquese el motivo. c. ¿Serían válidos los argumentos anteriores con paralelismo independiente? Es decir, ¿hay casos en que, incluso si las operaciones no se encauzan y hay muchos procesadores disponibles, sigue siendo conveniente llevar a cabo varias operaciones en el mismo procesador? 21.4 Considérese el procesamiento de reuniones utilizando el esquema simétrico de fragmentos y réplicas con división por rangos. ¿Cómo se puede optimizar la evaluación si la condición de reunión es de la forma | r.A − s.B |≤ k, donde k es una constante pequeña? Aquí, | x | denota el valor absoluto de x. Las reuniones con una condición de reunión así se denominan reuniones de banda.

www.detodoprogramacion.com


690

Capítulo 21

Bases de datos paralelas

21.5 Recuérdese que los histogramas se utilizan para generar particiones de rangos con carga equilibrada. a. Supóngase que se tiene un histograma en el que los valores varían de 1 a 100 y están divididos en 10 rangos, 1 – 10, 11–20, . . . , 91–100, con las frecuencias 15, 5, 20, 10, 10, 5, 5, 20, 5 y 5, respectivamente. Propóngase una función de división por rangos con carga equilibrada para dividir los valores en cinco particiones. b. Escríbase un algoritmo para calcular una división por rangos con carga equilibrada con p particiones, dado un histograma de las distribuciones de frecuencias que contenga n rangos. 21.6 Algunos sistemas paralelos de bases de datos almacenan una copia adicional de cada elemento de los datos en discos conectados a un procesador diferente, para evitar la pérdida de los datos si falla alguno de los procesadores. a. ¿Por qué es conveniente dividir las copias de los elementos de los datos de cada procesador entre varios procesadores? b. ¿Cuáles son las ventajas y los inconvenientes de utilizar almacenamiento RAID en lugar de almacenar otra copia de cada elemento de datos? Ejercicios

21.7 Para cada una de las tres técnicas de división, es decir, por turno rotatorio, por asociación y por rangos, propóngase un ejemplo de consulta para la que esa técnica de división proporcione la respuesta más rápida. 21.8 Indíquense los factores que pueden dar lugar a sesgo cuando se divide una relación de acuerdo con uno de sus atributos utilizando: a. División por asociación b. División por rangos En cada caso, indíquese lo que se puede hacer para reducir el sesgo. 21.9 Propóngase un ejemplo de reunión, que no sea una equirreunión simple, para la que pueda utilizarse paralelismo de divisiones. ¿Qué atributos deberían utilizarse para la división? 21.10 Descríbase una buena manera de paralelizar lo siguiente. a. b. c. d. e. f.

La operación diferencia. La agregación utilizando la operación count. La agregación utilizando la operación count distinct. La agregación utilizando la operación avg. La reunión externa por la izquierda, si la condición de reunión sólo implica igualdad. La reunión externa por la izquierda, si la condición de reunión implica comparaciones distintas de la igualdad. g. La reunión externa completa, si la condición de reunión implica comparaciones distintas de la igualdad.

21.11 Descríbanse las ventajas y los inconvenientes del paralelismo de encauzamiento. 21.12 Supóngase que se desea tratar una carga de trabajo consistente en gran cantidad de transacciones de pequeño tamaño mediante paralelismo independiente. a. ¿Se necesita paralelismo en consultas en esta situación? En caso de no ser así, indicar el motivo y la forma de paralelismo que se considera adecuada. b. ¿Qué forma de sesgo sería relevante con esta carga de trabajo? c. Supóngase que la mayoría de las transacciones accediesen a un registro de cuenta, que incluye un atributo del tipo de cuenta, y a un registro asociado maestro_tipo_cuenta, que proporciona la información sobre el tipo de la cuenta. ¿Cómo se dividirían y/o duplicarían los datos para acelerar las transacciones? Se puede suponer que la relación maestro_tipo_cuenta se actualiza rara vez.

www.detodoprogramacion.com


Notas bibliográficas

691

Notas bibliográ cas

Los sistemas de bases de datos relacionales comenzaron a aparecer en el mercado en 1983; hoy en día, lo dominan. A finales de los 70 y comienzos de los 80, a medida que el modelo relacional lograba un fundamento razonablemente sólido, se fue reconociendo que los operadores relacionales se pueden paralelizar en gran medida y que tienen buenas propiedades de flujo de datos. Se lanzaron en rápida sucesión un sistema comercial, Teradata, y varios proyectos de investigación, como GRACE (Kitsuregawa et al. [1983], Fushimi et al. [1986]), GAMMA (DeWitt et al. [1986], DeWitt [1990]) y Bubba (Boral et al. [1990]). Los investigadores utilizaron estos sistemas paralelos de bases de datos para estudiar la viabilidad de la ejecución en paralelo de los operadores relacionales. Posteriormente, a finales de los 80 y en los 90, varias compañías más — como Tandem, Oracle, Sybase, Informix y Red-Brick (ahora parte de Informix, que a su vez es parte de IBM)—entraron en el mercado de las bases de datos paralelas. Los proyectos de investigación dentro del mundo académico incluyen XPRS (Stonebraker et al. [1989]) y Volcano (Graefe [1990]). El bloqueo en las bases de datos paralelas se estudia en Joshi [1991], Mohan y Narang [1991] y Mohan y Narang [1992]. Los protocolos de coherencia de la caché para los sistemas paralelos de bases de datos se estudian en Dias et al. [1989], Mohan y Narang [1991], Mohan y Narang [1992] y Rahm [1993]. Carey et al. [1991] estudian los aspectos de la caché en los sistemas cliente-servidor. El paralelismo y la recuperación en sistemas de bases de datos se estudian en Bayer et al. [1980]. Graefe [1993] presenta un excelente resumen del procesamiento de consultas, incluido el procesamiento de consultas en paralelo. Graefe [1990] y Graefe [1993] defendieron el modelo del operador de intercambio. La ordenación en paralelo se estudia en DeWitt et al. [1992]. Los algoritmos de reunión en paralelo se describen en Nakayama et al. [1984], Kitsuregawa et al. [1983], Richardson et al. [1987], Schneider y DeWitt [1989], Kitsuregawa y Ogawa [1990], Lin et al. [1994] y Wilschut et al. [1995], entre otros trabajos. Los algoritmos de la reunión en paralelo para arquitecturas de memoria compartida se describen en Tsukuda et al. [1992], Deshpande y Larson [1992], y Shatdal y Naughton [1993]. El tratamiento del sesgo en las reuniones en paralelo se describe en Walton et al. [1991], Wolf [1991] y DeWitt et al. [1992]. Las técnicas de optimización de consultas en paralelo se describen en H. Lu y Tan [1991], Hong y Stonebraker [1991], Ganguly et al. [1992], Lanzelotte et al. [1993] y Jhingran et al. [1997].

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

22

Bases de datos distribuidas

A diferencia de los sistemas paralelos, en los que los procesadores se hallan estrechamente acoplados y constituyen un solo sistema de bases de datos, los sistemas de bases de datos distribuidos están formados por sitios débilmente acoplados que no comparten ningún componente físico. Además, puede que los sistemas de bases de datos que se ejecutan en cada sitio sean sustancialmente independientes entre sí. La estructura básica de los sistemas distribuidos se estudió en el Capítulo 20. Cada sitio puede participar en la ejecución de transacciones que acceden a los datos de uno o de varios sitios diferentes. La diferencia principal entre los sistemas de bases de datos centralizados y los distribuidos es que, en los primeros, los datos residen en una única ubicación, mientras que en los segundos los datos se reparten entre varios lugares. Esta distribución de los datos provoca muchas dificultades en el procesamiento de las transacciones y de las consultas. En este capítulo se abordarán esas dificultades. Se comenzará por clasificar las bases de datos distribuidas en homogéneas y heterogéneas, en el Apartado 22.1. A continuación se abordará el problema del almacenamiento de los datos en las bases de datos distribuidas en el Apartado 22.2. El Apartado 22.3 esboza un modelo de procesamiento de las transacciones en las bases de datos distribuidas. En el Apartado 22.4 se describe la manera de implementar transacciones atómicas en bases de datos distribuidas mediante protocolos de compromiso especiales. El Apartado 22.5 describe el control de concurrencia en las bases de datos distribuidas. En el Apartado 22.6 se esboza el modo de proporcionar una elevada disponibilidad en bases de datos distribuidas aprovechando las réplicas, de manera que el sistema pueda continuar procesando las transacciones aunque se produzca una avería. El procesamiento de las consultas en las bases de datos distribuidas se aborda en el Apartado 22.7. En el Apartado 22.8 se esbozan aspectos del manejo de bases de datos heterogéneas. El Apartado 22.9 describe los sistemas de directorio, que pueden considerarse una forma especializada de las bases de datos distribuidas. 22.1 Bases de datos homogéneas y heterogéneas

En los sistemas de bases de datos distribuidas homogéneas todos los sitios emplean idéntico software de gestión de bases de datos, son conscientes de la existencia de los demás sitios y acuerdan cooperar en el procesamiento de las solicitudes de los usuarios. En estos sistemas, los sitios locales renuncian a una parte de su autonomía en cuanto a su derecho a modificar los esquemas o el software de gestión de bases de datos. Ese software también debe cooperar con los demás sitios en el intercambio de la información sobre las transacciones para hacer posible su procesamiento entre varios sitios. A diferencia de lo anterior, en las bases de datos distribuidas heterogéneas puede que los diferentes sitios utilicen esquemas y software de gestión de sistemas de bases de datos diferentes. Puede que algunos sitios no tengan información de la existencia del resto y que sólo proporcionen facilidades limitadas para la cooperación en el procesamiento de las transacciones. Las diferencias en los esquemas suelen 693

www.detodoprogramacion.com


694

Capítulo 22

Bases de datos distribuidas

constituir un problema importante para el procesamiento de las consultas, mientras que la divergencia del software supone un inconveniente para el procesamiento de transacciones que acceden a varios sitios. Este capítulo se centrará en las bases de datos distribuidas homogéneas. No obstante, en el Apartado 22.8 se estudiarán brevemente los aspectos del procesamiento de las consultas en los sistemas de bases de datos distribuidas heterogéneas. Los aspectos del procesamiento de las transacciones en esos sistemas se tratan más adelante, en el Apartado 25.7. 22.2 Almacenamiento distribuido de datos

Considérese una relación r que hay que almacenar en la base de datos. Existen dos enfoques del almacenamiento de esta relación en la base de datos distribuida: • Réplica. El sistema conserva varias réplicas (copias) idénticas de la relación y guarda cada réplica en un sitio diferente. La alternativa a las réplicas es almacenar sólo una copia de la relación r. • Fragmentación. El sistema divide la relación en varios fragmentos y guarda cada fragmento en un sitio diferente. La fragmentación y la réplica pueden combinarse: las relaciones pueden dividirse en varios fragmentos y puede haber varias réplicas de cada fragmento. En los subapartados siguientes se profundizará en cada una de estas técnicas. 22.2.1 Réplica de datos

Si la relación r se replica, se guarda una copia de esa relación en dos o más sitios. En el caso más extremo se tiene una réplica completa, en la que se guarda una copia en cada sitio del sistema. Las réplicas presentan varias ventajas e inconvenientes. • Disponibilidad. Si alguno de los sitios que contiene la relación r falla, esa relación puede hallarse en otro sitio distinto. Por tanto, el sistema puede seguir procesando las consultas que impliquen a r, pese al fallo del sitio. • Paralelismo incrementado. En el caso en el que la mayoría de los accesos a la relación r sólo resultasen en lecturas, diferentes sitios podrían procesar en paralelo las lecturas que impliquen a r. Cuantas más réplicas de r existan, mayor será la posibilidad de que los datos necesarios se encuentren en el sitio en que se ejecuta la transacción. Por tanto, la réplica de los datos minimiza su transmisión entre los diferentes sitios. • Sobrecarga incrementada durante la actualización. El sistema debe asegurar que todas las réplicas de la relación r sean consistentes; en caso contrario pueden producirse cálculos erróneos. Por tanto, siempre que se actualiza r, hay que propagar la actualización a todos los sitios que contienen réplicas. El resultado es una sobrecarga incrementada. Por ejemplo, en un sistema bancario, en el que la información de las cuentas se replica en varios sitios, es necesario asegurarse de que el saldo de cada cuenta concuerde en todos ellos. En general, la réplica mejora el rendimiento de las operaciones de lectura y aumenta la disponibilidad de los datos para las transacciones de lectura. Sin embargo, las transacciones de actualización suponen una mayor sobrecarga. El control de las actualizaciones concurrentes de los datos replicados realizadas por varias transacciones resulta más complejo que en los sistemas centralizados, los cuales se estudiaron en el Capítulo 16. Se puede simplificar la gestión de las réplicas de la relación r escogiendo una de ellas como copia principal de r. Por ejemplo, en un sistema bancario, las cuentas pueden asociarse con el sitio en que se abrieron. De manera parecida, en un sistema de reserva de billetes de avión, cada vuelo puede asociarse con el sitio en que se origina. El esquema de copias principales y otras opciones del control de concurrencia distribuida se examinarán en el Apartado 22.5.

www.detodoprogramacion.com


22.2

Almacenamiento distribuido de datos

695

22.2.2 Fragmentación de los datos

Si la relación r se fragmenta, r se divide en varios fragmentos r2 , . . . , rn . Estos fragmentos contienen suficiente información como para permitir la reconstrucción de la relación original r. Existen dos esquemas diferentes de fragmentación de las relaciones: la fragmentación horizontal y la vertical. La fragmentación horizontal divide la relación asignando cada tupla de r a uno o más fragmentos. La fragmentación vertical divide la relación descomponiendo el esquema r de la relación r. Estos enfoques se ilustrarán fragmentando la relación cuenta, con el esquema Esquema_cuenta = (número_cuenta, nombre_sucursal, saldo) En la fragmentación horizontal la relación r se divide en varios subconjuntos, r1 , r2 , . . . , rn . Cada tupla de la relación r debe pertenecer, como mínimo, a uno de los fragmentos, de modo que se pueda reconstruir la relación original, si fuera necesario. A modo de ejemplo, la relación cuenta puede dividirse en varios fragmentos, cada uno de los cuales consiste en tuplas de cuentas pertenecientes a una sucursal concreta. Si el sistema bancario sólo tiene dos sucursales (Guadarrama y Cercedilla), habrá dos fragmentos diferentes: cuenta1 = σnombre_sucursal = “Guadarrama” (cuenta) cuenta2 = σnombre_sucursal = “Cercedilla” (cuenta) La fragmentación horizontal suele emplearse para conservar las tuplas en los sitios en que más se utilizan, para minimizar la transferencia de datos. En general, los fragmentos horizontales pueden definirse como una selección de la relación global r. Es decir, se utiliza un predicado Pi para construir el fragmento ri : ri = σPi (r) La relación r se reconstruye tomando la unión de todos los fragmentos; es decir, r = r1 ∪ r2 ∪ · · · ∪ rn En el ejemplo, los fragmentos son disjuntos. Al cambiar los predicados de selección empleados para crear los fragmentos se puede hacer que una tupla de r dada aparezca en más de uno de los fragmentos ri . En su forma más sencilla la fragmentación vertical es igual que la descomposición (véase el Capítulo 7). La fragmentación vertical de r(R) implica la definición de varios subconjuntos de atributos R1 , R2 , . . . , Rn del esquema R de modo que R = R1 ∪ R2 ∪ · · · ∪ Rn Cada fragmento ri de r se define mediante ri = ΠRi (r) La fragmentación debe hacerse de modo que se pueda reconstruir la relación r a partir de los fragmentos tomando la reunión natural r = r1 1 r2 1 r3 1 · · · 1 rn Una manera de asegurar que la relación r pueda reconstruirse es incluir los atributos de la clave principal de R en cada uno de los fragmentos Ri . De manera más general, se puede utilizar cualquier superclave. Suele resultar conveniente añadir un atributo especial, denominado id_tupla, al esquema R. El valor id_tupla de cada tupla es un valor único que distingue a esa tupla de todas las demás. El atributo id_tupla, por tanto, sirve como clave candidata para el esquema aumentado y se incluye en cada uno de los fragmentos Ri . La dirección física o lógica de la tupla puede utilizarse como id_tupla, ya que cada tupla tiene una dirección única. Para ilustrar la fragmentación vertical considérese una base de datos universitaria con una relación info_empleado que almacena, para cada empleado, id_empleado, nombre, puesto y salario. Por motivos de preservación de la intimidad puede que esta relación se fragmente en una denominada empleado_infoprivada, que contenga id_empleado y salario, y en otra llamada empleado_infopública, que contenga los

www.detodoprogramacion.com


696

Capítulo 22

Bases de datos distribuidas

atributos id_empleado, nombre y puesto. Puede que las dos relaciones se almacenen en sitios diferentes, nuevamente, por motivos de seguridad. Se pueden aplicar los dos tipos de fragmentación a un mismo esquema; por ejemplo, los fragmentos obtenidos de la fragmentación horizontal de una relación pueden dividirse nuevamente de manera vertical. Los fragmentos también pueden replicarse. En general, los fragmentos pueden replicarse, las réplicas de los fragmentos pueden fragmentarse más, y así sucesivamente. 22.2.3 Transparencia

No se debe exigir a los usuarios de los sistemas distribuidos de bases de datos que conozcan la ubicación física de los datos ni el modo en que se puede acceder a ellos en cada sitio local concreto. Esta característica, denominada transparencia de los datos, puede adoptar varias formas: • Transparencia de la fragmentación. No se exige a los usuarios que conozcan el modo en que se ha fragmentado la relación. • Transparencia de la réplica. Los usuarios ven cada objeto de datos como lógicamente único. Puede que el sistema distribuido replique los objetos para incrementar el rendimiento del sistema o la disponibilidad de los datos. Los usuarios no deben preocuparse por los objetos que se hayan replicado ni por la ubicación de esas réplicas. • Transparencia de la ubicación. No se exige a los usuarios que conozcan la ubicación física de los datos. El sistema distribuido de bases de datos debe poder hallar los datos siempre que la transacción del usuario facilite el identificador de esos datos. Los elementos de datos (como las relaciones, los fragmentos y las réplicas) deben tener nombres únicos. Esta propiedad es fácil de asegurar en las bases de datos centralizadas. En las bases de datos distribuidas, sin embargo, hay que tener cuidado para asegurarse de que dos sitios no utilicen el mismo nombre para elementos de datos diferentes. Una solución a este problema es exigir que todos los nombres se registren en un servidor de nombres central. El servidor de nombres ayuda a garantizar que el mismo nombre no se utilice para elementos de datos diferentes. También se puede utilizar el servidor de nombres para localizar los elementos de datos, dado su nombre. Este enfoque, sin embargo, presenta dos inconvenientes principales. En primer lugar, puede que el servidor de nombres se transforme en un cuello de botella para el rendimiento cuando los elementos de datos se buscan por el nombre, lo que da lugar a un bajo rendimiento. En segundo lugar, si el servidor de nombres queda fuera de servicio, puede que ningún otro sitio del sistema distribuido logre seguir en funcionamiento. Un enfoque alternativo más utilizado exige que cada sitio anteponga su propio identificador de sitio a cualquier nombre que genere. Este enfoque garantiza que dos sitios diferentes no generen nunca el mismo nombre (dado que cada sitio tiene un identificador único). Además, no se necesita ningún control centralizado. Esta solución, no obstante, no logra conseguir transparencia en la ubicación, dado que a los nombres se les adjuntan los identificadores de los sitios. Así, se puede hacer referencia a la relación cuenta como cuenta.sitio17, o cuenta@sitio17, en lugar de meramente cuenta. Muchos sistemas de bases de datos utilizan la dirección de Internet de los sitios para identificarlos. Para superar este problema, el sistema de bases de datos puede crear un conjunto de nombres alternativos, o alias, para los elementos de datos. En consecuencia, los usuarios se pueden referir a los elementos de datos mediante nombres sencillos que el sistema traduce a los nombres completos. La relación entre los alias y los nombres reales puede almacenarse en cada sitio. Cuando se emplean alias, el usuario puede ignorar la ubicación física de los elementos de datos. Además, no se ve afectado si el administrador de la base de datos decide trasladar un elemento de datos de un sitio a otro. Los usuarios no deberían tener necesidad de hacer referencia a una réplica concreta de un elemento de datos. En vez de eso, el sistema debe determinar la réplica a la que hay que hacer referencia en las solicitudes leer, y actualizar todas las réplicas en las solicitudes escribir. Se puede asegurar que lo hace si se mantiene una tabla de catálogo, que el sistema utilizará para determinar todas las réplicas del elemento de datos.

www.detodoprogramacion.com


22.3

Transacciones distribuidas

CT1

CTn

coordinador de transacciones

GT1

GTn

gestor de transacciones

computadora 1

computadora n Figura 22.1

697

Arquitectura del sistema.

22.3 Transacciones distribuidas

El acceso a los diferentes elementos de datos en los sistemas distribuidos suele realizarse mediante transacciones, que deben preservar las propiedades ACID (Apartado 15.1). Se deben considerar dos tipos de transacciones. Las transacciones locales son las que acceden a los datos y los actualizan en una única base de datos local; las transacciones globales son las que acceden a los datos y los actualizan en varias bases de datos locales. Las propiedades ACID de las transacciones locales se pueden asegurar como se describe en los Capítulos 15, 16 y 17. No obstante, para las transacciones globales, esta tarea resulta mucho más complicada, dado que puede que participen en la ejecución varios sitios. El fallo de alguno de estos sitios, o el de alguno de los enlaces de comunicaciones que los conectan entre sí, puede dar lugar a cálculos erróneos. En este apartado se estudia la estructura del sistema de una base de datos distribuida y sus posibles modos de fallo. Con base en el modelo presentado en este apartado, en el Apartado 22.4 se estudian los protocolos para garantizar el compromiso atómico de las transacciones globales, y en el Apartado 22.5 se estudian los protocolos para el control de concurrencia en las bases de datos distribuidas. En el Apartado 22.6 se estudia el modo en que pueden seguir funcionando las bases de datos distribuidas incluso en presencia de varios tipos de fallo. 22.3.1 Estructura del sistema

Cada sitio tiene su propio gestor local de transacciones, cuya función es garantizar las propiedades ACID de las transacciones que se ejecuten allí. Los diferentes gestores de transacciones colaboran para ejecutar las transacciones globales. Para comprender el modo en que se pueden implementar estos gestores, considérese un modelo abstracto de sistema de transacciones, en el que cada sitio contenga dos subsistemas: • El gestor de transacciones gestiona la ejecución de las transacciones (o subtransacciones) que acceden a los datos almacenados en un sitio local. Téngase en cuenta que cada una de esas transacciones puede ser local (es decir, una transacción que se ejecuta sólo en ese sitio) o formar parte de una transacción global (es decir, una transacción que se ejecuta en varios sitios). • El coordinador de transacciones coordina la ejecución de las diferentes transacciones (tanto locales como globales) iniciadas en ese sitio. La arquitectura global del sistema aparece en la Figura 22.1. La estructura de los gestores de transacciones es parecida en muchos aspectos a la de los sistemas centralizados. Cada gestor de transacciones es responsable de: • Mantener un registro histórico con fines de recuperación.

www.detodoprogramacion.com


698

Capítulo 22

Bases de datos distribuidas

• Participar en un esquema adecuado de control de concurrencia para coordinar la ejecución concurrente de las transacciones que se ejecuten en ese sitio. Como se verá, es necesario modificar tanto el esquema de recuperación como el de concurrencia para adaptarlos a la distribución de las transacciones. El subsistema del coordinador de transacciones no es necesario en los entornos centralizados, ya que las transacciones sólo acceden a los datos de un sitio. Los coordinadores de transacciones, como su propio nombre implica, son responsables de la coordinación de la ejecución de todas las transacciones iniciadas en ese sitio. En cada una de esas transacciones el coordinador es responsable de: • Iniciar la ejecución de la transacción. • Dividir la transacción en varias subtransacciones y distribuir esas subtransacciones a los sitios correspondientes para su ejecución. • Coordinar la terminación de la transacción, lo que puede hacer que la transacción se comprometa o se aborte en todos los sitios. 22.3.2 Modos de fallo del sistema

Los sistemas distribuidos pueden sufrir los mismos tipos de fallos que los sistemas centralizados (por ejemplo, errores de software, errores de hardware y fallos de discos). No obstante, en los entornos distribuidos también hay que tratar con otros tipos de fallos. Los tipos básicos de fallos son: • Fallos de sitios. • Pérdidas de mensajes. • Fallos de enlaces de comunicaciones. • Divisiones de la red. En los sistemas distribuidos siempre es posible la pérdida o el deterioro de los mensajes. El sistema utiliza protocolos de control de las transmisiones, como TCP/IP, para tratar esos errores. Se puede encontrar información sobre esos protocolos en los libros de texto estándar sobre redes (véanse las notas bibliográficas). No obstante, si dos sitios A y B no se hallan conectados de manera directa, los mensajes de uno a otro deben encaminarse mediante una serie de enlaces de comunicaciones. Si falla uno de los enlaces, hay que volver a encaminar los mensajes que debería haber transmitido. En algunos casos se puede hallar otra ruta por la red, de modo que los mensajes puedan alcanzar su destino. En otros casos, el fallo puede hacer que no haya ninguna conexión entre los dos sitios. Un sistema está dividido si se ha partido en dos (o más) subsistemas, denominados particiones, que carecen de conexión entre ellas. Obsérvese que, con esta definición, cada subsistema puede consistir en un solo nodo.

22.4 Protocolos de compromiso

Si hay que asegurar la atomicidad, todos los sitios en los que se ejecute una transacción T deben coincidir en el resultado final de esa ejecución. T debe comprometerse o abortarse en todos los sitios. Para garantizar esta propiedad, el coordinador de transacciones de T debe ejecutar un protocolo de compromiso. Entre los protocolos de compromiso más sencillos y más utilizados está el protocolo de compromiso de dos fases (C2F), que se describe en el Apartado 22.4.1. Una alternativa es el protocolo de compromiso de tres fases (C3F), que evita ciertos inconvenientes del protocolo C2F pero añade complejidad y sobrecarga. El Apartado 22.4.2 describe brevemente el protocolo C3F.

www.detodoprogramacion.com


22.4

Protocolos de compromiso

699

22.4.1 Compromiso de dos fases

En primer lugar se describe el modo en que opera el protocolo de compromiso de dos fases (C2F) durante el funcionamiento normal, luego se describe cómo maneja los fallos y, finalmente, la manera en que ejecuta la recuperación y el control de concurrencia. Considérese una transacción T iniciada en el sitio Si , en el que el coordinador de transacciones es Ci . 22.4.1.1 El protocolo de compromiso

Cuando se acaba de ejecutar T (es decir, cuando todos los sitios en los que se ha ejecutado informan a Ci de que T se ha completado) Ci inicia el protocolo C2F. • Fase 1. Ci añade el registro <preparar T> al registro histórico y obliga a que se guarde en un lugar de almacenamiento estable. Luego envía el mensaje preparar T a todos los sitios en los que se ha ejecutado T. Al recibir este mensaje, el gestor de transacciones de cada sitio determina si desea comprometer su parte de T. Si la respuesta es negativa, añade el registro <no T> al registro histórico y responde enviando a Ci el mensaje abortar T. Si la respuesta es positiva, añade el registro <T preparada> al registro histórico y hace que se guarde (con todos los registros del registro histórico correspondientes a T) en un almacenamiento estable. El gestor de transacciones contesta entonces a Ci con el mensaje T preparada. • Fase 2. Cuando Ci recibe de todos los sitios las respuestas al mensaje preparar T, o cuando ha transcurrido un intervalo de tiempo especificado con anterioridad desde que se envió el mensaje preparar T, Ci puede determinar si la transacción T puede comprometerse o abortarse. La transacción T se puede comprometer si Ci ha recibido el mensaje T preparada de todos los sitios participantes. En caso contrario, hay que abortar la transacción T. En función del resultado, se añade el registro <T comprometida> o <T abortada> al registro histórico, que se guarda en un almacenamiento estable. En ese momento, el destino de la transacción ya se ha sellado. A partir de este momento el coordinador envía a todos los sitios participantes el mensaje comprometer T o abortar T. Cuando un sitio recibe ese mensaje, lo guarda en el registro histórico. Los sitios en los que se ejecutó T pueden abortarla de manera incondicional en cualquier momento antes de enviar al coordinador el mensaje T preparada. Una vez enviado el mensaje, se dice que la transacción está en estado preparado en el sitio. El mensaje T preparada constituye, en realidad, un compromiso del sitio de acatar la orden del coordinador de comprometer o de abortar T. Para establecer ese compromiso, primero hay que guardar en un almacenamiento estable la información necesaria. En caso contrario, si el sitio fallara tras enviar el mensaje T preparada, puede que no fuera capaz de cumplir su promesa. Además, los bloqueos adquiridos por la transacción deben mantenerse hasta que ésta se complete. Dado que se exige la unanimidad para comprometer cada transacción, el destino de T queda sellado en cuanto un sitio responda abortar T. Dado que el sitio coordinador Si es uno de los sitios en los que se ha ejecutado T, el coordinador puede decidir unilateralmente abortarla. El veredicto final sobre T se determina en el momento en que el coordinador lo escribe (comprometer o abortar) en el registro histórico y obliga a que ese veredicto se guarde en un almacenamiento estable. En algunas implementaciones del protocolo C2F, los sitios envían al coordinador el mensaje acuse-de-recibo T al final de la segunda fase del protocolo. Cuando el coordinador recibe el mensaje acuse-de-recibo T de todos los sitios, añade el registro <T completada> al registro histórico. 22.4.1.2 Tratamiento de los fallos

El protocolo C2F responde de modo diferente a los distintos tipos de fallos: • Fallo de un sitio participante. Si el coordinador Ci detecta que un sitio ha fallado, emprende las acciones siguientes: si el sitio falla antes de responder a Ci con el mensaje T preparada, el coordinador da por supuesto que ha respondido con el mensaje abortar T. Si el sitio falla después

www.detodoprogramacion.com


700

Capítulo 22

Bases de datos distribuidas

de que el coordinador haya recibido del sitio el mensaje T preparada, el coordinador ejecuta el resto del protocolo de compromiso de manera normal, ignorando el fallo del sitio. Cuando el sitio participante Sk se recupera de un fallo, debe examinar su registro histórico para determinar el destino de las transacciones que se hallaban en trance de ejecución cuando se produjo ese fallo. Supóngase que T es una de esas transacciones. Se toman en consideración cada uno de los casos posibles: ¤ El registro histórico contiene el registro <T comprometida>. En ese caso, el sitio ejecuta rehacer(T). ¤ El registro histórico contiene el registro <T abortada>. En ese caso, el sitio ejecuta deshacer(T). ¤ El registro histórico contiene el registro <T preparada>. En ese caso, el sitio debe consultar con Ci para determinar el destino de T. Si Ci está activo, notifica a Sk si T se comprometió o se abortó. En el primer caso, se ejecuta rehacer(T); en el segundo, se ejecuta deshacer(T). Si Ci no está activo, Sk debe intentar averiguar el destino de T consultando a otros sitios. Lo hace enviando el mensaje consulta-estado T a todos los sitios del sistema. Al recibir ese mensaje, cada sitio debe consultar su registro histórico para determinar si allí se ejecutó T y, en caso afirmativo, si se comprometió o se abortó. Luego notifica a Sk el resultado. Si ningún sitio tiene la información correspondiente (es decir, si T se comprometió o se abortó), Sk no puede abortar ni comprometer T. La decisión sobre T se pospone hasta que Sk pueda obtener la información necesaria. Por tanto, Sk debe volver a enviar de manera periódica el mensaje consulta-estado a los demás sitios. Seguirá haciéndolo hasta que se recupere algún sitio que contenga la información necesaria. Téngase en cuenta que el sitio en el que reside Ci siempre tiene la información necesaria. ¤ El registro histórico no contiene ningún registro de control (abortada, comprometida, preparada) relativo a T. Por tanto, se sabe que Sk falló antes de responder al mensaje preparar T enviado por Ci . Dado que el fallo de Sk evitó el envío de la respuesta, de acuerdo con el algoritmo, Ci debe abortar T. Por tanto, Sk debe ejecutar deshacer(T). • Fallo del coordinador. Si el coordinador falla durante la ejecución del protocolo de compromiso para la transacción T, los sitios participantes deben decidir el destino de T. Se verá que, en ciertos casos, los sitios participantes no pueden decidir si comprometer o abortar T y, por tanto, deben esperar a la recuperación del coordinador que ha fallado. ¤ Si algún sitio activo contiene el registro <T comprometida> en su registro histórico, se debe comprometer T. ¤ Si algún sitio activo contiene el registro <T abortada> en su registro histórico, se debe abortar T. ¤ Si algún sitio activo no contiene el registro <T preparada> en su registro histórico, el coordinador Ci que ha fallado no puede haber decidido comprometer T, ya que los sitios que no contienen el registro <T preparada> en su registro histórico no pueden haber enviado el mensaje T preparada a Ci . No obstante, puede que el coordinador haya decidido abortar T, pero no comprometer T. En vez de esperar a que se recupere Ci , resulta preferible abortar T. ¤ Si no se da ninguno de los casos anteriores, todos los sitios activos deben tener el registro <T preparada> en sus registros históricos, pero ningún otro registro de control (como <T abortada> o <T comprometida>). Dado que el coordinador ha fallado, resulta imposible determinar si se ha tomado alguna decisión y, en caso de haberse tomado, averiguar la que era, hasta que se recupere el coordinador. Por tanto, los sitios activos deben esperar a que se recupere Ci . Dado que el destino de T sigue siendo dudoso, puede que siga consumiendo recursos del sistema. Por ejemplo, si se emplean bloqueos, puede que T conserve en los sitios activos los bloqueos sobre los datos. Esa situación no es deseable, ya que pueden pasar horas o días antes de que Ci vuelva a estar activo. Durante ese tiempo puede que otras transacciones se vean obligadas a esperar a T. En consecuencia, puede que los elementos de datos no estén disponibles, no sólo en el sitio que ha fallado (Ci ), sino también en los sitios activos. Esta situación se denomina problema del bloqueo, ya que T queda bloqueada a la espera de la recuperación del sitio Ci .

www.detodoprogramacion.com


22.4

Protocolos de compromiso

701

• División de la red. Cuando una red queda dividida, caben dos posibilidades: 1. El coordinador y todos los sitios participantes siguen en una de las particiones. En este caso, el fallo no tiene ningún efecto sobre el protocolo de compromiso. 2. El coordinador y los sitios participantes se distribuyen entre varias particiones. Desde el punto de vista de los sitios de cada partición, parece que los sitios de las demás particiones hubieran fallado. Los sitios que no se hallan en la partición que contiene al coordinador, sencillamente, ejecutan el protocolo para tratar el fallo del coordinador. El coordinador y los sitios que se hallan en su misma partición siguen el protocolo de compromiso habitual, dando por supuesto que los sitios de las demás particiones han fallado. Por tanto, el mayor inconveniente del protocolo C2F es que el fallo del coordinador puede dar lugar a un bloqueo, en el que puede que haya que retrasar la decisión sobre comprometer o abortar T hasta que se recupere Ci . 22.4.1.3 Recuperación y control de concurrencia

Cuando se reinicia el sitio que ha fallado, se puede llevar a cabo la recuperación, por ejemplo, utilizando el algoritmo de recuperación descrito en el Apartado 17.8. Para tratar con los protocolos de compromiso distribuidos (como C2F y C3F), el procedimiento de recuperación debe tratar de manera especial las transacciones dudosas; las transacciones dudosas son transacciones para las que se encuentra en el registro histórico un registro <T preparada>, pero no uno <T comprometida> ni uno <T abortada>. El sitio que se recupera debe determinar la situación comprometer-abortar de esas transacciones, como se describe en el Apartado 22.4.1.2. Sin embargo, si se realiza la recuperación como se acaba de describir, el procesamiento normal de las transacciones en el sitio no puede comenzar hasta que se hayan comprometido o deshecho todas las transacciones dudosas. Averiguar la situación de las transacciones dudosas puede ser un proceso lento, ya que puede que haya que contactar con varios sitios. Además, si ha fallado el coordinador, y ningún otro sitio tiene información sobre la situación comprometer-abortar de una transacción incompleta, se podría bloquear la recuperación si se utiliza C2F. En consecuencia, puede que el sitio que lleva a cabo la recuperación de reinicio quede inutilizable durante un largo periodo de tiempo. Para evitar este problema los algoritmos de recuperación suelen ofrecer soporte para anotar en el registro histórico la información relativa a los bloqueos (se da por supuesto que se utilizan los bloqueos para el control de concurrencia). En lugar de escribir en el registro histórico el registro <T preparada>, el algoritmo escribe <T preparada, L>, donde L es una lista de todos los bloqueos de escritura que tiene la transacción T cuando se escribe el registro del registro histórico. En el momento de la recuperación, tras llevar a cabo las acciones de recuperación locales, se renuevan para cada transacción dudosa T todos los bloqueos de escritura anotados en el registro <T preparada, L> del registro histórico (tras leerlos en el registro histórico). Después de que se haya completado la renovación de los bloqueos para todas las transacciones dudosas, puede comenzar en el sitio el procesamiento de las transacciones, incluso antes de que se determine el estado comprometer—abortar de las transacciones dudosas. Las transacciones dudosas se comprometen o se deshacen de manera concurrente con la ejecución de las nuevas transacciones. Así, la recuperación del sitio es más rápida y no se bloquea nunca. Obsérvese que las transacciones nuevas que tengan conflictos de bloqueo con algún bloqueo de escritura establecido por cualquier transacción dudosa no pueden progresar hasta que se hayan comprometido o deshecho las transacciones dudosas con las que estén en conflicto. 22.4.2 Compromiso de tres fases

El protocolo de compromiso de tres fases (C3F) es una extensión del protocolo de compromiso de dos fases que evita el problema del bloqueo con determinadas suposiciones. En concreto, se supone que no se produce ninguna fragmentación de la red y que no fallan más de k sitios, donde k es un número predeterminado. Con estas suposiciones, el protocolo evita el bloqueo introduciendo una tercera fase adicional en que varios sitios se implican en la decisión sobre el compromiso. En lugar de anotar directamente la decisión sobre el compromiso en su almacenamiento persistente, el coordinador se asegura

www.detodoprogramacion.com


702

Capítulo 22

Bases de datos distribuidas

antes de que, al menos, otros k sitios sepan que pretende comprometer la transacción. Si el coordinador falla, los sitios restantes seleccionan primero un nuevo coordinador. Este nuevo coordinador comprueba el estado del protocolo a partir de los demás sitios; si el coordinador había decidido comprometer, al menos uno de los otros k sitios a los que informó estará funcionando y garantizará que se respete la decisión de comprometer. El nuevo coordinador vuelve a iniciar la tercera fase del protocolo si algún sitio sabía que el antiguo coordinador pretendía comprometer la transacción. En caso contrario, el nuevo coordinador la aborta. Aunque el protocolo C3F tiene la propiedad deseable de no bloquearse a menos que fallen k sitios, tiene el inconveniente de que una división de la red puede parecer lo mismo que el fallo de más de k sitios, lo que produce un bloqueo. El protocolo también tiene que implementarse con mucho cuidado para garantizar que la división de la red (o el fallo de más de k sitios) no provoque inconsistencias, en las que una transacción se comprometa en una de las particiones y se aborte en otra. Debido a la sobrecarga que supone, el protocolo C3F no se utiliza mucho. Véanse las notas bibliográficas para hallar referencias que den más detalles del protocolo C3F.

22.4.3 Modelos alternativos del procesamiento de transacciones

Para muchas aplicaciones el problema del bloqueo del compromiso de dos fases no resulta aceptable. El problema en este caso es la idea de una sola transacción que trabaja en varios sitios. En este apartado se describe el modo de utilizar la mensajería persistente para evitar el problema del compromiso distribuido y luego se describe brevemente el problema, más importante, de los flujos de trabajo; los flujos de trabajo se consideran con mayor detalle en el Apartado 25.2. Para comprender la mensajería persistente, considérese el modo en que se podrían transferir fondos entre dos bancos diferentes, cada uno con su propia computadora. Un enfoque es hacer que la transacción abarque los dos sitios y utilizar el compromiso de dos fases para asegurar la atomicidad. Sin embargo, puede que la transacción tenga que actualizar todo el saldo del banco, y el bloqueo podría tener afectar gravemente a las demás transacciones de cada banco, ya que casi todas las transacciones de los bancos actualizan el saldo total del banco. Por el contrario, considérese el modo en que se produce la transferencia de fondos mediante cheque conformado. El banco deduce en primer lugar el importe del cheque del saldo disponible e imprime un cheque. El cheque se transfiere físicamente al otro banco, donde se ingresa. Tras comprobar el cheque, el banco incrementa el saldo local en el importe del cheque. El cheque constituye un mensaje enviado entre los dos bancos. Para que los fondos no se pierdan ni se incrementen de manera incorrecta, el cheque no se debe perder, duplicar ni ingresar más de una vez. Cuando las computadoras de los bancos se hallan conectadas en red, los mensajes persistentes ofrecen el mismo servicio que los cheques (pero, por supuesto, mucho más rápido). Los mensajes persistentes son mensajes que tienen garantizada su entrega al destinatario exactamente una sola vez (ni más, ni menos), independientemente de los fallos, si la transacción que envía el mensaje se compromete, y tienen garantizado que no se entregan si la transacción se aborta. Se emplean técnicas de recuperación de las bases de datos para implementar la mensajería persistente por encima de los canales normales de la red, como se verá brevemente. Por el contrario, los mensajes normales se pueden perder o, incluso, se pueden entregar varias veces en determinadas circunstancias. El manejo de los errores resulta más complicado con la mensajería persistente que con el compromiso de dos fases. Por ejemplo, si la cuenta en la que hay que ingresar el cheque se ha cerrado, hay que devolver el cheque a la cuenta que lo originó y volver a cargar su importe en ella. Por tanto, ambos sitios deben disponer de código para el manejo de errores y con código para manejar los mensajes persistentes. Por el contrario, con el compromiso de dos fases, el error lo detectaría la propia transacción, que, por tanto, no deduciría nunca el importe del cheque de la primera cuenta. Los tipos de condiciones de excepción que pueden surgir dependen de la aplicación, por lo que no es posible que el sistema de bases de datos maneje las excepciones de manera automática. Los programas de aplicación que envían y reciben los mensajes persistentes deben incluir código para el manejo de las condiciones de excepción y para la devolución del sistema a un estado consistente. Por ejemplo, no resulta aceptable que se pierda el dinero que se iba a transferir porque la cuenta receptora se haya

www.detodoprogramacion.com


22.4

Protocolos de compromiso

703

cerrado; hay que devolver el dinero a la cuenta ordenante, y si ello no resulta posible por algún motivo, hay que advertir a los empleados del banco para que resuelvan manualmente el problema. Existen muchas aplicaciones en que la ventaja de la eliminación del bloqueo compensa ampliamente el esfuerzo adicional de implementar sistemas que utilicen mensajes persistentes. De hecho, pocas organizaciones aceptarían soportar el compromiso de dos fases en transacciones que se originen en su exterior, ya que los fallos pueden provocar el bloqueo del acceso a los datos locales. La mensajería persistente, por tanto, desempeña un papel importante en la ejecución de las transacciones que cruzan las fronteras de las organizaciones. Los flujos de trabajo proporcionan un modelo general de procesamiento de las transacciones que implican a varios sitios y, posiblemente, el procesamiento manual por los empleados de la organización de determinadas fases del proceso. Por ejemplo, cuando un banco recibe una solicitud de préstamo, debe dar muchos pasos, incluido el contacto con agencias externas de calificación de crédito, antes de aceptar o rechazar esa solicitud. Esos pasos, en su conjunto, forman un flujo de trabajo. Los flujos de trabajo se estudian con mayor detalle en el Apartado 25.2. También se observa que la mensajería consistente forma la base subyacente a los flujos de trabajo en los entornos distribuidos. Se considerará ahora la implementación de la mensajería persistente. Los siguientes protocolos pueden implementar la mensajería persistente por encima de estructuras de mensajería que no sean dignas de confianza, las cuales pueden perder mensajes o entregarlos varias veces: • Protocolo de sitio remitente. Cuando una transacción desea enviar un mensaje persistente, escribe el registro que contiene el mensaje en la relación especial mensajes_por_enviar, en lugar de enviar el mensaje directamente. El mensaje también recibe un identificador de mensaje único. Un proceso de entrega de mensajes controla la relación y, cuando detecta un mensaje nuevo, lo envía a su destino. Los mecanismos habituales de control de concurrencia de las bases de datos garantizan que el proceso del sistema sólo lea el mensaje una vez que la transacción que lo ha escrito se haya comprometido; si la transacción se aborta, el mecanismo habitual de recuperación borra el mensaje de la relación. El proceso de entrega de mensajes sólo elimina los mensajes de la relación una vez que ha recibido un acuse de recibo del sitio de destino. Si no lo recibe, pasado cierto tiempo vuelve a enviar el mensaje. Repite este proceso hasta que recibe un acuse de recibo. En caso de fallo permanente, el sistema decide, pasado algún tiempo, que el mensaje no puede entregarse. Entonces invoca al código proporcionado por la aplicación para el manejo de excepciones para que trate el fallo. La escritura del mensaje en una relación y su procesamiento tan sólo después de que se haya comprometido la transacción garantiza que el mensaje se entregue si y sólo si la transacción se compromete. Su envío repetido garantiza que se entregue aunque haya fallos (temporales) del sistema o de la red. • Protocolo de sitio receptor. Cuando un sitio recibe un mensaje persistente, ejecuta una transacción que añade el mensaje a la relación especial mensajes_recibidos, siempre que no se halle ya presente en la relación (el identificador único de mensajes permite detectar los duplicados). Una vez comprometida la transacción, o si el mensaje ya se hallaba en la relación, el sitio receptor devuelve un acuse de recibo al sitio remitente. Hay que tener en cuenta que no resulta seguro enviar el acuse de recibo antes de que la transacción se comprometa, ya que un fallo del sistema podría dar lugar a la pérdida del mensaje. Comprobar si el mensaje se ha recibido previamente resulta fundamental para evitar que se entregue varias veces. En muchos sistemas de mensajería los mensajes se pueden retrasar de manera arbitraria, aunque esos retrasos sean muy improbables. Por tanto, para asegurarse, los mensajes no se deben eliminar nunca de la relación mensajes_recibidos. Su eliminación puede hacer que no se detecte una entrega duplicada. Pero, como consecuencia, la relación mensajes_recibidos puede crecer de manera indefinida. Para resolver este problema se asigna a cada mensaje una marca temporal y, si la marca temporal del mensaje recibido es más antigua que la de algún punto arbitrario de corte, ese mensaje se descarta. Todos los mensajes registrados en la relación mensajes_recibidos que sean más antiguos que el punto de corte se pueden eliminar.

www.detodoprogramacion.com


704

Capítulo 22

Bases de datos distribuidas

22.5 Control de la concurrencia en las bases de datos distribuidas

En este apartado se muestra el modo en que se pueden modificar algunos de los esquemas de control de concurrencia que se estudian en el Capítulo 16 para utilizarlos en entornos distribuidos. Se da por supuesto que cada sitio participa en la ejecución de un protocolo de compromiso para garantizar la atomicidad global de las transacciones. Los protocolos que se describen en este apartado necesitan que se hagan actualizaciones de todas las réplicas de los elementos de datos. Si ha fallado algún sitio que contenga una réplica de un elemento de datos, no se pueden procesar las actualizaciones de ese elemento de datos. En el Apartado 22.6 se describen los protocolos que pueden continuar el procesamiento de las transacciones aunque haya fallado algún sitio o algún enlace, lo que proporciona una gran disponibilidad. 22.5.1 Protocolos de bloqueo

Los diferentes protocolos de bloqueo descritos en el Capítulo 16 se pueden utilizar en entornos distribuidos. La única modificación que hay que incorporar es el modo en que el gestor de bloqueos trata los datos replicados. Se presentan varios esquemas posibles que son aplicables a entornos en que los datos se pueden replicar en varios sitios. Al igual que en el Capítulo 16, se dará por supuesto la existencia de los modos de bloqueo compartido y exclusivo. 22.5.1.1 Enfoque de gestor único de bloqueos

En el enfoque de gestor único de bloqueos el sistema mantiene un único gestor de bloqueos que reside en un sitio único escogido (por ejemplo, Si ). Todas las solicitudes de bloqueo y de desbloqueo se realizan en el sitio Si . Cuando una transacción necesita bloquear un elemento de datos, envía una solicitud de bloqueo a Si . El gestor de bloqueos determina si se puede conceder el bloqueo de manera inmediata. En caso afirmativo, envía un mensaje al respecto al sitio en el que se inició la solicitud de bloqueo. En caso contrario, la solicitud se retrasa hasta que se puede conceder, en cuyo momento se envía un mensaje al sitio en el que se inició la solicitud de bloqueo. La transacción puede leer el elemento de datos de cualquiera de los sitios en los que residan sus réplicas. En el caso de las operaciones de escritura, deben implicarse todos los sitios en los que residan réplicas del elemento de datos. El esquema tiene las ventajas siguientes: • Implementación sencilla. Este esquema necesita dos mensajes para tratar las solicitudes de bloqueo y sólo uno para las de desbloqueo. • Tratamiento sencillo de los interbloqueos. Como todas las solicitudes de bloqueo y de desbloqueo se realizan en un solo sitio, se pueden aplicar directamente a este entorno los algoritmos de tratamiento de los interbloqueos estudiados en el Capítulo 16. Los inconvenientes del esquema son: • Cuello de botella. El sitio Si se transforma en un cuello de botella, ya que todas las solicitudes deben procesarse allí. • Vulnerabilidad. Si el sitio Si falla, se pierde el controlador de la concurrencia. O bien hay que detener el procesamiento, o bien hay que utilizar un esquema de recuperación para que un sitio de respaldo pueda asumir la administración de los bloqueos, como se describe en el Apartado 22.6.5. 22.5.1.2 Gestor distribuido de bloqueos

Se puede lograr un compromiso entre las ventajas y los inconvenientes ya mencionados mediante el enfoque del gestor distribuido de bloqueos, en el que la función de gestor de bloqueos se halla distribuida entre varios sitios. Cada sitio mantiene un gestor de bloqueos local, cuya función es administrar las solicitudes de bloqueo y de desbloqueo para los elementos de datos que se almacenan en ese sitio. Cuando una transac-

www.detodoprogramacion.com


22.5

Control de la concurrencia en las bases de datos distribuidas

705

ción desea bloquear el elemento de datos Q, que no está replicado y reside en el sitio Si , envía un mensaje al gestor de bloqueos del sitio Si para solicitarle un bloqueo (en un modo de bloqueo determinado). Si el elemento de datos Q está bloqueado en un modo incompatible, la solicitud se retrasa hasta que se pueda conceder. Una vez se haya determinado que la solicitud de bloqueo se puede conceder, el gestor de bloqueos devuelve un mensaje al sitio que ha iniciado la solicitud para indicar que ha concedido la solicitud de bloqueo. Existen varios modos alternativos de tratar con la réplica de los elementos de datos, que se estudian en los Apartados 22.5.1.3 a 22.5.1.6. El esquema del gestor distribuido de bloqueos presenta la ventaja de su sencilla implementación y reduce el grado en el que el coordinador constituye un cuello de botella. Tiene una sobrecarga razonablemente baja, ya que sólo necesita dos transferencias de mensajes para tratar las solicitudes de bloqueo y una transferencia de mensaje para las de desbloqueo. Sin embargo, el tratamiento de los interbloqueos resulta más complejo, dado que las solicitudes de bloqueo y de desbloqueo ya no se realizan en un solo sitio. Puede haber interbloqueos entre sitios aunque no los haya dentro de ninguno de los sitios. Los algoritmos de tratamiento de los interbloqueos estudiados en el Capítulo 16 deben modificarse, como se estudiará en el Apartado 22.5.4 para que detecten los interbloqueos globales. 22.5.1.3 Copia principal

Cuando un sistema utiliza la réplica de datos se puede escoger una de las réplicas como copia principal. Así, para cada elemento de datos Q, la copia principal de Q debe residir exactamente en un sitio, que se denomina sitio principal de Q. Cuando una transacción necesita bloquear el elemento de datos Q, solicita un bloqueo en el sitio principal de Q. Como ya se ha visto, la respuesta a la solicitud se retrasa hasta que pueda concederse. Por tanto, la copia principal permite que el control de concurrencia de los datos replicados se trate como el de los datos no replicados. Esta semejanza permite una implementación sencilla. No obstante, si falla el sitio principal de Q, ese elemento de datos queda inaccesible, aunque otros sitios que contengan réplicas suyas estén accesibles. 22.5.1.4 Protocolo de mayoría

El protocolo de mayoría funciona de la manera siguiente: si el elemento de datos Q se replica en n sitios diferentes, hay que enviar un mensaje de solicitud de bloqueo a más del cincuenta por ciento de esos sitios. Cada gestor de bloqueos determina si se puede conceder el bloqueo de manera inmediata (en lo que a él se refiere). Como ya se ha visto, la respuesta se retrasa hasta que la solicitud se pueda conceder. La transacción no se lleva a cabo en Q hasta que logre obtener un bloqueo sobre la mayoría de las réplicas de Q. Supóngase por ahora que las operaciones de escritura se llevan a cabo en todas las réplicas, lo que exige que todos los sitios que las contienen estén disponibles. No obstante, la principal ventaja del protocolo de mayoría es que puede extenderse para que trate los fallos de los sitios, como se verá en el Apartado 22.6.1. Este protocolo también trata los datos replicados de manera descentralizada, con lo que evita los inconvenientes del control centralizado. Sin embargo, presenta los siguientes inconvenientes: • Implementación. El protocolo de mayoría es más complicado de implementar que los esquemas anteriores. Necesita, como mínimo, 2(n/2 + 1) mensajes para manejar las solicitudes de bloqueo y, al menos, (n/2 + 1) mensajes para manejar las solicitudes de desbloqueo. • Tratamiento de los interbloqueos. Además del problema de los interbloqueos globales debidos al empleo del enfoque del gestor distribuido de bloqueos, puede que se produzcan interbloqueos aunque sólo se esté bloqueando un elemento de datos. A modo de ejemplo, considérese un sistema con cuatro sitios y réplica completa. Supóngase que las transacciones T1 y T2 desean bloquear el elemento de datos Q en modo exclusivo. Puede que la transacción T1 tenga éxito en el bloqueo de Q en los sitios S1 y S3 y la transacción T2 consiga bloquear Q en los sitios S2 y S4 . Cada una de ellas deberá esperar a adquirir el tercer bloqueo; por tanto, se ha producido un interbloqueo. Por

www.detodoprogramacion.com


706

Capítulo 22

Bases de datos distribuidas

fortuna, estos interbloqueos se pueden evitar con relativa facilidad exigiendo que todos los sitios soliciten el bloqueo de las réplicas de cada elemento de datos en el mismo orden predeterminado. 22.5.1.5 Protocolo sesgado

El protocolo sesgado es otro enfoque del manejo de las réplicas. La diferencia con el protocolo de mayoría es que se concede un tratamiento más favorable a las solicitudes de bloqueo compartido que a las solicitudes de bloqueo exclusivo. • Bloqueos compartidos. Cuando una transacción necesita bloquear el elemento de datos Q, simplemente solicita su bloqueo al gestor de bloqueos de un sitio que contenga una réplica de Q. • Bloqueos exclusivos. Cuando una transacción necesita bloquear el elemento de datos Q, solicita su bloqueo al gestor de bloqueos de todos los sitios que contienen una réplica de Q. Al igual que antes, la respuesta a la solicitud se retrasa hasta que pueda concederse. El esquema sesgado tiene la ventaja de imponer menos sobrecarga a las operaciones leer que el protocolo de mayoría. Este ahorro resulta especialmente significativo en el frecuente caso en que la frecuencia de las operaciones leer es mucho mayor que la de las operaciones escribir. No obstante, la sobrecarga adicional sobre las operaciones de escritura supone un inconveniente. Además, el protocolo sesgado comparte con el protocolo de mayoría el inconveniente de la complejidad en el manejo de los interbloqueos. 22.5.1.6 Protocolo de consenso de quórum

El protocolo de consenso de quórum es una generalización del protocolo de mayoría. El protocolo de consenso de quórum asigna a cada sitio un peso no negativo. Asigna a las operaciones de lectura y de escritura sobre el elemento x dos enteros, denominados quórum de lectura Ql y quórum de escritura Qe , que deben cumplir la siguiente condición, donde S es el peso total de todos los sitios en los que x reside: Ql + Qe > S y 2 ∗ Qe > S Para ejecutar una operación de lectura deben bloquearse suficientes réplicas como para que su peso total sea ≥ Ql . Para ejecutar una operación de escritura se deben bloquear suficientes réplicas como para que su peso total sea ≥ Qe . Una ventaja del enfoque de consenso de quórum es que puede permitir la reducción selectiva del coste de los bloqueos de lectura o de escritura mediante la adecuada definición de los quórum de lectura y de escritura. Por ejemplo, con un quórum de lectura pequeño, las operaciones de lectura necesitan obtener menos bloqueos, pero el quórum de escritura será mayor, por lo que las operaciones de escritura necesitarán obtener más bloqueos. Además, si se asignan pesos más elevados a algunos sitios (por ejemplo, a los que tengan menos posibilidad de fallar), hace falta acceder a menos sitios para adquirir los bloqueos. De hecho, si se definen los pesos y los quórum de manera adecuada, el protocolo de consenso de quórum puede simular tanto el protocolo de mayoría como el sesgado. Al igual que el protocolo de mayoría, el de consenso de quórum se puede extender para que trabaje incluso en caso de fallos de los sitios, como se verá en el Apartado 22.6.1. 22.5.2 Marcas temporales

La idea principal tras el esquema de marcas temporales del Apartado 16.2 es que se concede a cada transacción una marca temporal única que el sistema utiliza para decidir el orden de secuenciación. La primera tarea, por tanto, al generalizar el esquema centralizado a uno distribuido es desarrollar un esquema para la generación de marcas temporales únicas. Por tanto, los diferentes protocolos pueden operar directamente en el entorno no replicado. Existen dos métodos principales para la generación de marcas temporales únicas, uno centralizado y otro distribuido. En el esquema centralizado un solo sitio distribuye las marcas temporales. El sitio puede utilizar para ello un contador lógico o su propio reloj local.

www.detodoprogramacion.com


22.5

Control de la concurrencia en las bases de datos distribuidas

707

Figura 22.2

GeneraciĂłn de marcas temporales Ăşnicas.

En el esquema distribuido cada sitio genera una marca temporal local Ăşnica mediante un contador lĂłgico o su reloj local. La marca temporal global Ăşnica se obtiene concatenando la marca temporal local Ăşnica correspondiente con el identificador de ese sitio, que tambiĂŠn debe ser Ăşnico (Figura 22.2). El orden de concatenaciĂłn es importante. El identificador del sitio se utiliza en la posiciĂłn menos significativa para garantizar que las marcas temporales globales generadas en un sitio dado no sean siempre mayores que las generadas en otro. CompĂĄrese esta tĂŠcnica para la generaciĂłn de marcas temporales Ăşnicas con la presentada en el Apartado 22.2.3 para la generaciĂłn de nombres Ăşnicos. Puede que todavĂ­a surja algĂşn problema si un sitio genera marcas temporales locales a una velocidad mayor que los demĂĄs sitios. En ese caso el contador lĂłgico del sitio rĂĄpido serĂĄ mayor que el de los demĂĄs sitios. Por tanto, todas las marcas temporales generadas por el sitio rĂĄpido serĂĄn mayores que las generadas por los demĂĄs sitios. Lo que se necesita es un mecanismo que garantice que las marcas temporales locales se generen de manera homogĂŠnea en todo el sistema. En cada sitio Si se define un reloj lĂłgico (RLi ), que genera la marca temporal local Ăşnica. El reloj lĂłgico puede implementarse como un contador que se incremente despuĂŠs de generar cada nueva marca temporal local. Para garantizar que los diferentes relojes lĂłgicos estĂŠn sincronizados, se exige que el sitio Si adelante su reloj lĂłgico siempre que una transacciĂłn Ti con la marca temporal <x,y> visite ese sitio y x sea mayor que el valor actual de RLi . En ese caso, el sitio Si adelantarĂĄ su reloj lĂłgico hasta el valor x + 1. Si se utiliza el reloj del sistema para generar las marcas temporales, ĂŠstas se asignarĂĄn de manera homogĂŠnea, siempre que ningĂşn sitio tenga un reloj del sistema que adelante o atrase. Dado que es posible que los relojes no sean totalmente exactos, hay que utilizar una tĂŠcnica parecida a la de los relojes lĂłgicos para garantizar que ningĂşn reloj se adelante o se atrase mucho respecto de los demĂĄs. 22.5.3 RĂŠplica con grado de consistencia bajo

Muchas bases de datos comerciales actuales soportan las rÊplicas, que pueden adoptar varias formas. Con la rÊplica maestro – esclavo, la base de datos permite las actualizaciones en el sitio principal y las propaga de manera automåtica a las rÊplicas de los demås sitios. Las transacciones pueden leer las rÊplicas en los demås sitios, pero no se les permite actualizarlas. Una característica importante de esta rÊplica es que las transacciones no consiguen bloqueos en los sitios remotos. Para garantizar que las transacciones que se ejecutan en los sitios de rÊplica vean una vista consistente (aunque quizås desactualizada) de la base de datos la rÊplica debe reflejar una instantånea consistente para las transacciones de los datos del sitio principal, es decir, la rÊplica debe reflejar todas las actualizaciones de las transacciones hasta una transacción dada según el orden de secuenciación, y no deben reflejar ninguna actualización de transacciones posteriores según el orden de secuenciación. Se puede configurar la base de datos para que propague las actualizaciones de manera inmediata, una vez producidas en el sitio principal, o para que las propague sólo de manera periódica. La rÊplica maestro– esclavo resulta especialmente útil para distribuir información, por ejemplo, desde una oficina central a las sucursales de una organización. Otra aplicación de esta forma de rÊplica es la creación de copias de la base de datos para la ejecución de consultas de gran tamaùo, de modo que las consultas no interfieran con las transacciones. Las actualizaciones deben propagarse de manera periódica (cada noche, por ejemplo), de modo que la propagación no interfiera con el procesamiento de las consultas. El sistema de bases de datos Oracle posee la sentencia create snapshot (crear instantånea), que puede crear en un sitio remoto una copia instantånea de una relación, o de un conjunto de relaciones, consistente para las transacciones. TambiÊn soporta la actualización de las instantåneas, que puede hacerse

www.detodoprogramacion.com


708

Capítulo 22

Bases de datos distribuidas

volviendo a calcular cada instantánea o actualizándola de manera incremental. Oracle soporta la actualización automática, tanto continua como a intervalos periódicos. Con la réplica multimaestro (también denominada réplica de actualización distribuida) las actualizaciones se permiten en cualquier réplica de cada elemento de datos y se propagan de manera automática a todas las réplicas. Este modelo es el modelo básico utilizado para administrar las réplicas en las bases de datos distribuidas. Las transacciones actualizan la copia local y el sistema actualiza las demás réplicas de manera transparente. Un modo de actualizar las réplicas es aplicar la actualización inmediata con compromiso de dos fases, utilizando una de las técnicas de control de concurrencia distribuida que se han visto. Muchos sistemas de bases de datos utilizan el protocolo sesgado, en el que las operaciones de escritura tienen que bloquear y actualizar todas las réplicas y las operaciones de lectura bloquean y leen cualquier réplica, como técnica de control de concurrencia. Muchos sistemas de bases de datos ofrecen una forma alternativa de actualización: actualizan en un sitio dado, con propagación perezosa de las actualizaciones a los demás sitios, en lugar de aplicar de manera inmediata las actualizaciones a todas las réplicas como parte de la transacción que lleva a cabo la actualización. Los esquemas basados en la propagación perezosa permiten que continúe el procesamiento de las transacciones (incluidas las actualizaciones) aunque algún sitio quede desconectado de la red, lo que mejora la disponibilidad, pero, por desgracia, lo hacen a costa de la consistencia. Se suele seguir uno de estos dos enfoques cuando se emplea la propagación perezosa: • Las actualizaciones de las réplicas se traducen en actualizaciones del sitio principal, que luego se propagan de manera perezosa a todas las réplicas. Este enfoque garantiza que las actualizaciones de cada elemento se ordenen de manera secuencial, aunque puedan producirse problemas de secuenciabilidad, ya que puede que las transacciones lean un valor antiguo de algún otro elemento de datos y lo utilicen para llevar a cabo una actualización. • Las actualizaciones se llevan a cabo en cualquier réplica y se propagan a todas las demás. Este enfoque puede provocar todavía más problemas, ya que el mismo elemento de datos puede ser actualizado de manera concurrente en varios sitios. Algunos conflictos debidos a la falta de control de concurrencia distribuida pueden detectarse cuando las actualizaciones se propagan a otros sitios (se verá el modo de hacerlo en el Apartado 24.5.4), pero la resolución del conflicto implica hacer retroceder transacciones comprometidas y, por tanto, no se garantiza la durabilidad de las transacciones comprometidas. Además, puede que se necesite la intervención del personal encargado para que resuelva el conflicto. Por tanto, los esquemas mencionados deben evitarse o utilizarse con precaución.

22.5.4 Tratamiento de los interbloqueos

Los algoritmos de prevención y de detección de interbloqueos del Capítulo 16 pueden utilizarse en los sistemas distribuidos, siempre que se realicen modificaciones. Por ejemplo, se puede utilizar el protocolo de árbol si se define un árbol global entre los elementos de datos del sistema. De manera parecida, el enfoque de ordenación por marcas temporales puede aplicarse de manera directa en entornos distribuidos, como se vio en el Apartado 22.5.2. La prevención de interbloqueos puede dar lugar a esperas y retrocesos innecesarios. Además, puede que algunas técnicas de prevención de interbloqueos necesiten que se impliquen en la ejecución de cada transacción más sitios de los que serían necesarios de otro modo. Si se permite que los interbloqueos se produzcan y se confía en su detección, el problema principal en los sistemas distribuidos es decidir el modo en que se mantiene el grafo de espera. Las técnicas habituales para tratar este problema exigen que cada sitio guarde un grafo local de espera. Los nodos del grafo en un momento dado se corresponden con todas las transacciones (locales y no locales) que en ese momento tienen o solicitan alguno de los elementos locales de ese sitio. Por ejemplo, la Figura 22.3 muestra un sistema que consta de dos sitios, cada uno de los cuales mantiene su propio grafo

www.detodoprogramacion.com


Control de la concurrencia en las bases de datos distribuidas

22.5

Figura 22.3

709

Grafos locales de espera.

local de espera. Obsérvese que las transacciones T2 y T3 aparecen en los dos grafos, lo que indica que han solicitado elementos en los dos sitios. Estos grafos locales de espera se crean de la manera habitual para las transacciones y los elementos de datos locales. Cuando la transacción Ti del sitio S1 necesita un recurso del sitio S2 , envía un mensaje de solicitud al sitio S2 . Si el recurso lo tiene la transacción Tj , el sistema introduce el arco Ti → Tj en el grafo de espera local del sitio S2 . Evidentemente, si algún grafo de espera local tiene un ciclo, se ha producido un interbloqueo. Por otro lado, el hecho de que no haya ciclos en ninguno de los grafos locales de espera no significa que no haya interbloqueos. Para ilustrar este problema, considérense los grafos locales de espera de la Figura 22.3. Cada grafo de espera es acíclico y, sin embargo, hay un interbloqueo en el sistema debido a que la unión de los grafos locales de espera contiene un ciclo. Este grafo aparece en la Figura 22.4. En el enfoque de detección centralizada de interbloqueos el sistema crea y mantiene un grafo global de espera (la unión de todos los grafos locales) en un solo sitio: el coordinador de detección de interbloqueos. Dado que hay un retraso en las comunicaciones en el sistema, hay que distinguir entre dos tipos de grafos de espera. Los grafos reales describen el estado real pero desconocido del sistema en un momento dado, como lo vería un observador omnisciente. Los grafos creados son una aproximación generada por el controlador durante la ejecución de su algoritmo. Evidentemente, el controlador debe generar el grafo creado de modo que, siempre que se invoque al algoritmo de detección, los resultados obtenidos sean correctos. Correcto significa en este caso que, si hay algún interbloqueo, se comunique con prontitud y, si el sistema comunica algún interbloqueo, realmente se halle en estado de interbloqueo. El grafo global de espera debe poder volver a crearse o a actualizarse bajo las siguientes condiciones: • Siempre que se introduzca o se elimine un nuevo arco en alguno de los grafos locales de espera. • De manera periódica, cuando se hayan producido varias modificaciones en los grafos locales de espera. • Siempre que el coordinador necesite invocar el algoritmo de detección de ciclos. Cuando el coordinador invoca el algoritmo de detección de interbloqueos, busca en su grafo global. Si halla un ciclo, selecciona una víctima para hacer que retroceda. El coordinador debe comunicar a todos los sitios que se ha seleccionado como víctima a una transacción concreta. Los sitios, a su vez, hacen retroceder la transacción víctima. Este esquema puede producir retrocesos innecesarios si:

Figura 22.4

T1

T2

T5

T3

T4

Grafo global de espera de la Figura 22.3.

www.detodoprogramacion.com


710

Capítulo 22

Bases de datos distribuidas

Figura 22.5

Ciclos falsos en el grafo global de espera.

• Existen ciclos falsos en el grafo global de espera. A modo de ejemplo, considérese una instantánea del sistema representado por los grafos locales de espera de la Figura 22.5. Supóngase que T2 libera el recurso que tiene en el sitio S1 , lo que provoca la eliminación del arco T1 → T2 de S1 . La transacción T2 solicita entonces un recurso que tiene T3 en el sitio S2 , lo que da lugar a la agregación del arco T2 → T3 en S2 . Si el mensaje insertar T2 → T3 llega antes que el mensaje eliminar T1 → T2 de S1 , puede que el coordinador descubra el ciclo falso T1 → T2 → T3 después del mensaje insertar (pero antes del mensaje eliminar). Puede que se inicie la recuperación de interbloqueos, aunque no se haya producido ninguno. Obsérvese que la situación con ciclos falsos no se puede producir con bloqueos de dos fases. La probabilidad de aparición de ciclos falsos suele ser lo bastante baja como para que no generen un problema serio de rendimiento. • Se produce realmente un interbloqueo y se escoge una víctima cuando resulta que se ha abortado alguna de las transacciones por motivos no relacionados con el interbloqueo. Por ejemplo, supóngase que el sitio S1 de la Figura 22.3 decide abortar T2 . Al mismo tiempo, el coordinador ha descubierto un ciclo y ha escogido como víctima a T3 . Se hace que retrocedan tanto T2 como T3 , aunque sólo sería necesario hacer que retrocediera T2 . La detección de interbloqueos puede hacerse de manera distribuida, con varios sitios que asuman partes de la tarea, en lugar de hacerla en un solo sitio. No obstante, los algoritmos correspondientes resultan más complicados y costosos. Véanse las notas bibliográficas para hallar referencias a esos algoritmos 22.6 Disponibilidad

Uno de los objetivos del empleo de bases de datos distribuidas es disfrutar de una disponibilidad elevada; es decir, la base de datos debe funcionar casi todo el tiempo. En concreto, dado que los fallos son más probables en los sistemas distribuidos de gran tamaño, las bases de datos distribuidas deben seguir funcionando aunque sufran diferentes tipos de fallos. La posibilidad de continuar funcionando incluso durante los fallos se denomina robustez. Para que un sistema distribuido sea robusto debe detectar los fallos, reconfigurar el sistema de modo que el cálculo pueda continuar y recuperarse cuando se repare el procesador o el enlace. Los diferentes tipos de fallos se tratan de manera diferente. Por ejemplo, la pérdida de mensajes se trata mediante su retransmisión. La retransmisión repetida de un mensaje por un enlace, sin la recepción de un acuse de recibo, suele ser síntoma de un fallo de ese enlace. La red intentará hallar una ruta

www.detodoprogramacion.com


22.6

Disponibilidad

711

alternativa para el mensaje. La imposibilidad de hallar esa ruta suele ser síntoma de una división de la red. No obstante, no suele ser posible diferenciar claramente entre los fallos de los sitios y las divisiones de la red. El sistema, generalmente, puede detectar que se ha producido un fallo, pero puede que no logre identificar su tipo. Por ejemplo, supóngase que el sitio S1 no puede comunicar con S2 . Puede ser que S2 haya fallado. No obstante, otra posibilidad es que el enlace entre S1 y S2 haya fallado, lo que habrá provocado la división de la red. El problema se aborda en parte empleando varios enlaces entre los diferentes sitios, de modo que, aunque falle algún enlace, sigan conectados. Sin embargo, todavía pueden fallar varios enlaces simultáneamente, por lo que hay situaciones en las que no se puede estar seguro de si se ha producido un fallo del sitio o una división de la red. Supóngase que el sitio S1 ha descubierto que se ha producido un fallo. Debe iniciar un procedimiento que permita que el sistema se reconfigure y continúe con el modo normal de operación. • Si en el momento del fallo había transacciones activas en un sitio que haya fallado o que haya quedado inaccesible, hay que abortar esas transacciones. Resulta conveniente abortarlas cuanto antes, ya que puede que tengan bloqueos sobre datos de sitios que sigan activos; puede que esperar a que el sito que ha fallado o que ha quedado inaccesible vuelva a estar accesible impida otras transacciones en sitios que están operativos. No obstante, en algunos casos, cuando los objetos de datos están replicados, puede que sea posible seguir adelante con las operaciones de lectura y de actualización aunque algunas réplicas estén inaccesibles. En ese caso, cuando se recupera el sitio que ha fallado, si tenía réplicas de algún objeto de datos, debe obtener los valores actualizados de esos objetos de datos y asegurarse de que recibe todas las actualizaciones posteriores. Este problema se aborda en el Apartado 22.6.1. • Si los datos replicados se guardan en un sitio que ha fallado o que está inaccesible, hay que actualizar el catálogo para que las consultas no hagan referencia a la copia ubicada en ese sitio. Cuando el sitio vuelva a estar activo, hay que asegurarse de que los datos que alberga sean consistentes, como se verá en el Apartado 22.6.3. • Si el sitio que ha fallado es un servidor central de algún subsistema, hay que celebrar una elección para determinar el nuevo servidor (véase el Apartado 22.6.5). Entre los servidores centrales están los servidores de nombres, los coordinadores de concurrencia y los detectores globales de interbloqueos. Dado que, en general, no es posible distinguir entre los fallos de los enlaces de red y los de los sitios, hay que diseñar todos los esquemas de reconfiguración para que funcionen de manera correcta en caso de división de la red. En concreto, deben evitarse las situaciones siguientes: • Que se elijan dos o más servidores centrales en particiones distintas. • Que más de una partición actualice un mismo elemento de datos replicado. 22.6.1 Enfoque basado en la mayoría

Se puede modificar el enfoque basado en la mayoría del control distribuido de la concurrencia del Apartado 22.5.1.4 para que funcione a pesar de los fallos. En este enfoque, cada objeto de datos guarda con él un número de versión para detectar el momento en que se escribió en él por última vez. Siempre que una transacción escribe un objeto, actualiza también su número de versión de la manera siguiente: • Si el objeto de datos a se replica en n sitios diferentes, se debe enviar un mensaje de solicitud de bloqueo a más de la mitad de los n sitios en los que se guarda a. La transacción no opera sobre a hasta que ha conseguido obtener un bloqueo en la mayoría de las réplicas de a. • Las operaciones de lectura examinan todas las réplicas sobre las que se ha obtenido el bloqueo y leen el valor de la réplica que tenga el número de versión más elevado (de manera opcional, también pueden escribir ese valor en las réplicas con números de versión más bajos). Las operaciones de escritura leen todas las réplicas, igual que hacen las operaciones de lectura, para hallar el número de versión más elevado (normalmente, una operación de lectura habrá llevado a cabo antes este paso de la transacción, y el resultado obtenido se puede volver a utilizar). El nuevo

www.detodoprogramacion.com


712

Capítulo 22

Bases de datos distribuidas

número de versión es una unidad mayor que el número de versión más elevado encontrado. La operación de escritura escribe en todas las réplicas sobre las que ha obtenido bloqueos y da al número de versión de todas las réplicas el valor del nuevo número de versión. Los fallos durante las transacciones (tanto las divisiones de la red como los fallos de los sitios) se pueden tolerar siempre que (1) los sitios disponibles en el momento del compromiso contengan la mayoría de las réplicas de todos los objetos en los que se ha escrito y (2) durante las operaciones de lectura se lea la mayoría de las réplicas para averiguar su número de versión. Si se violan estos requisitos, hay que abortar la transacción. Siempre que se satisfagan estos requisitos, se puede utilizar el protocolo de compromiso de dos fases, como siempre, en los sitios que estén disponibles. En este esquema la reintegración resulta trivial; no hay que hacer nada. Esto se debe a que las operaciones de escritura habrían actualizado la mayoría de las réplicas, mientras las operaciones de lectura leerán la mayoría de las réplicas y hallarán, como mínimo, una que tenga la última versión. La técnica de numeración de las versiones utilizada con el protocolo de mayoría se puede utilizar también para hacer que funcione el protocolo de consenso de quórum en presencia de fallos. Los detalles (evidentes) se dejan al lector. No obstante, el riesgo de que los fallos eviten que el sistema procese las transacciones aumenta si se asignan pesos superiores a algunos sitios. 22.6.2 Enfoque leer uno, escribir todos los disponibles

Como caso especial de consenso de quórum se puede emplear el protocolo sesgado, si se asignan pesos unitarios a todos los sitios, se define el quórum de lectura como 1 y se define el quórum de escritura como n (todos los sitios). En este caso especial no hace falta utilizar números de versión; sin embargo, con que falle un solo sitio que contenga un elemento de datos, no podrá llevarse a cabo ninguna operación de escritura en ese elemento, ya que no se dispondrá del quórum de escritura. Este protocolo se denomina protocolo leer uno, escribir todos, ya que hay que escribir todas las réplicas. Para permitir que el trabajo continúe en caso de fallos, sería deseable poder utilizar el protocolo leer uno, escribir todos los disponibles. En este enfoque las operaciones de lectura se llevan a cabo como en el esquema leer uno, escribir todos; se puede leer cualquier réplica disponible, y sobre ella se obtiene un bloqueo de lectura. Se envía una operación de escritura a todas las réplicas, y se adquieren bloqueos de escritura sobre todas ellas. Si algún sitio no está disponible, el gestor de transacciones continúa su labor sin esperar a que se recupere. Aunque este enfoque parezca muy atractivo, presenta varias complicaciones. En concreto, los fallos de comunicación temporales pueden hacer que un sitio parezca no disponible, lo que hace que la operación de escritura no se lleve a cabo pero, cuando el enlace se restaura, el sitio no sabe que tiene que llevar a cabo acciones de reintegración para ponerse al día con las operaciones de escritura que se ha perdido. Además, si la red se divide, puede que cada partición actualice el mismo elemento de datos, creyendo que los sitios de las demás particiones no funcionan. El esquema leer uno, escribir todos los disponibles puede utilizarse si nunca se producen divisiones de la red, pero puede dar lugar a inconsistencias en caso de que se produzcan. 22.6.3 Reintegración de los sitios

La reintegración al sistema de los sitios o enlaces reparados exige la adopción de precauciones. Cuando un sitio que ha fallado se recupera, debe iniciar un procedimiento para actualizar sus tablas de sistema y que reflejen las modificaciones acaecidas mientras estaba fuera de servicio. Si el sitio tiene réplicas de elementos de datos, debe obtener sus valores actualizados y asegurarse de que recibe todas las actualizaciones que se produzcan a partir de ese momento. La reintegración de los sitios es más complicada de lo que parece a primera vista, ya que puede que haya actualizaciones de los elementos de datos que se procesen durante el tiempo en el que el sitio se está recuperando. Una solución sencilla es detener temporalmente todo el sistema hasta que el sitio que ha fallado vuelva a estar activo. En la mayor parte de las aplicaciones, sin embargo, esa detención temporal plantea problemas inaceptables. Se han desarrollado técnicas para permitir que los sitios que han fallado se reintegren mientras se ejecutan de manera concurrente las actualizaciones de los elementos de datos. Antes de que se conceda ningún bloqueo de lectura o escritura sobre algún elemento de datos, el sitio

www.detodoprogramacion.com


22.6

Disponibilidad

713

debe asegurarse de que se ha puesto al día con todas las actualizaciones de ese elemento de datos. Si se recupera un enlace que había fallado, se pueden volver a unir dos o más divisiones de la red. Dado que la división de la red limita las operaciones admisibles para algunos de los sitios, o para todos ellos, hay que informar con prontitud a todos los sitios de la recuperación de ese enlace. Véanse las notas bibliográficas para obtener más información sobre la recuperación en los sistemas distribuidos. 22.6.4 Comparación con la copia de seguridad remota

Los sistemas remotos de copia de seguridad, que se estudiaron en el Apartado 17.9, y la réplica en las bases de datos distribuidas son dos enfoques alternativos para la provisión de una disponibilidad elevada. La diferencia principal entre los dos esquemas es que, con los sistemas remotos de copia de seguridad, las acciones como el control de concurrencia y la recuperación se llevan a cabo en un único sitio, y sólo se replican en el otro sitio los datos y los registros del registro histórico. En concreto, los sistemas remotos de copia de seguridad ayudan a evitar el compromiso de dos fases, y las sobrecargas resultantes. Además, las transacciones sólo tienen que entrar en contacto con un sitio (el sitio principal) y, así, se evita la sobrecarga de la ejecución del código de las transacciones en varios sitios. Por tanto, los sistemas remotos de copia de seguridad ofrecen un enfoque de la elevada disponibilidad de menor coste que las réplicas. Por otro lado, la réplica puede ofrecer mayor disponibilidad al tener disponibles varias réplicas y utilizar el protocolo de mayoría. 22.6.5 Selección del coordinador

Varios de los algoritmos que se han presentado exigen el empleo de un coordinador. Si el coordinador falla por problemas en el sitio en el que reside el sistema, el sistema sólo puede continuar la ejecución reiniciando un nuevo coordinador en otro sitio. Un modo de continuar la ejecución es mantener un coordinador suplente, que esté preparado para asumir la responsabilidad si el coordinador falla. El coordinador suplente es un sitio que, además de otras tareas, mantiene de manera local suficiente información como para poder asumir el papel de coordinador con un perjuicio mínimo al sistema distribuido. Tanto el coordinador como su suplente reciben todos los mensajes dirigidos al coordinador. El coordinador suplente ejecuta los mismos algoritmos y mantiene la misma información interna de estado (como, por ejemplo, para el coordinador de concurrencia, la tabla de bloqueos) que el coordinador auténtico. La única diferencia en funcionamiento entre el coordinador y su suplente es que el suplente no emprende ninguna acción que afecte a otros sitios. Esas acciones se dejan al coordinador auténtico. En caso de que el coordinador suplente detecte el fallo del coordinador auténtico, asume el papel de coordinador. Dado que el suplente dispone de toda la información que tenía el coordinador que ha fallado, el procesamiento puede continuar sin interrupción. La ventaja principal del enfoque del suplente es la posibilidad de continuar el procesamiento de manera inmediata. Si no hubiera un suplente dispuesto a asumir la responsabilidad del coordinador, el coordinador que se designara ex novo tendría que buscar la información en todos los sitios del sistema para poder ejecutar las tareas de coordinación. Con frecuencia, la única fuente de parte de la información necesaria es el coordinador que ha fallado. En ese caso, puede que sea necesario abortar parte de las transacciones activas (o todas ellas) y reiniciarlas bajo el control del nuevo coordinador. Por tanto, el enfoque del coordinador suplente evita retrasos sustanciales mientras el sistema distribuido se recupera del fallo del coordinador. El inconveniente es la sobrecarga de la ejecución duplicada de las tareas del coordinador. Además, el coordinador y su suplente necesitan comunicarse de manera regular para asegurarse de que sus actividades están sincronizadas. En resumen, el enfoque del coordinador suplente supone una sobrecarga durante el procesamiento normal para permitir una recuperación rápida de los fallos del coordinador. A falta de un coordinador suplente designado, o con objeto de tratar varios fallos, los sitios que siguen funcionando pueden escoger de manera dinámica un nuevo coordinador. Los algoritmos de elección permiten que los sitios escojan el sitio del nuevo coordinador de manera descentralizada. Los algoritmos de selección necesitan que se asocie un número de identificación único con cada sitio activo del sistema. El algoritmo de acoso para la elección funciona de la manera siguiente. Para no complicar la notación ni la discusión, supóngase que el número de identificación del sitio Si es i y que el coordinador elegido

www.detodoprogramacion.com


714

Capítulo 22

Bases de datos distribuidas

siempre será el sitio activo con el número de identificación más elevado. Por tanto, cuando un coordinador falla, el algoritmo debe elegir el sitio activo que tenga el número de identificación más elevado. El algoritmo debe enviar ese número a cada sitio activo del sistema. Además, el algoritmo debe proporcionar un mecanismo por el que los sitios que se recuperen de un fallo puedan identificar al coordinador activo. Supóngase que el sitio Si envía una solicitud que el coordinador no responde dentro del intervalo de tiempo predeterminado T. En esa situación se supone que el coordinador ha fallado y Si intenta elegirse a sí mismo como sitio del nuevo coordinador. El sitio Si envía un mensaje de elección a cada sitio que tenga un número de identificación más elevado. Luego espera, un intervalo de tiempo T, la respuesta de cualquiera de esos sitios. Si no recibe respuesta dentro del tiempo T, da por supuesto que todos los sitios con números mayores que i han fallado, se elige a sí mismo sitio del nuevo coordinador y envía un mensaje para informar a todos los sitios activos con números de identificación menores de que i de que es el sitio en el que reside el nuevo coordinador. Si Si recibe respuesta, comienza un intervalo de tiempo T’ para recibir un mensaje que lo informe de que se ha elegido un sitio con un número de identificación más elevado (algún otro sitio se está eligiendo coordinador, y debe comunicar los resultados dentro del tiempo T’). Si Si no recibe ningún mensaje antes de T’, da por supuesto que el sitio con el número más elevado ha fallado y vuelve a iniciar el algoritmo. Después de que un sitio que ha fallado se haya recuperado, comienza de inmediato la ejecución de ese mismo algoritmo. Si no hay ningún sitio activo con un número más elevado, el sitio que se ha recuperado obliga a todos los sitios con números más bajos a permitirle transformarse en el sitio coordinador, aunque ya haya un coordinador activo con un número más bajo. Por este motivo, al algoritmo se le denomina algoritmo de acoso. Si la red se divide, el algoritmo de acoso elige un coordinador diferente en cada partición; para garantizar que, a lo sumo, se elige un coordinador, los sitios que ganan deben comprobar también que la mayoría de los sitios se halla en su partición. 22.7 Procesamiento distribuido de consultas

En el Capítulo 14 se estudió que existen una gran variedad de métodos para el cálculo de la respuesta a una consulta. Se examinaron varias técnicas para escoger una estrategia de procesamiento de consultas que minimice el tiempo que se tarda en calcular la respuesta. Para los sistemas centralizados el criterio principal para medir el coste de una estrategia dada es el número de accesos a disco. En los sistemas distribuidos hay que tener en cuenta varios asuntos más, entre los que se incluyen: • El coste de la transmisión de los datos por la red. • La posible ganancia de rendimiento al hacer que varios sitios procesen en paralelo diferentes partes de la consulta. El coste relativo de la transferencia de datos por la red y del intercambio de datos con el disco varía ampliamente en función del tipo de red y de la velocidad de los discos. Por tanto, en general, uno no se puede centrar exclusivamente en los costes de disco ni en los de la red. Más bien hay que hallar un buen equilibrio entre los dos. 22.7.1 Transformación de consultas

Considérese una consulta extremadamente sencilla: “Hallar todas las tuplas de la relación cuenta”. Aunque la consulta es sencilla (en realidad, trivial), su procesamiento no es trivial, ya que puede que la relación cuenta esté fragmentada, replicada o ambas cosas, como se vio en el Apartado 22.2. Si la relación cuenta está replicada, hay que elegir la réplica. Si las réplicas no se han dividido, se escoge aquélla para la que el coste de transmisión sea mínimo. Sin embargo, si alguna réplica se ha dividido, la elección no resulta tan sencilla, ya que hay que calcular varias reuniones o uniones para reconstruir la relación cuenta. En ese caso, el número de estrategias para el sencillo ejemplo escogido puede ser elevado. Puede que la optimización de las consultas mediante la enumeración exhaustiva de todas las estrategias alternativas no resulte práctica en esas situaciones.

www.detodoprogramacion.com


22.7

Procesamiento distribuido de consultas

715

La transparencia de la fragmentación implica que los usuarios pueden escribir una consulta como σnombre_sucursal = “Guadarrama” (cuenta) Ya que cuenta está definida como cuenta1 ∪ cuenta2 la expresión que resulta del esquema de traducción de nombres es σnombre_sucursal = “Guadarrama” (cuenta1 ∪ cuenta2 ) Esta expresión se puede simplificar de manera automática mediante las técnicas de optimización de consultas del Capítulo 14. El resultado es la expresión σnombre_sucursal = “Guadarrama” (cuenta1 ) ∪ σnombre_sucursal = “Guadarrama” (cuenta2 ) la cual incluye dos subexpresiones. La primera sólo implica a cuenta1 y, por tanto, puede evaluarse en el sitio Guadarrama. La segunda sólo implica a cuenta2 y, por tanto, puede evaluarse en el sitio Cercedilla. Hay otra optimización más que puede hacerse al evaluar σnombre_sucursal = “Guadarrama” (cuenta1 ) Dado que cuenta1 sólo contiene tuplas correspondientes a la sucursal de Guadarrama, se puede eliminar la operación de selección. Al evaluar σnombre_sucursal = “Guadarrama” (cuenta2 ) se puede aplicar la definición del fragmento de cuenta2 para obtener σnombre_sucursal = “Guadarrama” (σnombre_sucursal = “Cercedilla” (cuenta)) Esta expresión es el conjunto vacío, independientemente del contenido de la relación cuenta. Por tanto, la estrategia final es que el sitio Guadarrama devuelva cuenta1 como resultado de la consulta. 22.7.2 Procesamiento de reuniones sencillas

Como se vio en el Capítulo 14, una decisión importante en la selección de una estrategia de procesamiento de consultas es la elección de la estrategia de reunión. Considérese la siguiente expresión del álgebra relacional: cuenta 1 impositor 1 sucursal Supóngase que ninguna de las tres relaciones está replicada ni fragmentada, y que cuenta está almacenada en el sitio S1 , impositor en S2 y sucursal en S3 . Supóngase que SF denota el sitio en el que se ha formulado la consulta. El sistema necesita obtener el resultado en el sitio SF . Entre las posibles estrategias para el procesamiento de esta consulta figuran las siguientes: • Enviar copias de las tres relaciones al sitio SF . Empleando las técnicas del Capítulo 14, hay que escoger una estrategia para el procesamiento local de toda la consulta en el sitio SF . • Enviar una copia de la relación cuenta al sitio S2 y calcular temp1 = cuenta 1 impositor en S2 . Enviar temp1 de S2 a S3 y calcular temp2 = temp1 1 sucursal en S3 . Enviar el resultado temp2 a SF . • Diseñar estrategias parecidas a la anterior con los roles de S1 , S2 y S3 intercambiados. Ninguna de las estrategias es la mejor en todos los casos. Entre los factores que deben tenerse en cuenta están el volumen de los datos que se envían, el coste de la transmisión de los bloques de datos entre cada par de sitios y la velocidad relativa de procesamiento en cada sitio. Considérense las dos primeras estrategias mencionadas. Supóngase que los índices existentes en S2 y en S3 resultan útiles para calcular la reunión. Si se envían las tres relaciones a SF , habrá que volver a crear esos índices en SF o emplear una estrategia de reunión diferente, posiblemente más costosa. Esta recreación de los índices

www.detodoprogramacion.com


716

Capítulo 22

Bases de datos distribuidas

supone una sobrecarga adicional de procesamiento y más accesos a disco. Con la segunda estrategia hay que enviar una relación potencialmente grande (cuenta 1 impositor) de S2 a S3 . Esta relación repite el nombre de cada cliente una vez por cada cuenta que tenga abierta. Por tanto, puede que la segunda estrategia, en comparación con la primera, dé lugar a un mayor volumen de transmisión de datos por la red. 22.7.3 Estrategia de semirreunión

Supóngase que se desea evaluar la expresión r1 1 r2 , donde r1 y r2 se almacenan en los sitios S1 y S2 , respectivamente. Sean r1 y r2 los esquemas de r1 y de r2 . Supóngase que se desea obtener el resultado en S1 . Si hay muchas tuplas de r2 que no se reúnen con ninguna tupla de r1 , el envío de r2 a S1 supone el envío de tuplas que no contribuyen al resultado. Se desea eliminar esas tuplas antes de enviar los datos a S1 , especialmente si los costes de la red son elevados. Una posible estrategia para lograr todo esto es la siguiente: 1. Calcular temp1 ← ΠR1 ∩ R2 (r1 ) en S1 . 2. Enviar temp1 de S1 a S2 . 3. Calcular temp2 ← r2 1 temp1 en S2 . 4. Enviar temp2 de S2 aS1 . 5. Calcular r1 1 temp2 en S1 . La relación resultante es la misma que r1 1 r2 . Antes de considerar la eficiencia de esta estrategia hay que comprobar que la estrategia calcula la respuesta correcta. En el paso 3 temp2 tiene el resultado de r2 1 ΠR1 ∩ R2 (r1 ). En el paso 5 se calcula r1 1 r2 1 ΠR1 ∩ R2 (r1 ) Dado que la reunión es asociativa y conmutativa, se puede volver a escribir esta expresión como (r1 1 ΠR1 ∩ R2 (r1 )) 1 r2 Dado que r1 1 Π(R1 ∩ R2 ) (r1 ) = r1 , la expresión es, realmente, igual a r1 1 r2 , la expresión que se pretendía evaluar. Esta estrategia resulta especialmente ventajosa cuando contribuyen a la reunión relativamente pocas tuplas de r2 . Es probable que se produzca esta situación si r1 es resultado de una expresión de álgebra relacional que implica una selección. En esos casos, puede que temp2 tenga significativamente menos tuplas que r2 . El ahorro de costes de la estrategia procede de no tener que enviar a S1 más que temp2 , en vez de toda r2 . El envío de temp1 a S2 supone un coste adicional. Si sólo contribuye a la reunión una fracción de tuplas de r2 lo bastante pequeña, la sobrecarga del envío de temp1 queda dominada por el ahorro de no tener que enviar más que una parte de las tuplas de r2 . Esta estrategia se denomina estrategia de semirreunión (debido al operador de semirreunión del álgebra relacional, denotado por n). La semirreunión de r1 con r2 , denotada por r1 n r2 , es ΠR1 (r1 1 r2 ) Por tanto, r1 n r2 selecciona las tuplas de r1 que han contribuido a r1 1 r2 . En el paso 3 temp2 = r2 n r1 . Para las reuniones de varias relaciones esta estrategia puede ampliarse a una serie de pasos de semirreunión. Se ha desarrollado un importante corpus teórico en relación con el empleo de la semirreunión para la optimización de consultas. Parte de esta teoría se menciona en las notas bibliográficas. 22.7.4 Estrategias de reunión que aprovechan el paralelismo

Considérese una reunión de cuatro relaciones: r1 1 r2 1 r3 1 r4 donde la relación ri se guarda en el sitio Si . Supóngase que el resultado debe presentarse en el sitio S1 . Hay muchas estrategias posibles para la evaluación en paralelo (el problema del procesamiento de las consultas en paralelo se estudió con detalle en el Capítulo 21). En una de estas estrategias, r1 se envía

www.detodoprogramacion.com


22.8

Bases de datos distribuidas heterogéneas

717

a S2 , donde se calcula r1 1 r2 . Al mismo tiempo, r3 se envía a S4 , donde se calcula r3 1 r4 . El sitio S2 puede enviar las tuplas de (r1 1 r2 ) a S1 a medida que se generan, en lugar de esperar a que se calcule toda la reunión. De manera parecida, S4 puede enviar las tuplas de (r3 1 r4 ) a S1 . Una vez que las tuplas de (r1 1 r2 ) y de (r3 1 r4 ) hayan llegado a S1 , puede comenzar el cálculo de (r1 1 r2 ) 1 (r3 1 r4 ), con la técnica de reunión canalizada del Apartado 13.7.2.2. Por tanto, el cálculo del resultado de la reunión final en S1 puede hacerse en paralelo con el cálculo de (r1 1 r2 ) en S2 , y con el de (r3 1 r4 ) en S4 . 22.8 Bases de datos distribuidas heterogéneas

Muchas de las últimas aplicaciones de bases de datos necesitan datos de gran variedad de bases de datos ya existentes y ubicadas en un conjunto heterogéneo de entornos de hardware y de software. El tratamiento de la información ubicada en bases de datos distribuidas heterogéneas exige una capa de software adicional por encima de los sistemas de bases de datos ya existentes. Esta capa de software se denomina sistema de bases de datos múltiples. Puede que los sistemas locales de bases de datos empleen modelos lógicos y lenguajes de definición y de tratamiento de datos diferentes, y que difieran en sus mecanismos de control de concurrencia y de administración de las transacciones. Los sistemas de bases de datos múltiples crean la ilusión de la integración lógica de las bases de datos sin necesidad de su integración física. La integración completa de sistemas heterogéneos en una misma base de datos distribuida homogénea suele resultar difícil o imposible: • Dificultades técnicas. La inversión en los programas de aplicaciones basados en los sistemas de bases de datos ya existentes puede ser enorme, y el coste de transformar esas aplicaciones puede resultar prohibitivo. • Dificultades organizativas. Aunque la integración resulte técnicamente posible, puede que no lo sea políticamente, porque los sistemas de bases de datos ya existentes pertenezcan a diferentes empresas u organizaciones. En ese caso es importante que el sistema de bases de datos múltiples permita que los sistemas de bases de datos locales conserven un elevado grado de autonomía para la base de datos local y para las transacciones que se ejecuten con esos datos. Por estos motivos los sistemas de bases de datos múltiples ofrecen ventajas significativas que compensan la sobrecarga que suponen. En este apartado se proporciona una visión general de los retos que se afrontan al construir entornos con bases de datos múltiples desde el punto de vista de la definición de los datos y del procesamiento de las consultas. El Apartado 25.7 ofrece una visión general de los problemas de la administración de las transacciones en bases de datos múltiples. 22.8.1 Vista uni cada de los datos

Cada sistema local de administración de bases de datos puede utilizar un modelo de datos diferente. Por ejemplo, puede que algunos empleen el modelo relacional, mientras que otros pueden emplear modelos de datos más antiguos, como el de red (véase el Apéndice A) o el jerárquico (véase el Apéndice B). Dado que se supone que los sistemas con bases de datos múltiples ofrecen la ilusión de un solo sistema de bases de datos integrado, hay que utilizar un modelo de datos común. Una opción adoptada con frecuencia es el modelo relacional, con SQL como lenguaje común de consulta. En realidad, hoy en día hay varios sistemas disponibles que permiten realizar consultas SQL en sistemas de administración de bases de datos no relacionales. Otra dificultad es proporcionar un esquema conceptual común. Cada sistema local ofrece su propio esquema conceptual. El sistema de bases de datos múltiples debe integrar esos esquemas independientes en uno común. La integración de los esquemas es una tarea complicada, sobre todo por la heterogeneidad semántica. La integración de los esquemas no es la mera traducción directa de unos lenguajes de definición de datos a otros. Puede que los mismos nombres de atributos aparezcan en diferentes bases de datos locales pero con significados distintos. Puede que los tipos de datos utilizados en un sistema no estén soportados por los demás y que la traducción de unos tipos a otros no resulte sencilla. Incluso en el

www.detodoprogramacion.com


718

Capítulo 22

Bases de datos distribuidas

caso de tipos de datos idénticos pueden surgir problemas debidos a la representación física de los datos: puede que un sistema utilice ASCII y otro EBCDIC; las representaciones en coma flotante pueden ser diferentes, los enteros pueden representarse como orden más significativo (big–endian) o como orden menos significativo (little – endian). En el nivel semántico, el valor entero de una longitud puede ser pulgadas en un sistema y milímetros en otro, lo que crea una situación incómoda en la que la igualdad entre los enteros sea sólo un concepto aproximado (como ocurre siempre con los números con coma flotante). Puede que el mismo nombre aparezca en idiomas distintos en diferentes sistemas. Por ejemplo, puede que un sistema basado en Estados Unidos se refiera a la ciudad de Saragossa, mientras que uno con base en España lo haga como Zaragoza. Todas estas diferencias aparentemente menores deben registrarse de manera adecuada en el esquema conceptual global común. Hay que proporcionar funciones de traducción. Hay que anotar los índices para el comportamiento dependiente del sistema (por ejemplo, el orden de clasificación de los caracteres no alfanuméricos no es igual en ASCII que en EBCDIC). Como ya se ha comentado, puede que la alternativa de convertir cada base de datos a un formato común no resulte factible sin dejar obsoletos los programas de aplicación ya existentes. 22.8.2 Procesamiento de las consultas

El procesamiento de las consultas en las bases de datos heterogéneas puede resultar complicado. Algunos de los problemas son: • Dada una consulta en un esquema global, puede que haya que traducir la consulta a consultas en los esquemas locales de cada uno de los sitios en que hay que ejecutar la consulta. Hay que volver a traducir los resultados de las consultas al esquema global. La tarea se simplifica escribiendo envolturas para cada origen de datos, que ofrezcan una vista de los datos locales en el esquema global. Las envolturas también traducen las consultas del esquema global a consultas del esquema local y vuelven a traducir los resultados al esquema global. Las envolturas puede ofrecerlas cada sitio o escribirse de manera independiente como parte del sistema de bases de datos múltiples. Las envolturas pueden, incluso, utilizarse para proporcionar una vista relacional de orígenes de datos no relacionales, como las páginas Web (posiblemente con interfaces de formularios), archivos planos, bases de datos jerárquicas y de red y sistemas de directorio. • Puede que algunos orígenes de datos sólo ofrezcan capacidades de consulta limitadas; por ejemplo, puede que soporten selecciones pero no reuniones. Puede incluso que restrinjan la forma de las selecciones, permitiéndolas sólo para determinados campos; los orígenes de datos Web con interfaces de formulario son un ejemplo de este tipo de orígenes de datos. Por tanto, puede que haya que dividir las consultas para que se lleven a cabo en parte en el origen de datos y en parte en el sitio que formula la consulta. • En general, puede que haya que acceder a más de un sitio para responder a una consulta dada. Es posible que haya que procesar las respuestas obtenidas de los diferentes sitios para eliminar los valores duplicados. Supóngase que un sitio contiene las tuplas de cuenta que satisfacen la selección saldo < 100, mientras que otro contiene las que satisfacen saldo > 50. Una consulta sobre toda la relación cuenta exigiría acceder a los dos sitios y eliminar las respuestas duplicadas consecuencia de las tuplas con saldo entre 50 y 100, que están replicadas en los dos sitios. • La optimización global de consultas en bases de datos heterogéneas resulta difícil, ya que puede que el sistema de ejecución de consultas no conozca los costes de los planes de consulta alternativos en los diferentes sitios. La solución habitual es confiar sólo en la optimización a nivel local y utilizar únicamente la heurística a nivel global. Los sistemas mediadores son sistemas que integran varios orígenes de datos heterogéneos, lo que proporciona una vista global integrada de los datos y facilidades de consulta sobre la misma. A diferencia de los sistemas de bases de datos múltiples completos, los sistemas mediadores no se ocupan del procesamiento de las transacciones (los términos mediador y bases de datos múltiples suelen utilizarse

www.detodoprogramacion.com


22.9

Sistemas de directorio

719

de manera indistinta, y puede que los sistemas denominados mediadores soporten formas limitadas de transacción). El término base de datos virtual se utiliza para hacer referencia a los sistemas de bases de datos múltiples o a los sistemas mediadores, ya que ofrecen la apariencia de una sola base de datos con un esquema global, aunque los datos estén en varios sitios en esquemas locales. 22.9 Sistemas de directorio

Considérese una organización que desea poner los datos de sus empleados a disposición de diferentes miembros de la organización; entre esos datos estarían el nombre, el cargo, el ID de empleado, la dirección, la dirección de correo electrónico, el número de teléfono, el número de fax, etc. En los días anteriores a la informática las organizaciones creaban directorios físicos de los empleados y los distribuían por toda la organización. Incluso en nuestros días, las compañías telefónicas crean directorios físicos de sus clientes. En general, un directorio es un listado de la información sobre alguna clase de objetos como las personas. Los directorios pueden utilizarse para hallar información sobre un objeto concreto o, en sentido contrario, hallar objetos que cumplen un determinado requisito. En el mundo de los directorios telefónicos físicos, los directorios que permiten las búsquedas en sentido directo se denominan páginas blancas, mientras que los directorios que permiten las búsquedas en sentido inverso se denominan páginas amarillas. En el mundo interconectado de hoy en día la necesidad de los directorios sigue vigente y, si acaso, es aún más importante. No obstante, hoy en día los directorios deben estar disponibles en las redes informáticas en lugar de en forma física (papel). 22.9.1 Protocolos de acceso a directorios

La información de directorio puede ponerse a disposición de los usuarios mediante interfaces Web, como hacen muchas organizaciones y, en especial, las compañías telefónicas. Esas interfaces son buenas para las personas que las utilizan. No obstante, también los programas necesitan tener acceso a la información de los directorios. Éstos pueden utilizarse para almacenar otros tipos de información, de manera parecida a como hacen los directorios de sistemas de archivos. Por ejemplo, los exploradores Web pueden almacenar marcas personales de sitios favoritos y otros parámetros del explorador en un sistema de directorio. Por tanto, los usuarios pueden acceder a los mismos parámetros desde varias ubicaciones, por ejemplo, desde casa y desde el trabajo, sin tener que compartir el sistema de archivos. Se han desarrollado varios protocolos!de acceso a directorios para ofrecer una manera normalizada de acceso a los datos contenidos en ellos. Entre todos, el más utilizado hoy en día es el protocolo ligero de acceso a directorios (Lightweight Directory Access Protocol, LDAP). Evidentemente, todos los tipos de datos de los ejemplos de este capítulo pueden almacenarse sin demasiados problemas en sistemas de bases de datos, y se puede acceder a ellos mediante protocolos como JDBC u ODBC. La pregunta, entonces, es si hace falta crear un protocolo especializado para el acceso a la información de directorio. Al menos hay dos respuestas a esa pregunta. • En primer lugar, los protocolos de acceso a directorios son protocolos simplificados que atienden a un tipo limitado de acceso a los datos. Han evolucionado en paralelo con los protocolos de acceso a las bases de datos. • En segundo lugar, y lo que es más importante, los sistemas de directorio ofrecen un mecanismo sencillo para nombrar a los objetos de manera jerárquica, parecida a los nombres de los directorios de los sistemas de archivos, que pueden utilizarse en un sistema distribuido de directorio para especificar la información que se almacena en cada servidor de directorio. Por ejemplo, puede que un servidor de directorio concreto almacene la información de los empleados de Laboratorios Bell en Cáceres y que otro almacene la de los empleados de Zarzalejo, lo que da a ambos sitios autonomía para controlar sus datos locales. Se puede utilizar el protocolo de acceso al directorio para obtener datos de los dos directorios a través de la red. Lo que es más importante, el sistema de directorios puede configurarse para que envíe de manera automática a un sitio las consultas formuladas en el otro, sin intervención del usuario.

www.detodoprogramacion.com


720

Capítulo 22

Bases de datos distribuidas

Por estos motivos, varias organizaciones tienen sistemas de directorios para hacer que la información de la organización esté disponible en conexión mediante un protocolo de acceso al directorio. La información del directorio de la organización se puede utilizar con varios fines, como encontrar la dirección, el teléfono o las direcciones de correo electrónico de la gente, encontrar el departamento al que pertenece cada persona y explorar la jerarquía de los departamentos. Los directorios también se utilizan para autenticar a los usuarios: las aplicaciones pueden recoger la información de autentificación, como las contraseñas de los usuarios, y autenticarlos mediante el directorio. Como cabe esperar, varias implementaciones de los directorios consideran conveniente utilizar las bases de datos relacionales para almacenar los datos, en lugar de crear sistemas de almacenamiento específicos.

22.9.2 El protocolo de acceso ligero a directorios LDAP (Lightweight Directory Access Protocol)

En general, los sistemas de directorios se implementan como uno o varios servidores que atienden a varios clientes. Los clientes utilizan la interfaz de programación de aplicaciones definida por el sistema de directorios para comunicarse con los servidores de directorios. Los protocolos de acceso a los directorios también definen un modelo de datos y el control de los accesos. El protocolo de acceso a directorios X.500, definido por la organización internacional para la normalización (International Organization for Standardization, ISO), es una norma para el acceso a información de los directorios. No obstante, el protocolo es bastante complejo y no se utiliza mucho. El protocolo ligero de acceso a directorios (Lightweight Directory Access Protocol, LDAP) ofrece muchas de las características de X.500, pero con menos complejidad y se utiliza mucho. En el resto de este apartado se esbozarán detalles del modelo de datos y del protocolo de acceso de LDAP.

22.9.2.1 El modelo de datos LDAP

En LDAP los directorios almacenan entradas, que son parecidas a los objetos. Cada entrada debe tener un nombre distinguido (ND), que la identifica de manera única. Cada ND, a su vez, está formado por una secuencia de nombres distinguidos relativos (NDR). Por ejemplo, una entrada puede tener el siguiente nombre distinguido: cn=Silberschatz, ou=Laboratorios Bell, o=Lucent, c=EEUU Como puede verse, el nombre distinguido de este ejemplo es una combinación de nombre y dirección (dentro de la organización), que comienza por el nombre de la persona y luego da la unidad organizativa (organizational unit, ou), la organización (organization, o) y el país (country, c). El orden de los componentes del nombre distinguido refleja el orden normal de las direcciones postales, en lugar del orden inverso que se utiliza al especificar nombres de camino para los archivos. El conjunto de NDRs de cada ND viene definido por el esquema del sistema de directorio. Las entradas también pueden tener atributos. LDAP ofrece los tipos binary (binario), string (cadena de caracteres) y time (hora) y, de manera adicional, los tipos tel (telefónico) para los números de teléfono y PostalAddress (dirección postal) para las direcciones (las líneas se separan con un carácter “$”). A diferencia de los del modelo relacional, de manera predeterminada los atributos pueden tener varios valores, por lo que es posible almacenar varios números de teléfono o direcciones para cada entrada. LDAP permite la definición de clases de objetos con nombres y tipos de atributos. Se puede utilizar la herencia para definir las clases de objetos. Además, se puede especificar que las entradas sean de una clase de objeto o de varias. No es necesario que haya una única clase de objeto más específica a la que pertenezca una entrada dada. Las entradas se organizan en un árbol de información del directorio (AID), de acuerdo con sus nombres distinguidos. Las entradas en el nivel de las hojas del árbol suelen representar objetos concretos. Las entradas que son nodos internos representan objetos como las unidades organizativas, las organizaciones o los países. Los hijos de cada nodo tienen un ND que contiene todos los NDR del padre, y uno o

www.detodoprogramacion.com


22.9

Sistemas de directorio

721

varios NDR adicionales. Por ejemplo, puede que un nodo interno tenga como c=España del ND, y todas las entradas por debajo de él tengan el valor EEUU para el campo c del NDR. No hace falta almacenar el nombre distinguido completo en las entradas. El sistema puede generar el nombre distinguido de cada una de ellas recorriendo el AID en sentido ascendente desde la entrada, reuniendo los componentes NDR=valor para crear el nombre distinguido completo. Puede que las entradas tengan más de un nombre distinguido (por ejemplo, la entrada de una persona en más de una organización). Para tratar estos casos el nivel de las hojas del AID puede ser un alias, que apunte a una entrada en otra rama del árbol. 22.9.2.2 Tratamiento de los datos

A diferencia de SQL, LDAP no define ni un lenguaje de definición de datos ni uno de tratamiento de datos. Sin embargo, LDAP define un protocolo de red para llevar a cabo la definición y el tratamiento de los datos. Los usuarios de LDAP pueden utilizar tanto una interfaz de programación de aplicaciones como las herramientas ofrecidas por diferentes fabricantes para llevar a cabo la definición y el tratamiento de los datos. LDAP también define un formato de archivos denominado formato de intercambio de datos LDAP (LDAP Data Interchange Format, LDIF) que puede utilizarse para almacenar e intercambiar información. El mecanismo de consulta en LDAP es muy sencillo, consiste simplemente en selecciones y proyecciones, sin ninguna reunión. Cada consulta debe especificar lo siguiente: • Una base (es decir, un nodo del AID), dando su nombre distinguido (el camino desde la raíz hasta el nodo). • Una condición de búsqueda, que puede ser una combinación booleana de condiciones para diferentes atributos. Se soportan la igualdad, la coincidencia con caracteres comodín y la igualdad aproximada (la definición exacta de la igualdad aproximada depende de cada sistema). • Un ámbito, que puede ser sencillamente la base, la base y sus hijos o todo el subárbol por debajo de la base. • Los atributos que hay que devolver. • Los límites impuestos al número de resultados y al consumo de recursos. La consulta también puede especificar si hay que eliminar de manera automática las referencias de los alias; si se desactiva la eliminación de las referencias de los alias se pueden devolver las entradas de los alias como respuestas. Una manera de consultar orígenes de datos LDAP es emplear URL LDAP. Ejemplos de URL LDAP son: ldap:://aura.research.bell-labs.com/o=Lucent,c=EEUU ldap:://aura.research.bell-labs.com/o=Lucent,c=EEUU??sub?cn=Korth El primer URL devuelve todos los atributos de todas las entradas del servidor en que la organización es Lucent y el país es EEUU. El segundo URL ejecuta una consulta de búsqueda (selección) cn=Korth en el subárbol del nodo con nombre distinguido o=Lucent, c=EEUU. Los signos de interrogación del URL separan campos diferentes. El primer campo es el nombre distinguido, en este caso o=Lucent,c=EEUU. El segundo campo, la lista de atributos que hay que devolver, se ha dejado vacío, lo que significa que hay que devolver todos los atributos. El tercer atributo, sub, indica que hay que buscar en todo el subárbol. El último parámetro es la condición de búsqueda. Una segunda manera de consultar los directorios LDAP es utilizar una interfaz de programación de aplicaciones. La Figura 22.6 muestra un fragmento de código C que se utiliza para conectar con un servidor LDAP y ejecutar en él una consulta. El código, en primer lugar, abre una conexión con un servidor LDAP mediante ldap_open y ldap_bind. Luego ejecuta una consulta mediante ldap_search_s. Los argumentos para ldap_search_s son el controlador de conexión LDAP, el ND de la base desde la que se debe realizar la búsqueda, el ámbito de la búsqueda, la condición de búsqueda, la lista de atributos que hay que devolver y un atributo denominado attrsonly que, si se le asigna el valor de 1, hace que sólo

www.detodoprogramacion.com


722

Capítulo 22

Bases de datos distribuidas

se devuelva el esquema del resultado, sin ninguna tupla real. El último argumento es un argumento de resultados que devuelve el resultado de la búsqueda en forma de estructura LDAPMessage. El primer bucle for itera sobre cada entrada del resultado y la imprime. Obsérvese que cada entrada puede tener varios atributos, y el segundo bucle for imprime cada uno de ellos. Dado que los atributos en LDAP pueden tener varios valores, el tercer bucle for imprime cada uno de los valores de cada atributo. Las llamadas ldap_msgfree y ldap_value_free liberan la memoria que asignan las bibliotecas LDAP. La Figura 22.6 no muestra el código para el tratamiento de las condiciones de error. La API de LDAP también contiene funciones para crear, actualizar y eliminar entradas, así como para otras operaciones con el AID. Cada llamada a una función se comporta como una transacción independiente; LDAP no soporta la atomicidad de las actualizaciones múltiples. 22.9.2.3 Árboles de directorio distribuidos

La información sobre las organizaciones se puede dividir entre varios AIDs, cada uno de los cuales almacena información sobre algunas entradas. El sufijo de cada AID es una secuencia de pares RDN=valor (RDN, Relative Distinguished Name, nombre relativo distinguido) que identifica la información que almacena ese AID; los pares están concatenados con el resto del nombre distinguido generado al recorrer el árbol desde la entrada hasta la raíz. Por ejemplo, el sufijo de un AID puede ser o=Lucent, c=EEUU, #include <stdio.h> #include <ldap.h> main() { LDAP *ld; LDAPMessage *res, *entry; char *dn, *attr, *attrList[] = {“telephoneNumber”, NULL}; BerElement *ptr; int vals, i; ld = ldap_open(“aura.research.bell-labs.com”, LDAP_PORT); ldap_simple_bind(ld, “avi”, “avi-passwd”) ; ldap_search_s(ld, “o=Lucent, c=EEUU”, LDAP_SCOPE_SUBTREE, “cn=Korth”, attrList, /*attrsonly*/ 0, &res); printf(“found %d entries”, ldap_count_entries(ld, res)); for (entry=ldap_first_entry(ld, res); entry != NULL; entry = ldap_next_entry(ld, entry)) { dn = ldap_get_dn(ld, entry); printf(“dn: %s”, dn); ldap_memfree(dn); for (attr = ldap_first_attribute(ld, entry, &ptr); attr ! NULL; attr = ldap_next_attribute(ld, entry, ptr)) { printf(“ %s: ”, attr); vals = ldap_get_values(ld, entry, attr); for (i=0; vals[i] != NULL; i++) printf(“ %s, ”, vals[i]); ldap_value_free(vals); } } ldap_msgfree(res); ldap_unbind(ld); } Figura 22.6

Ejemplo de código LDAP en C.

www.detodoprogramacion.com


22.10

Resumen

723

mientras que otro puede tener el sufijo o=Lucent, c=India. Los AIDs pueden estar divididos organizativa y geográficamente. Los nodos de un AID pueden contener una referencia a un nodo de otro AID; por ejemplo, la unidad organizativa Laboratorios Bellbajo o=Lucent, c=EEUU puede tener su propio AID, en cuyo caso el AID de o=Lucent, c=EEUU tendría el nodo ou=Laboratorios Bell, que representará una referencia al AID de Laboratorios Bell. Las referencias son el componente clave que ayuda a organizar un conjunto distribuido de directorios en un sistema integrado. Puede que, cuando un servidor recibe una consulta sobre un AID, devuelva una referencia al cliente, el cual, a su vez, emite una consulta sobre el AID referenciado. El acceso al AID referenciado es transparente, y se lleva a cabo sin el conocimiento del usuario. Alternativamente, el propio servidor puede formular la consulta al AID referenciado y devolver el resultado junto con el resultado calculado localmente. El mecanismo jerárquico de denominación utilizado por LDAP ayuda a repartir el control de la información entre diferentes partes de la organización. La facilidad de las referencias ayuda a integrar todos los directorios de la organización en un solo directorio virtual. Aunque no sea un requisito LDAP, las organizaciones suelen decidir repartir la información por criterios geográficos (por ejemplo, puede que la organización mantenga un directorio por cada sitio en que tenga una presencia importante) o según su estructura organizativa (por ejemplo, cada unidad organizativa, como puede ser un departamento, mantiene su propio directorio). Muchas implementaciones de LDAP soportan la réplica maestro–esclavo y la réplica multimaestro de los AIDs, aunque la réplica no forme parte de la versión actual de la norma LDAP, la 3. El trabajo de normalización de la réplica en LDAP se halla en curso. 22.10 Resumen

• Los sistemas distribuidos de bases de datos consisten en un conjunto de sitios, cada uno de los cuales mantiene un sistema local de bases de datos. Cada sitio puede procesar las transacciones locales: las transacciones que sólo acceden a datos de ese mismo sitio. Además, cada sitio puede participar en la ejecución de transacciones globales: las que acceden a los datos de varios sitios. La ejecución de las transacciones globales necesita que haya comunicación entre los diferentes sitios. • Las bases de datos distribuidas pueden ser homogéneas, en las que todos los sitios tienen un esquema y un código de sistemas de bases de datos comunes, o heterogéneas, en las que el esquema y el código de los sistemas pueden ser diferentes. • Surgen varios problemas relacionados con el almacenamiento de relaciones en bases de datos distribuidas, incluidas la réplica y la fragmentación. Es fundamental que el sistema minimice el grado de conocimiento por los usuarios del modo en que se almacenan las relaciones. • Los sistemas distribuidos pueden sufrir los mismos tipos de fallos que los sistemas centralizados. No obstante, hay otros fallos con los que hay que tratar en los entornos distribuidos; entre ellos, los fallos de los sitios, los de los enlaces, las pérdidas de mensajes y las divisiones de la red. Es necesario tener en consideración cada uno de esos problemas en el diseño del esquema distribuido de recuperación. • Para asegurar la atomicidad, todos los sitios en los que se ejecuta la transacción T deben estar de acuerdo en el resultado final de su ejecución. O bien T se compromete en todos los sitios o se aborta en todos. Para asegurar esta propiedad el coordinador de la transacción de T debe ejecutar un protocolo de compromiso. El protocolo de compromiso más empleado es el protocolo de compromiso de dos fases. • El protocolo de compromiso de dos fases puede provocar bloqueos, la situación en que el destino de una transacción no se puede determinar hasta que se recupere un sitio que haya fallado (el coordinador). Se puede utilizar el protocolo de compromiso de tres fases para reducir la probabilidad de bloqueo.

www.detodoprogramacion.com


724

Capítulo 22

Bases de datos distribuidas

• La mensajería persistente ofrece un modelo alternativo para el tratamiento de las transacciones distribuidas. El modelo divide cada transacción en varias partes que se ejecutan en diferentes bases de datos. Se envían mensajes persistentes (que está garantizado que se entregan exactamente una vez, independientemente de los fallos) a los sitios remotos para solicitar que se emprendan acciones en ellos. Aunque la mensajería persistente evita el problema de los bloqueos, los desarrolladores de aplicaciones tienen que escribir código para tratar diferentes tipos de fallos. • Los diferentes esquemas de control de concurrencia empleados en los sistemas centralizados se pueden modificar para su empleo en entornos distribuidos. ¤ En el caso de los protocolos de bloqueo, la única modificación que hay que hacer es el modo en que se implementa el gestor de bloqueos. Existen varios enfoques posibles. Se pueden utilizar uno o varios coordinadores centrales. Si, en vez de eso, se adopta un enfoque con un gestor distribuido de bloqueos, hay que tratar de manera especial los datos replicados. ¤ Entre los protocolos para el tratamiento de los datos replicados se hallan el protocolo de copia principal, el de mayoría, el sesgado y el de consenso de quórum. Cada uno de ellos representa diferentes equilibrios en términos de coste y de posibilidad de trabajo en presencia de fallos. ¤ En el caso de los esquemas de marcas temporales y de validación, el único cambio necesario es el desarrollo de un mecanismo para la generación de marcas temporales globales únicas. ¤ Muchos sistemas de bases de datos soportan la réplica perezosa, en la que las actualizaciones se propagan a las réplicas ubicadas fuera del ámbito de la transacción que ha llevado a cabo la actualización. Estas facilidades deben utilizarse con grandes precauciones, ya que pueden dar lugar a ejecuciones no secuenciables. • La detección de interbloqueos en entornos con gestor distribuido de bloqueos exige la colaboración entre varios sitios, dado que puede haber interbloqueos globales aunque no haya ningún interbloqueo local. • Para ofrecer una elevada disponibilidad, las bases de datos distribuidas deben detectar los fallos, reconfigurarse de modo que el cálculo pueda continuar y recuperarse cuando se repare el procesador o el enlace correspondiente. La tarea se complica enormemente por el hecho de que resulta difícil distinguir entre las divisiones de la red y los fallos de los sitios. Se puede extender el protocolo de mayoría mediante el empleo de números de versión para permitir que continúe el procesamiento de las transacciones incluso en presencia de fallos. Aunque el protocolo supone una sobrecarga significativa, funciona independientemente del tipo de fallo. Se dispone de protocolos menos costosos para tratar los fallos de los sitios, pero dan por supuesto que no se producen divisiones de la red. • Algunos algoritmos distribuidos exigen el empleo de coordinadores. Para ofrecer una elevada disponibilidad el sistema debe mantener una copia de seguridad que esté preparada para asumir la responsabilidad si falla el coordinador. Otro enfoque es escoger el nuevo coordinador después de que haya fallado el anterior. Los algoritmos que determinan el sitio que deberá actuar como coordinador se denominan algoritmos de elección. • Puede que las consultas a las bases de datos distribuidas necesiten tener acceso a varios sitios. Se dispone de varias técnicas de optimización para escoger los sitios a los que hay que tener acceso. Basadas en la fragmentación y en la réplica, las técnicas pueden utilizar técnicas de semirreunión para reducir las transferencias de datos. • Las bases de datos distribuidas heterogéneas permiten que cada sitio tenga su propio esquema y su propio código de sistema de bases de datos. Los sistemas de bases de datos múltiples ofrecen un entorno en el que las nuevas aplicaciones de bases de datos pueden acceder a los datos de gran variedad de bases de datos ya existentes ubicadas en diferentes entornos heterogéneos de hardware y de software. Puede que los sistemas locales de bases de datos empleen modelos lógicos y lenguajes de definición o de manipulación de datos diferentes y que se diferencien en los mecanismos de control de concurrencia o de administración de las transacciones. Los sistemas de bases de datos múltiples crean la ilusión de la integración lógica de las bases de datos, sin exigir su integración física.

www.detodoprogramacion.com


Términos de repaso

725

• Los sistemas de directorio pueden considerarse una modalidad especializada de base de datos en la que la información se organiza de manera jerárquica, parecida al modo en que los archivos se organizan en los sistemas de archivos. Se accede a los directorios mediante protocolos normalizados de acceso a directorios, como LDAP. Los directorios pueden estar distribuidos entre varios sitios para proporcionar autonomía a cada sitio. Los directorios pueden contener referencias a otros directorios, lo que ayuda a crear vistas integradas en las que cada consulta sólo se envía a un directorio y se ejecuta de manera transparente en los directorios correspondientes Términos de repaso

• Base de datos distribuida homogénea. • Base de datos distribuida heterogénea. • Réplica de datos. • Copia principal. • Fragmentación de los datos: ¤ Horizontal. ¤ Vertical. • Transparencia de los datos: ¤ De la fragmentación. ¤ De la réplica. ¤ De la ubicación. • Servidor de nombres. • Alias. • Transacciones distribuidas: ¤ Locales. ¤ Globales. • Gestor de transacciones. • Coordinador de transacciones. • Modalidades de fallo del sistema. • División de la red. • Protocolos de compromiso. • Protocolo de compromiso de dos fases (C2F). ¤ Estado de preparación. ¤ Transacciones dudosas. ¤ Problema del bloqueo.

• Marcas temporales. • Réplica maestro–esclavo. • Réplica con varios maestros (actualización distribuida). • Instantánea consistente con las transacciones. • Propagación perezosa. • Tratamiento de los interbloqueos. ¤ Grafo local de espera. ¤ Grafo global de espera. ¤ Ciclos falsos. • Disponibilidad. • Robustez. ¤ Enfoque basado en la mayoría. ¤ Leer uno, escribir todo. ¤ Leer uno, escribir todos los disponibles. ¤ Reintegración de sitios. • Selección del coordinador. • Coordinador suplente. • Algoritmos de selección. • Algoritmo de acoso. • Procesamiento distribuido de consultas. • Estrategia de semirreunión. • Sistema de bases de datos múltiples. • Autonomía. • Mediadores.

• Protocolo de compromiso de tres fases (C3F).

• Base de datos virtual. • Sistemas de directorio.

• Mensajería persistente. • Control de la concurrencia.

• Protocolo ligero de acceso a directorios LDAP (Lightweight directory access protocol).

• Gestor único de bloqueos. • Gestor distribuido de bloqueos. • Protocolos para las réplicas. ¤ Copia principal. ¤ Protocolo de mayoría. ¤ Protocolo sesgado. ¤ Protocolo de consenso de quórum.

¤ Nombre distinguido (ND). ¤ Nombres distinguidos relativos (NDR). ¤ Árbol de información del directorio (AID). • Árboles distribuidos de directorio. • Sufijo AID. • Referencia.

www.detodoprogramacion.com


726

Capítulo 22

Bases de datos distribuidas

Ejercicios prácticos

22.1 Indíquese lo que diferencia a una base de datos distribuida diseñada para una red de área local de otra diseñada para una red de área amplia. 22.2 Para crear un sistema distribuido con elevada disponibilidad hay que conocer los tipos de fallos que pueden producirse. a. Indíquense los tipos de fallos posibles en los sistemas distribuidos. b. Indíquense los elementos de la lista de la pregunta a que también sean aplicables a los sistemas centralizados. 22.3 Considérese un fallo que se produce durante la ejecución de C2F para una transacción. Para cada fallo posible de los indicados en el Ejercicio práctico 22.2.a, explíquese el modo en que C2F garantiza la atomicidad de la transacción a pesar del fallo. 22.4 Considérese un sistema distribuido con dos sitios, A y B. Indíquese si el sitio A puede distinguir entre: • B deja de funcionar. • El enlace entre A y B deja de funcionar. • B está extremadamente sobrecargado y su tiempo de respuesta es cien veces el habitual. Indíquense las implicaciones de la respuesta para la recuperación de los sistemas distribuidos. 22.5 El esquema de mensajería persistente descrito en este capítulo depende de las marcas temporales combinadas con el descarte de los mensajes recibidos si son demasiado antiguos. Propóngase un esquema alternativo basado en los números de secuencia en lugar de en las marcas temporales. 22.6 Dese un ejemplo en que el enfoque de leer uno, escribir todos los disponibles conduzca a un estado erróneo. 22.7 Explíquese la diferencia entre la réplica de datos en los sistemas distribuidos y el mantenimiento de sitios remotos de respaldo. 22.8 Dese un ejemplo en el que la réplica perezosa pueda conducir a un estado inconsistente de la base de datos aunque las actualizaciones obtengan un bloqueo exclusivo sobre la copia principal (maestra). 22.9 Considérese el siguiente algoritmo de detección de interbloqueos. Cuando la transacción Ti , en el sitio S1 , solicita un recurso a Tj , en el sitio S3 , se envía un mensaje de solicitud con la marca temporal n. Se inserta el arco (Ti , Tj , n) en el grafo local de espera de S1 . El arco (Ti , Tj , n) sólo se inserta en el grafo local de espera de S3 si Tj ha recibido el mensaje de solicitud y no puede conceder de manera inmediata el recurso solicitado. La solicitud de Ti a Tj en el mismo sitio se trata de la manera habitual; no se asocia ninguna marca temporal con el arco (Ti , Tj ). El coordinador central invoca el algoritmo de detección enviando el mensaje de inicio a cada sitio del sistema. Al recibir ese mensaje, cada sitio envía al coordinador su grafo local de espera. Obsérvese que ese grafo contiene toda la información local que tiene cada sitio sobre el estado del grafo real. El grafo de espera refleja un estado instantáneo del sitio, pero no está sincronizado con respecto a ningún otro sitio. Cuando el controlador ha recibido respuesta de cada sitio, crea un grafo de la manera siguiente: • El grafo contiene un vértice para cada transacción del sistema. • El grafo tiene un arco (Ti , Tj ) si y sólo si ¤ Existe un arco (Ti , Tj ) en uno de los grafos de espera. ¤ Aparece un arco (Ti , Tj , n) (para algún n) en más de un grafo de espera. Pruébese que, si hay un ciclo en el grafo creado, el sistema se halla en estado de interbloqueo y que, si no hay ningún ciclo en el grafo creado, el sistema no se hallaba en estado de interbloqueo cuando comenzó la ejecución del algoritmo. 22.10 Considérese una relación que está fragmentada horizontalmente por número_planta:

www.detodoprogramacion.com


Ejercicios

A 1 4 1 5 8

B 2 5 2 3 9

C 3 6 4 2 7

r Figura 22.7

C 3 3 2 1 1

D 4 6 3 4 2

727

E 5 8 2 1 3

s Relaciones para el Ejercicio práctico 22.11

empleado (nombre, dirección, sueldo, número_planta) Supóngase que cada fragmento tiene dos réplicas: una almacenada en el sitio de Madrid y otra almacenada localmente en el sitio de la planta. Descríbase una buena estrategia de procesamiento de las consultas siguientes, formuladas en el sitio de Lima. a. Determinar todos los empleados de la planta de Managua. b. Determinar el sueldo promedio de todos los empleados. c. Determinar el empleado mejor pagado de cada uno de los sitios siguientes: Buenos Aires, Rosario, Córdoba, Bahía Blanca. d. Determinar el empleado peor pagado de la compañía. 22.11 Calcúlese r n s para las relaciones de la Figura 22.7. 22.12 Dado que la funcionalidad LDAP puede implementarse sobre un sistema de bases de datos, indíquese el motivo por el que la norma LDAP es necesaria. Ejercicios

22.13 Explíquense las ventajas relativas de las bases de datos centralizadas y de las distribuidas. 22.14 Explíquense las diferencias entre transparencia de la fragmentación, transparencia de las réplicas y transparencia de la ubicación. 22.15 Indíquese en qué momento resulta útil tener réplicas de los datos o tenerlos fragmentados. Justifíquese la respuesta. 22.16 Explíquense los conceptos de transparencia y de autonomía. Indíquese el motivo de que estos conceptos sean deseables desde el punto de vista de los factores humanos. 22.17 Si se aplica una versión distribuida del protocolo de granularidad múltiple del Capítulo 16 a una base de datos distribuida, el sitio responsable de la raíz del GAD puede convertirse en un cuello de botella. Supóngase que se modifica ese protocolo de la manera siguiente: • Sólo se permiten en la raíz bloqueos en modo tentativo. • A todas las transacciones se les conceden de manera automática todos los bloqueos en modo tentativo posibles. Pruébese que estas modificaciones alivian el problema sin permitir planificaciones no secuenciables. 22.18 Estúdiense y resúmanse las facilidades que ofrece el sistema de bases de datos que se esté utilizando para tratar los estados inconsistentes a los que se puede llegar con la propagación perezosa de las actualizaciones. 22.19 Explíquense las ventajas e inconvenientes de los dos métodos presentados en el Apartado 22.5.2 para la generación de marcas temporales globalmente únicas. 22.20 Considérense las relaciones

www.detodoprogramacion.com


728

Capítulo 22

Bases de datos distribuidas

empleado (nombre, dirección, sueldo, número_planta) máquina (número_máquina, tipo, número_planta) Supóngase que la relación empleado está fragmentada horizontalmente por número_planta y que cada fragmento se almacena localmente en el sitio de la planta correspondiente. Supóngase que toda la relación máquina se almacena en el sitio de Sucre. Descríbase una buena estrategia para el procesamiento de cada una de las consultas siguientes. a. Determinar todos los empleados de la planta que contiene el número de máquina 1130. b. Determinar todos los empleados de las plantas que contienen máquinas cuyo tipo sea “trituradora”. c. Determinar todas las máquinas de la planta de Almadén. d. Determinar empleado 1 máquina. 22.21 Para cada una de las estrategias del Ejercicio 22.20 indíquese el modo en que la elección de estrategia depende: a. Del sitio en el que se formuló la consulta. b. Del sitio en el que se desea obtener el resultado. 22.22 ¿Es necesariamente ri n rj igual a rj n ri ? ¿En qué circunstancias se cumple ri n rj = rj n ri ? 22.23 Descríbase el modo en que se puede utilizar LDAP para ofrecer varias vistas jerárquicas de los datos sin necesidad de replicar los datos del nivel básico.

Notas bibliográ cas

Las bases de datos distribuidas se explican en los libros de texto Ozsu y Valduriez [1999] y Ceri y Pelagatti [1984]. Las redes de computadoras se estudian en Tanenbaum [2002] y Halsall [1996]. Breitbart et al. [1999b] presentan una visión general de las bases de datos distribuidas. La implementación del concepto de transacción en bases de datos distribuidas se presenta en Gray [1981], Traiger et al. [1982], Spector y Schwarz [1983], y Eppinger et al. [1991]. El protocolo C2F lo desarrollaron Lampson y Sturgis [1976] y Gray [1978]. El protocolo de compromiso de tres fases proviene de Skeen [1981]. Mohan y Lindsay [1983] estudian dos versiones modificadas de C2F, denominadas presumir compromiso y presumir abortar, que reducen la sobrecarga de C2F mediante la definición de suposiciones predeterminadas relativas al destino de las transacciones. El algoritmo de acoso del Apartado 22.6.5 proviene de Garcia-Molina [1982]. La sincronización distribuida de los relojes se estudia en Lamport [1978]. El control distribuido de la concurrencia se estudia en Menasce et al. [1980], Bernstein y Goodman [1980], Bernstein y Goodman [1981] y Bernstein y Goodman [1982]. El gestor de transacciones de R* se describe en Mohan et al. [1986]. El control de concurrencia de los datos replicados que se basa en el concepto de votación se presenta en Gifford [1979] y Thomas [1979]. Las técnicas de validación para los esquemas distribuidos de control de concurrencia se describen en Schlageter [1981], Ceri y Owicki [1983] y Bassiouni [1988]. El problema de las actualizaciones concurrentes de los datos replicados se revisó en el contexto de los almacenes de datos en Gray et al. [1996] Anderson et al. [1998] estudian problemas relativos a la réplica perezosa y a la consistencia. Breitbart et al. [1999a] describen los protocolos de actualización perezosa para el tratamiento de réplicas. Los manuales de usuario de varios sistemas de bases de datos ofrecen detalles del modo en que tratan la réplica y la consistencia. Huang y Garcia-Molina [2001] abordan la semántica de sólo-una-vez en los sistemas de mensajería con réplica. Knapp [1987] estudia la literatura sobre detección distribuida de interbloqueos, el Ejercicio práctico 22.9 procede de Stuart et al. [1984]. El procesamiento distribuido de las consultas se estudia en Wong [1977], Epstein et al. [1978], Hevner y Yao [1979] y Epstein y Stonebraker [1980].

www.detodoprogramacion.com


Notas bibliográficas

729

Selinger y Adiba [1980] y Daniels et al. [1982] describen el enfoque del procesamiento distribuido de las consultas adoptado por R* (una versión distribuida del Sistema R). Mackert y Lohman [1986] ofrecen una evaluación del rendimiento de los algoritmos de procesamiento de consultas en R*. La optimización dinámica de las consultas en bases de datos múltiples se aborda en Ozcan et al. [1997]. Adali et al. [1996] y Papakonstantinou et al. [1996] describen los problemas de optimización de las consultas en los sistemas mediadores. Los libros de texto Weltman y Dahbura [2000] y Howes et al. [1999] tratan LDAP. Kapitskaia et al. [2000] describen los problemas del almacenamiento en la caché de los datos de directorio de LDAP.

www.detodoprogramacion.com


www.detodoprogramacion.com


P

A

R

T

E

8

Otros temas

El Capítulo 23 trata varios aspectos sobre el ajuste de rendimiento de sistemas de bases de datos para aumentar la velocidad de las aplicaciones. También describe las pruebas que se usan para medir el rendimiento de los sistemas de bases de datos comerciales. Después se describe el proceso de normalización y las normas de lenguajes de bases de datos existentes. Concluye con un análisis del papel de los sistemas de bases de datos en el comercio electrónico y los desafíos en el mantenimiento del acceso a datos almacenados en “sistemas heredados”, y sobre la migración de las aplicaciones al nuevo sistema. El Capítulo 24 describe los tipos de datos, tales como los datos temporales, los espaciales y los multimedia, y los aspectos de su almacenamiento en bases de datos. Las aplicaciones como la informática móvil y sus conexiones con las bases de datos también se describen en este capítulo. Finalmente, en el Capítulo 25, se describen varias técnicas avanzadas de procesamiento de transacciones, incluidos los monitores de procesamiento de transacciones, los flujos de trabajo transaccionales, las transacciones de larga duración y las transacciones entre varias bases de datos.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

23

Desarrollo avanzado de aplicaciones

Se pueden distinguir varias tareas en el desarrollo de aplicaciones. En los Capítulos del 6 al 8 se estudió la forma de diseñar y desarrollar una aplicación. Uno de los aspectos del diseño de aplicaciones es el rendimiento que se espera de ellas. De hecho es común encontrar que al finalizar el desarrollo de una aplicación, funciona más lentamente de lo que se hubiera deseado, o gestiona menos transacciones por segundo de las que se requieren. Las aplicaciones que necesitan una cantidad de tiempo excesiva para realizar las acciones requeridas pueden causar el descontento de los usuario en el mejor de los casos y ser totalmente inutilizable en el peor. Se puede hacer que las aplicaciones se ejecuten significativamente más rápido mediante el ajuste del rendimiento, que consiste en hallar y eliminar los cuellos de botella y en añadir el hardware adecuado, como puede ser memoria o discos. Los desarrolladores de aplicaciones pueden ajustar las aplicaciones de diversas formas, así como los administradores pueden acelerar el procesamiento de las aplicaciones. Las normas son muy importantes para el desarrollo de las aplicaciones, especialmente en la época de Internet, dado que éstas necesitan comunicarse entre sí para llevar a cabo tareas útiles. Se han propuesto varias normas que afectan al desarrollo de las aplicaciones de bases de datos. Los sistemas heredados son sistemas de aplicaciones que están desfasados y basados en tecnologías de generaciones anteriores. Sin embargo, suelen hallarse en el núcleo de las organizaciones y ejecutan aplicaciones con misiones críticas. Se describen aspectos de la definición de interfaces y de la migración con los sistemas heredados y el modo en que pueden sustituirse por otros sistemas. 23.1 Ajuste del rendimiento

El ajuste del rendimiento de un sistema implica ajustar varios parámetros y opciones de diseño para mejorar su rendimiento en una aplicación concreta. Existen varios aspectos del diseño de los sistemas de bases de datos que afectan al rendimiento de las aplicaciones (aspectos de alto nivel como el esquema y el diseño de las transacciones, parámetros de las bases de datos como los tamaños de la memoria intermedia y aspectos del hardware como el número de discos). Cada uno de estos aspectos puede ajustarse de modo que se mejore el rendimiento. 23.1.1 Localización de los cuellos de botella

El rendimiento de la mayor parte de los sistemas (al menos, antes de ajustarlos) suele quedar limitado principalmente por el que presenta un componente o unos pocos, denominados cuellos de botella. Por ejemplo, puede que un programa pase el ochenta por ciento del tiempo en un pequeño bucle ubicado en las profundidades del código y el veinte por ciento restante del tiempo en el resto del código; ese pequeño bucle es, pues, un cuello de botella. La mejora del rendimiento de un componente que no sea un cuello de botella hace poco para mejorar la velocidad global del sistema; en este ejemplo, la mejora 733

www.detodoprogramacion.com


734

Capítulo 23

Desarrollo avanzado de aplicaciones

gestor del control de la concurrencia

… solicitud de bloqueo

concesión de bloqueo gestor de la CPU

origen de las transacciones

gestor de transacciones monitor de transacciones

solicitud de página

respuesta de página

solicitud gestor de de página la memoria respuesta intermedia de página

Figura 23.1

gestor de discos

Colas de un sistema de bases de datos.

de la velocidad del resto del código no puede conducir a más de un veinte por ciento de mejora global, mientras que la mejora de la velocidad del bucle cuello de botella puede lograr una mejora de casi el ochenta por ciento global, en el mejor de los casos. Por tanto, al ajustar un sistema, primero hay que intentar descubrir los cuellos de botella y luego eliminarlos mejorando el rendimiento de los componentes que los generan. Cuando se elimina un cuello de botella puede ocurrir que otro componente se transforme en cuello de botella. En los sistemas bien equilibrados ningún componente aislado constituye un cuello de botella. Si el sistema contiene cuellos de botella se infrautilizan los componentes que no forman parte de los cuellos de botella y quizás pudieran haberse sustituido por componentes más económicos de menores prestaciones. En los programas sencillos el tiempo pasado en cada zona del código determina el tiempo global de ejecución. No obstante, los sistemas de bases de datos son mucho más complejos y pueden modelarse como sistemas de colas. Cada transacción necesita varios servicios del sistema de bases de datos, comenzando por la entrada en los procesos del servidor, las lecturas de disco durante la ejecución, los ciclos de la CPU y los bloqueos para el control de concurrencia. Cada uno de estos servicios tiene asociada una cola, y puede que las transacciones pequeñas pasen la mayor parte del tiempo esperando en las colas — especialmente en las colas de E/S de los discos—en lugar de ejecutando código. La Figura 23.1 muestra algunas de las colas de los sistemas de bases de datos. Como consecuencia de las numerosas colas de la base de datos, los cuellos de botella de los sistemas de bases de datos suelen manifestarse en forma de largas colas para un servicio determinado o, de modo equivalente, en elevados índices de uso de un servicio concreto. Si las solicitudes se espacian de manera exactamente uniforme, y el tiempo para atender una solicitud es menor o igual que el tiempo antes de que llegue la siguiente solicitud, cada solicitud hallará el recurso sin usar y podrá iniciar la ejecución de manera inmediata, sin esperar. Por desgracia, la llegada de las solicitudes en los sistemas de bases de datos nunca es tan uniforme, más bien aleatoria. Si un recurso (como puede ser un disco) tiene un índice de uso bajo, es probable que este recurso no se esté utilizando al realizar una solicitud, en cuyo caso el tiempo de espera de la solicitud será cero. Suponiendo llegadas distribuidas de forma aleatoria uniforme, la longitud de la cola (y, en consecuencia, el tiempo de espera) aumentará de manera exponencial con el uso; a medida que el uso se aproxime al cien por cien, la longitud de la cola aumentará abruptamente, lo que dará lugar a tiempos de espera excesivamente elevados. El uso de los recursos debe mantenerse lo suficientemente baja como para que

www.detodoprogramacion.com


23.1

Ajuste del rendimiento

735

la longitud de la cola sea corta. Como indicativo, las usos cercanos al setenta por ciento se consideran buenas, y los superiores al noventa por ciento se consideran excesivas, dado que generan retrasos significativos. Para aprender más sobre la teoría de los sistemas de colas, generalmente conocida como teoría de colas, se pueden consultar las referencias citadas en las notas bibliográficas.

23.1.2 Parámetros ajustables

Los administradores de bases de datos pueden ajustar los sistemas de bases de datos en tres niveles. El nivel inferior es el nivel de hardware. Las opciones para el ajuste de los sistemas en este nivel incluyen añadir discos o usar sistemas RAID (si la E/S de disco constituye un cuello de botella), añadir más memoria si el tamaño de la memoria intermedia de disco constituye un cuello de botella o aumentar la velocidad del procesador si el uso de la CPU constituye un cuello de botella. El segundo nivel consiste en los parámetros de los sistemas de bases de datos, como el tamaño de la memoria intermedia y los intervalos de puntos de revisión. El conjunto exacto de los parámetros de los sistemas de bases de datos que pueden ajustarse depende de cada sistema concreto de bases de datos. La mayor parte de los manuales de los sistemas de bases de datos proporcionan información sobre los parámetros del sistema de bases de datos que pueden ajustarse y sobre el modo en que deben escogerse los valores de esos parámetros. Los sistemas de bases de datos bien diseñados llevan a cabo automáticamente todos los ajustes posibles, lo que libera al usuario o al administrador de la base de datos de esa carga. Por ejemplo, en muchos sistemas de bases de datos el tamaño de la memoria intermedia es fijo pero ajustable. Si el sistema ajusta de manera automática el tamaño de la memoria intermedia observando los indicadores como las tasas de fallo de las páginas, el usuario no tendrá que preocuparse por el ajuste del tamaño de la memoria intermedia. El tercer nivel es el nivel superior. Incluye el esquema y las transacciones. El administrador puede ajustar el diseño del esquema, los índices que se crean y las transacciones que se ejecutan para mejorar el rendimiento. El ajuste en este nivel es, comparativamente, independiente del sistema. Los tres niveles de ajuste interactúan entre sí; hay que considerarlos en conjunto al ajustar los sistemas. Por ejemplo, el ajuste en un nivel superior puede hacer que el cuello de botella pase del sistema de discos a la CPU o viceversa. 23.1.3 Ajuste del hardware

Incluso en un sistema de procesamiento de transacciones bien diseñado, cada transacción suele tener que realizar al menos unas cuantas operaciones de E/S, si los datos necesarios para la transacción se hallan en el disco. Un factor importante en el ajuste de un sistema de procesamiento de transacciones, es asegurarse de que el subsistema de disco puede admitir la velocidad en que se solicitan las operaciones de E/S. Por ejemplo, considérese un disco con un tiempo de acceso de unos diez milisegundos y una velocidad media de transferencia de 25 megabytes por segundo (un disco habitual en la actualidad). Este disco soportaría un poco menos de cien operaciones E/S de acceso aleatorio de cuatro kilobytes cada segundo. Si cada transacción necesita exactamente dos operaciones E/S, cada disco soportará como mucho cincuenta transacciones por segundo. La única manera de soportar más transacciones por segundo es aumentar el número de discos. Si el sistema tiene que soportar n transacciones por segundo y cada una de ella lleva a cabo dos operaciones de E/S, hay que dividir (o fragmentar de otra manera) los datos al menos entre n/ 50 discos (ignorando el sesgo). Hay que tener en cuenta que el factor limitador no es la capacidad del disco, sino la velocidad a la que se puede tener acceso a los datos aleatorios (limitada, a su vez, por la velocidad a la que se puede desplazar el brazo del disco). El número de operaciones de E/S por transacción puede reducirse almacenando más datos en la memoria. Si todos los datos se hallan en la memoria no habrá operaciones de E/S en el disco salvo por las operaciones de escritura. Guardar los datos usados con frecuencia en la memoria reduce el número de operaciones de E/S y compensa el coste extra de la memoria. Guardar los datos usados con muy poca frecuencia en la memoria sería un despilfarro, dado que la memoria es mucho más cara que los discos. El problema es, para una cantidad dada de dinero disponible para gastarlo en discos o en memoria, hallar la mejor manera de gastar el dinero para obtener el número máximo de transacciones por

www.detodoprogramacion.com


736

Capítulo 23

Desarrollo avanzado de aplicaciones

segundo. Una reducción de una operación de E/S por segundo ahorra (precio por unidad de disco)/(accesos por segundo por disco) Por tanto, si se tiene acceso a una página concreta n veces por segundo, el ahorro debido a guardarla en la memoria es n veces el valor calculado anteriormente. Guardar una página en la memoria cuesta (precio por megabyte de memoria)/(páginas por megabyte de memoria) Por tanto, el punto de equilibrio es n∗

precio por unidad de disco precio por megabyte de memoria = accesos por segundo por disco páginas por megabyte de memoria

Se puede reordenar la ecuación y sustituir los valores actuales por cada uno de los parámetros citados más arriba para obtener un valor de n; si se tiene acceso a una página con una frecuencia mayor que ésta merece la pena comprar suficiente memoria como para almacenarla. La tecnología de discos y los precios actuales de los discos dan un valor de n de alrededor de 1/300 veces por segundo (o, de manera equivalente, una vez cada cinco minutos) para las páginas a las que se tiene acceso de manera aleatoria. Este razonamiento se refleja en la recomendación denominada regla de los cinco minutos: si una página se usa más de una vez cada cinco minutos se debe guardar en la caché de memoria. En otras palabras, merece la pena comprar suficiente memoria para guardar en la caché todas las páginas a las que se tiene acceso al menos una vez cada cinco minutos de promedio. Para los datos a los que se tiene acceso con menos frecuencia hay que comprar discos suficientes para soportar la tasa de E/S exigida por los datos. La fórmula para hallar el punto de equilibrio depende de factores, como los costes de los discos y de la memoria, que han cambiado en factores de cien o de mil en la última década. No obstante, resulta interesante observar que los índices de los cambios han sido tales que el punto de equilibrio ha permanecido en unos cinco minutos; ¡la regla de los cinco minutos no se ha vuelto la regla de la hora o la regla del segundo! Para los datos con acceso secuencial se puede leer un número de páginas por segundo significativamente mayor. Suponiendo que se lee cada vez un megabyte de datos, se obtiene la regla del minuto, que dice que los datos con acceso secuencial deben guardarse en la caché de memoria si se usan al menos una vez por minuto. Las recomendaciones sólo tienen en cuenta el número de operaciones de E/S y no tienen en consideración factores como el tiempo de respuesta. Algunas aplicaciones necesitan guardar en la memoria incluso los datos que se usan con poca frecuencia para soportar tiempos de respuesta inferiores o similares al tiempo de acceso al disco. Otro aspecto del ajuste es si se debe usar RAID 1 o RAID 5. La respuesta depende de la frecuencia con que se actualicen los datos, dado que RAID 5 es mucho más lento que RAID 1 en las operaciones aleatorias de escritura: RAID 5 necesita dos operaciones de lectura y dos operaciones de escritura para ejecutar una sola solicitud aleatoria de escritura. Si una aplicación realiza r operaciones aleatorias de lectura y e operaciones aleatorias de escritura por segundo para soportar un intercambio concreto, una implementación de RAID 5 necesitaría r + 4e operaciones de E/S por segundo, mientras que una implementación de RAID 1 necesitaría r + e operaciones de E/S por segundo. Se puede calcular el número de discos necesario para soportar las operaciones de E/S necesarias por segundo dividiendo el resultado del cálculo por cien operaciones de E/S por segundo (para los discos de la generación actual). Para muchas aplicaciones, r y e son lo bastante grandes como para que (r + e)/100 discos puedan guardar con facilidad dos copias de todos los datos. Para esas aplicaciones, si se usa RAID 1, ¡el número necesario de discos es realmente menor que el número necesario de discos si se usa RAID 5! Por tanto, RAID 5 sólo resulta útil cuando los requisitos de almacenamiento de datos son muy grandes, pero las velocidades de E/S y los requisitos de transferencia de datos son pequeños, es decir, para datos muy grandes y muy “fríos”. 23.1.4 Ajuste del esquema

Dentro de las restricciones de la forma normal escogida es posible dividir las relaciones verticalmente. Por ejemplo, considérese la relación cuenta, con el esquema

www.detodoprogramacion.com


23.1

Ajuste del rendimiento

737

cuenta (número_cuenta, nombre_sucursal, saldo) para la que número_cuenta es una clave. Dentro de las restricciones de las formas normales (formas normales FNBC y tercera) se puede dividir la relación cuenta en dos relaciones: sucursal_cuenta (número_cuenta, nombre_sucursal) saldo_cuenta (número_cuenta, saldo) Las dos representaciones son lógicamente equivalentes, dado que número_cuenta es una clave, pero tienen características de rendimiento diferentes. Si la mayor parte de los accesos a la información de la cuenta sólo examinan número_cuenta y saldo, pueden ejecutarse sobre la relación saldo_cuenta, y es probable que el acceso resulte algo más rápido, dado que no se captura el atributo nombre_sucursal. Por el mismo motivo, cabrán en la memoria intermedia más tuplas de saldo_cuenta que las correspondientes tuplas de cuenta, lo que vuelve a generar un mayor rendimiento. Este efecto sería especialmente destacado si el atributo nombre_sucursal fuera de gran tamaño. Por tanto, un esquema que consistiera en sucursal_cuenta y saldo_cuenta sería preferible en este caso a otro que consistiera en la relación cuenta. Por otro lado, si la mayor parte de los accesos a la información de la cuenta necesitan tanto saldo como nombre_sucursal, el uso de la relación cuenta será preferible, dado que se evitará el coste de la fusión de saldo_cuenta y sucursal_cuenta. Además, la sobrecarga de almacenamiento sería menor, dado que sólo habría una relación y no se replicaría el atributo número_cuenta. Otro truco para mejorar el rendimiento es guardar una relación desnormalizada, como puede ser una fusión de cuenta y de impositor, donde la información sobre los nombres de las sucursales y sobre los saldos se repitiera para cada titular de una cuenta. Hay que realizar más esfuerzo para asegurarse de que la relación es consistente siempre que se realice una actualización. No obstante, una consulta que capture los nombres de los clientes y sus saldos asociados se aceleraría, dado que la fusión de cuenta con impositor se habría calculado previamente. Si se ejecuta con frecuencia una consulta de este tipo, y hay que llevarla a cabo con la máxima eficiencia posible, la relación desnormalizada puede resultar beneficiosa. Las vistas materializadas pueden proporcionar las ventajas que ofrecen las relaciones desnormalizadas, al coste de algún almacenamiento extra; el ajuste del rendimiento de las vistas materializadas se describe en el Apartado 23.1.6. Una de las principales ventajas de las vistas materializadas respecto de las relaciones desnormalizadas es que el mantenimiento de la consistencia de los datos redundantes pasa a ser labor del sistema de bases de datos, no del programador. Por tanto, las vistas materializadas resultan preferibles, siempre que las soporte el sistema de bases de datos. Otro enfoque de la aceleración del cálculo de la fusión sin materializarla es agrupar los registros que coincidirán en la fusión en la misma página del disco. Estas organizaciones agrupadas de archivos se vieron en el Apartado 11.7.2.

23.1.5 Ajuste de los índices

Se pueden ajustar los índices de un sistema de bases de datos para mejorar el rendimiento. Si las consultas constituyen el cuello de botella se las suele poder acelerar creando los índices adecuados en las relaciones. Si lo constituyen las actualizaciones, puede que haya demasiados índices, que hay que actualizar cuando se actualizan las relaciones. La eliminación de índices puede que acelere algunas actualizaciones. La elección del tipo de índice también es importante. Algunos sistemas de bases de datos soportan diferentes tipos de índices, como los índices asociativos y los índices de árboles B. Si las consultas más frecuentes son de rango es preferible usar índices de árboles B a los índices asociativos. Otro parámetro ajustable es la posibilidad de hacer que un índice tenga agrupación. Sólo se puede hacer un índice con agrupación por relación, guardando la relación ordenada por los atributos del índice. Generalmente conviene hacer el índice con agrupación que beneficie al mayor número de consultas y de actualizaciones.

www.detodoprogramacion.com


738

Capítulo 23

Desarrollo avanzado de aplicaciones

Para ayudar a identificar los índices que se deben crear y el índice (si es que hay alguno) de cada relación que se debe agrupar, la mayoría de sistemas de bases de datos comerciales proporcionan asistentes para el ajuste; se describen con más detalle en el Apartado 23.1.7. Estas herramientas usan el historial de consultas y de actualizaciones (denominado carga de trabajo) para estimar los efectos de varios índices en el tiempo de ejecución de las consultas y de las actualizaciones en la carga de trabajo. Las recomendaciones sobre los índices que se deben crear se basan en estas estimaciones. 23.1.6 Uso de vistas materializadas

El uso de las vistas materializadas puede acelerar enormemente ciertos tipos de consultas, en especial las consultas de agregación. Recuérdese el ejemplo del Apartado 14.5 en que el importe total de los créditos de cada sucursal (obtenido sumando los importes de los créditos de todos los créditos de la sucursal) se solicita con frecuencia. Como se vio en ese apartado, la creación de una vista materializada que guarde el importe total de los créditos de cada sucursal puede acelerar enormemente estas consultas. Las vistas materializadas deben usarse con cuidado, no obstante, dado que no sólo supone una sobrecarga de espacio almacenarlas sino que, lo que es más importante, su mantenimiento también supone una sobrecarga de tiempo. En el caso del mantenimiento inmediato de las vistas, si las actualizaciones de una transacción afectan a la vista materializada, hay que actualizarla como parte de la misma transacción. Por tanto, puede que la transacción se ejecute más lentamente. En el caso del mantenimiento diferido de las vistas, la vista materializada se actualiza posteriormente; hasta que se actualice puede que la vista materializada sea inconsistente con las relaciones de la base de datos. Por ejemplo, puede que la vista materializada se actualice cuando la utilice una consulta o que se actualice de manera periódica. El uso del mantenimiento diferido reduce la carga de las transacciones de actualización. Un problema importante es el modo en que se seleccionan las vistas materializadas que hay que mantener. El administrador del sistema puede realizar la selección de modo manual examinando los tipos de consultas de la carga de trabajo y averiguando las consultas que necesitan ejecutarse más rápidamente y las actualizaciones o consultas que pueden ejecutarse más lentamente. A partir del examen, el administrador del sistema puede escoger un conjunto adecuado de vistas materializadas. Por ejemplo, puede que el administrador descubra que se usa con frecuencia un agregado determinado y decida materializarlo, o puede que halle que una fusión concreta se calcula con frecuencia y decida materializarla. Sin embargo, la selección manual resulta tediosa incluso para conjuntos de tipos de consultas moderadamente grandes y puede que resulte difícil realizar una buena selección, dado que exige comprender los costes de diferentes alternativas; sólo el optimizador de consultas puede estimar los costes con una precisión razonable, sin ejecutar realmente la consulta. Por tanto, puede que sólo se halle un buen conjunto de vistas mediante el procedimiento de prueba y error—es decir, materializando una o varias vistas, ejecutando la carga de trabajo y midiendo el tiempo usado para ejecutar las consultas de la carga de trabajo. El administrador repetirá el proceso hasta que se halle un conjunto de vistas que dé un rendimiento aceptable. Una opción mejor es proporcionar soporte para la selección de las vistas materializadas desde el interior del propio sistema de bases de datos, integrado con el optimizador de consultas. Este enfoque se describe con más detalle en el Apartado 23.1.7. 23.1.7 Ajuste automático del diseño físico

La mayoría de sistemas comerciales de bases de datos actuales ofrecen herramientas para ayudar al administrador de la base de datos en la selección de los índices y de las vistas materializadas, y otras tareas relacionadas con el diseño de bases de datos tales como la división de datos en sistemas de bases de datos paralelos. Estas herramientas examinan la carga de trabajo (el historial de consultas y de actualizaciones) y sugiere los índices y las vistas que hay que materializar. El usuario de la herramienta de ajuste tiene la posibilidad de especificar la importancia de la aceleración de las diferentes consultas, lo que el usuario tiene en cuenta al seleccionar las vistas que vaya a materializar. A menudo el ajuste se debe hacer antes de que se desarrolle completamente la aplicación, y el contenido real de la base de datos puede ser pequeño en la de desarrollo, pero se espera que sea mucho más grande en la de producción. Así, algunas

www.detodoprogramacion.com


23.1

Ajuste del rendimiento

739

herramientas de ajuste también permiten que el usuario especifique la información sobre el tamaño previsto de la base de datos y de las estadísticas relacionadas. Database Tuning Assistant de Microsoft, por ejemplo, permite que el usuario formule preguntas del tipo “¿qué pasaría si...?”, por lo que el usuario puede escoger una vista y el optimizador estimará el efecto de materializarla en el coste total de la carga de trabajo y en los costes individuales de los diferentes tipos de consultas o de actualizaciones en la carga de trabajo. Las técnicas de selección automática de índices y vistas materializadas se implementan generalmente enumerando varias alternativas y usando el optimizador de consultas para estimar los costes y las ventajas de seleccionar cada alternativa usando la carga de trabajo. Puesto que el número de los alternativas de diseño puede ser extremadamente grande, así como la carga de trabajo, las técnicas de la selección se deben diseñar cuidadosamente. El primer paso es generar una carga de trabajo. Esto se hace generalmente registrando todas las consultas y actualizaciones que se ejecutan durante un cierto período. Después, las herramientas de selección realizan una compresión de la carga de trabajo, es decir, crean una representación de la carga de trabajo usando un número pequeño de actualizaciones y de consultas. Por ejemplo, las actualizaciones con la misma forma se pueden representar con una sola actualización con un peso que corresponde a cuántas veces ocurrió la actualización. Las consultas con la misma forma se pueden sustituir análogamente por un representante con el peso apropiado. Después de esto, las preguntas que son muy infrecuentes y no tienen un alto coste se pueden desechar del análisis. Las preguntas más costosas se pueden elegir para tratarlas en primer lugar. La compresión de la carga de trabajo es esencial para grandes cargas de trabajo. Con la ayuda del optimizador, la herramienta calcularía un conjunto de índices y de vistas materializadas que mejorarían las consultas y actualizaciones en la compresión de la carga de trabajo. Se pueden probar diversas combinaciones de estos índices y vistas materializadas para encontrar la mejor combinación. Sin embargo, un enfoque exhaustivo sería impracticable, puesto que el número potencial de índices y vistas materializadas es ya grande, y cada subconjunto de éstos es un alternativa potencial de diseño, conduciendo a un número exponencial de alternativas. Se usan heurísticas para la reducción del espacio de alternativas, es decir, para reducir el número de las combinaciones consideradas. Las heurísticas impacientes de la selección de índices y vistas materializadas operan como se explica a continuación. Se estiman las ventajas de la materialización de las diferentes vistas e índices (usando la estimación del coste del optimizador). Se escoge la vista o índice que ofrece la máxima ganancia o la máxima ventaja por unidad de espacio (es decir, la ventaja dividida por el espacio necesario para guardar la vista o el índice). El coste del mantenimiento de la vista o índice también se debe tomar en consideración al calcular la ganancia. Una vez que la heurística ha seleccionado una vista o índice puede que hayan cambiado las ganancias de otras vistas o índices, por lo que la heurística vuelve a calcularlas y escoge la segunda mejor vista para su materialización. El proceso continúa hasta que se agota el espacio de disco disponible para guardar las vistas materializadas e índices, o bien el coste del mantenimiento del resto de candidatos es superior a la ganancia de las consultas que los usen. Las herramientas del mundo real para la selección de índices y vistas materializadas incorporan generalmente algunos elementos de la selección impaciente, pero usan otras técnicas para conseguir mejores resultados. También contemplan otros aspectos del diseño físico de bases de datos, tales como decidir la forma de dividir las relaciones en las bases de datos paralelas, o el mecanismo físico de almacenaje a usar para una relación. 23.1.8 Ajuste de las transacciones

En este apartado se estudian dos enfoques de la mejora del rendimiento de las transacciones: • Mejora de la orientación a conjuntos. • Reducción de la contención de los bloqueos. En el pasado los optimizadores de muchos sistemas de bases de datos no eran especialmente buenos, por lo que el modo en que se había escrito la consulta tenía gran influencia en el modo en que se ejecutaba y, por tanto, en el rendimiento. Los optimizadores avanzados de hoy en día pueden transformar incluso las consultas mal escritas y ejecutarlas de manera eficiente, por lo que la necesidad de ajustar las consultas

www.detodoprogramacion.com


740

Capítulo 23

Desarrollo avanzado de aplicaciones

una a una es menos importante que en el pasado. No obstante, las consultas complejas que contienen subconsultas anidadas no las suelen optimizar muy bien. La mayor parte de los sistemas proporcionan un mecanismo para averiguar el plan de ejecución preciso de las consultas; esta información puede usarse para volver a escribir la consulta de forma que el optimizador pueda trabajar mejor con ella. En SQL incorporado, si se ejecuta con frecuencia una consulta con valores diferentes de un parámetro puede que resulte de ayuda combinar las llamadas en una consulta más orientada al conjunto que sólo se ejecute una vez. El coste de comunicación de las consultas SQL es generalmente elevado en los sistemas cliente-servidor, por lo que la combinación de las llamadas de SQL incorporado resulta de especial ayuda en esos sistemas Por ejemplo, considérese un programa que pase por cada departamento especificado en una lista invocando una consulta de SQL para buscar los gastos totales del departamento usando la estructura group by en la relación gastos (fecha, empleado, departamento, importe). Si la relación gastos no tiene un índice con agrupación en departamento, cada consulta de ese tipo dará lugar a una exploración de la relación. En lugar de eso, se puede usar una sola consulta SQL para averiguar los gastos totales de todos los departamentos; la consulta puede evaluarse con una sola exploración. Los departamentos importantes pueden examinarse luego en esta relación temporal (mucho más pequeña) que contiene el agregado. Aunque haya un índice que permita el acceso eficiente a las tuplas de un departamento dado, el uso de varias consultas SQL puede suponer una gran sobrecarga de comunicaciones en los sistemas cliente– servidor. El coste de comunicaciones puede reducirse usando una sola consulta SQL, capturando los resultados para el lado cliente y pasando por los resultados para hallar las tuplas necesarias. Otra técnica muy usada en los sistemas cliente–servidor para reducir el coste de las comunicaciones y la compilación de SQL es usar procedimientos almacenados, en los que las consultas se guardan en el servidor en forma de procedimientos almacenados, que pueden estar compilados con antelación. Los clientes pueden invocar estos procedimientos almacenados en lugar de comunicar consultas enteras. La ejecución concurrente de diferentes tipos de transacciones puede llevar a veces a un rendimiento bajo por la contención de los bloqueos. Considérese, por ejemplo, una base de datos bancaria. De día se ejecutan de manera casi continua numerosas transacciones de actualización de pequeño tamaño. Supóngase que se ejecuta al mismo tiempo una consulta de gran tamaño que calcula estadísticas de las sucursales. Si la consulta ejecuta una exploración de la relación puede que bloquee todas las actualizaciones de la relación mientras se ejecuta, y eso puede tener un efecto desastroso en el rendimiento del sistema. Algunos sistemas de bases de datos (Oracle y SQL Serverde Microsoft, por ejemplo) permiten el control de concurrencia multiversión, por lo que las consultas se ejecutan sobre una instantánea de los datos, y las actualizaciones pueden seguir de manera concurrente. Esta característica debe usarse si está disponible. Si no se encuentra disponible, una opción alternativa es ejecutar las consultas de gran tamaño en momentos en que las actualizaciones sean pocas o no haya ninguna. Para las bases de datos que soporten los sitios Web puede que no exista ese periodo de calma para las actualizaciones. Otra opción es usar niveles de consistencia más débiles, por lo que la evaluación de la consulta tendrá un impacto mínimo en las actualizaciones concurrentes, pero no se garantiza que los resultados de la consulta sean consistentes. La semántica de la aplicación determina si son aceptables las respuestas aproximadas (inconsistentes). Las aplicaciones mantienen generalmente contadores de secuencias actualizados por muchas transacciones, que pueden convertirse en puntos de la contención de bloqueos. El Ejercicio práctico 23.1 explora la forma en los contadores de secuencias de las bases de datos pueden ayudar a mejorar la concurrencia usando niveles más débiles de consistencia. Las transacciones de actualización de larga duración pueden crear problemas de rendimiento con los registros del sistema e incrementar el tiempo que éste tarda en recuperarse de las caídas. Si una transacción lleva a cabo muchas actualizaciones puede que el registro del sistema se llene antes incluso de que se complete la transacción, en cuyo caso habrá que hacer retroceder la transacción. Si una transacción de actualización se ejecuta durante mucho tiempo (aunque tenga pocas actualizaciones) puede que bloquee la eliminación de las partes más antiguas del registro, si el sistema de registros no está bien diseñado. Nuevamente, este bloqueo puede llevar a que se llene el registro histórico. Para evitar estos problemas muchos sistemas de bases de datos imponen límites estrictos para el número de actualizaciones que puede llevar a cabo una sola transacción. Aunque el sistema no imponga estos límites suele resultar de ayuda fraccionar las transacciones de actualización de gran tamaño en

www.detodoprogramacion.com


23.2

Pruebas de rendimiento

741

conjuntos de transacciones de actualización de menor tamaño siempre que sea posible. Por ejemplo, una transacción que dé un aumento a cada empleado de una gran empresa puede dividirse en una serie transacciones de pequeño tamaño, cada una de las cuales es un pequeño rango de identificadores de empleados. Estas transacciones se denominan transacciones procesadas por minilotes. No obstante, las transacciones procesadas por minilotes deben usarse con cuidado. En primer lugar, si hay actualizaciones concurrentes en el conjunto de empleados puede que el resultado del conjunto de transacciones de menor tamaño no sea equivalente al de la transacción única de gran tamaño. En segundo lugar, si se produce un fallo las transacciones confirmadas habrán aumentado el salario de algunos empleados pero no el de los demás. Para evitar este problema, en cuanto el sistema se recupere del fallo, hay que ejecutar las restantes transacciones del lote. 23.1.9 Simulación del rendimiento

Para comprobar el rendimiento de un sistema de bases de datos incluso antes de instalarlo se puede crear un modelo de simulación del rendimiento de ese sistema. En la simulación se modela cada servicio que aparece en la Figura 23.1, como la CPU, cada disco, la memoria intermedia y el control de concurrencia. En lugar de modelar los detalles de un servicio, puede que el modelo de simulación sólo capture algunos aspectos de cada uno, como el tiempo de servicio —es decir, el tiempo que tarda en acabar de procesar una solicitud una vez comenzado el procesamiento. Por tanto, la simulación puede modelar el acceso a disco partiendo sólo del tiempo medio de acceso a disco. Dado que las solicitudes de un servicio suelen tener que aguardar su turno, cada servicio tiene asociada una cola en el modelo de simulación. Cada transacción consiste en una serie de solicitudes. Las solicitudes se disponen en una cola según llegan y se atienden de acuerdo con la política de cada servicio, como puede ser que el primero en llegar sea el primero en ser atendido. Los modelos de los servicios como la CPU y los discos operan conceptualmente en paralelo, para tener en cuenta el hecho de que estos subsistemas operan en paralelo en los sistemas reales. Una vez creado el modelo de simulación para el procesamiento de las transacciones, el administrador del sistema puede ejecutar en él varios experimentos. El administrador puede usar los experimentos con transacciones simuladas que lleguen con diferentes velocidades para averiguar el modo en que se comportaría el sistema bajo diferentes condiciones de carga. También puede ejecutar otros experimentos que varíen los tiempos de servicio de cada servicio para averiguar la sensibilidad del rendimiento a cada uno de ellos. También se pueden variar los parámetros del sistema de modo que se pueda realizar el ajuste del rendimiento en el modelo de simulación. 23.2 Pruebas de rendimiento

A medida que se van estandarizando los servidores de bases de datos, el factor diferenciador entre los productos de los diferentes fabricantes es el rendimiento de esos productos. Las pruebas de rendimiento son conjuntos de tareas que se usan para cuantificar el rendimiento de los sistemas de software. 23.2.1 Familias de tareas

Dado que la mayor parte de los sistemas de software, como las bases de datos, son complejos hay bastante variación en su implementación por parte de los diferentes fabricantes. En consecuencia, hay una variación significativa en su rendimiento en las diferentes tareas. Puede que un sistema sea el más eficiente en una tarea concreta y puede que otro lo sea en una tarea diferente. Por tanto, una sola tarea no suele resultar suficiente para cuantificar el rendimiento del sistema. En lugar de eso, el rendimiento de un sistema se mire mediante familias de tareas estandarizadas, denominados pruebas de rendimiento. La combinación de los resultados de rendimiento de varias tareas debe realizarse con cuidado. Supóngase que se tienen dos tareas, T1 y T2 , y que se mide la productividad de un sistema como el número de transacciones de cada tipo que se ejecutan en un tiempo dado (digamos, un segundo). Supóngase que el sistema A ejecuta T1 a noventa y nueve transacciones por segundo y que T2 se ejecuta a una transacción por segundo. De manera parecida, supóngase que el sistema B ejecuta T1 y T2 a cincuenta transacciones por segundo. Supóngase también que una carga de trabajo tiene una mezcla a partes iguales de los dos tipos de transacciones.

www.detodoprogramacion.com


742

Capítulo 23

Desarrollo avanzado de aplicaciones

Si se toma el promedio de los dos pares de resultados (es decir, noventa y nueve y uno frente a cincuenta y cincuenta), pudiera parecer que los dos sistemas tienen el mismo rendimiento. Sin embargo, sería erróneo tomar los promedios de esta manera (si se ejecutaran cincuenta transacciones de cada tipo el sistema A tardaría unos 50.5 segundos en concluirlas, mientras que el sistema B las terminaría ¡en sólo 2 segundos!). Este ejemplo muestra que una sola medida del rendimiento induce a error si hay más de un tipo de transacción. El modo correcto de promediar los números es tomar el tiempo para concluir la carga de trabajo, en vez de la productividad promedio de cada tipo de transacción. Se puede así calcular el rendimiento del sistema en transacciones por segundo para una carga de trabajo concreta con exactitud. Por tanto, el sistema A tarda 50.5/100, que son 0.505 segundos por transacción, mientras que el sistema B tarda 0.02 segundos por transacción, en promedio. En términos de productividad, el sistema A se ejecuta a un promedio de 1.98 transacciones por segundo, mientras que el sistema B se ejecuta a 50 transacciones por segundo. Suponiendo que las transacciones de todos los tipos son igual de probables el modo correcto de promediar la productividad respecto de los diferentes tipos de transacciones es tomar la media armónica de las productividades. La media armónica de n productividades f1 , . . . , fn se define como 1 f1

+

1 f2

n + ··· +

1 fn

Para este ejemplo la media armónica de las productividades en el sistema A es 1.98. Para el sistema B es 50. Por tanto, el sistema B es aproximadamente veinticinco veces más rápido que el sistema A para una carga de trabajo consistente en una mezcla a partes iguales de los dos tipos de transacciones de ejemplo. 23.2.2 Clases de aplicaciones de bases de datos

El procesamiento en conexión de transacciones (Online Transaction Processing, OLTP) y la ayuda a la toma de decisiones (incluyendo el procesamiento en conexión analítico (Online Analytical Processing, OLAP)) son dos grandes clases de aplicaciones manejadas por los sistemas de bases de datos. Estas dos clases de tareas tienen necesidades diferentes. La elevada concurrencia y las técnicas inteligentes para acelerar el procesamiento de las operaciones de compromiso se necesitan para soportar una elevada tasa de transacciones de actualización. Por otro lado, los buenos algoritmos para la evaluación de consultas y la optimización de las consultas son necesarios para la ayuda a la toma de decisiones. La arquitectura de algunos sistemas de bases de datos se ha ajustado para el procesamiento de las transacciones; la de otros, como la serie DBC de Teradata de sistemas paralelos de bases de datos, para el ayuda a la toma de decisiones. Otros fabricantes intentan conseguir un equilibrio entre las dos tareas. Las aplicaciones suelen tener una mezcla de necesidades de procesamiento de transacciones y ayuda a la toma de decisiones. Por tanto, el mejor sistema de bases de datos para cada aplicación depende de la mezcla de las dos necesidades que tenga la aplicación. Supóngase que se tienen resultados de productividad para las dos clases de aplicaciones por separado y la aplicación en cuestión tiene una mezcla de transacciones de las dos clases. Hay que ser precavido incluso al tomar la media armónica de los resultados de productividad, debido a la interferencia entre las transacciones. Por ejemplo, una transacción de ayuda a la toma de decisiones que tarde mucho en ejecutarse puede adquirir varios bloqueos, lo que puede evitar el progreso de las transacciones de actualización. La media armónica de las productividades sólo debe usarse si las transacciones no interfieren entre sí. 23.2.3 Las pruebas de rendimiento TPC

El Consejo para el rendimiento del procesamiento de las transacciones (Transaction Processing Performance Council, TPC) ha definido una serie de normas de pruebas de rendimiento para los sistemas de bases de datos. Las pruebas TPC se definen con gran minuciosidad. Definen el conjunto de relaciones y el tamaño de las tuplas. Definen el número de tuplas de las relaciones no como un número fijo, sino como un

www.detodoprogramacion.com


23.2

Pruebas de rendimiento

743

múltiplo del número de transacciones por segundo que se afirma que se realizan, para reflejar que una tasa mayor de ejecución de transacciones probablemente se halle correlacionada con un número mayor de cuentas. La métrica del rendimiento es la productividad, expresado como transacciones por segundo (TPS). Cuando se mide el rendimiento, el sistema debe proporcionar un tiempo de respuesta que se halle dentro de ciertos límites, de modo que una productividad elevada no pueda obtenerse a expensas de tiempos de respuesta muy elevados. Además, para las aplicaciones profesionales, el coste es de gran importancia. Por tanto, la prueba TPC también mide el rendimiento en términos de precio por TPS. Puede que los sistemas de gran tamaño tengan un elevado número de transacciones por segundo, pero puede que resulten caros (es decir, que tengan un precio elevado por TPS). Además, una compañía no puede afirmar que tiene resultados de las pruebas TPC en sus sistemas sin una auditoría externa que asegure que el sistema sigue fielmente la definición de la prueba, incluyendo el soporte pleno de las propiedades ACID de las transacciones. La primera de la serie fue la prueba TPC-A, que se definió en 1989. Esta prueba simula una aplicación bancaria típica mediante un solo tipo de transacción que modela la retirada y el depósito de efectivo en un cajero automático. La transacción actualiza varias relaciones—como el saldo del banco, el saldo del cajero y el saldo del cliente—y añade un registro a una relación de seguimiento para la auditoría. La prueba también incorpora la comunicación con los terminales para modelar el rendimiento de extremo a extremo del sistema de manera realista. La prueba TPC-B se diseñó para probar el rendimiento central del sistema de bases de datos, junto con el sistema operativo en el que se ejecuta el sistema. Elimina las partes de la prueba TPC-A que tratan de los usuarios, de las comunicaciones y de los terminales para centrarse en el servidor de bases de datos dorsal. Ni TPC-A ni TPC-B se usan mucho hoy en día. La prueba TPC-C se diseñó para modelar un sistema más complejo que el de la prueba TPC-A. La prueba TPC-C se concentra en las actividades principales de un entorno de admisión de pedidos, como son la entrada y la entrega de pedidos, el registro de los pagos, la verificación del estado de los pedidos y el seguimiento de los niveles de inventarios. La prueba TPC-C se sigue usando con profusión para el procesamiento de transacciones. La prueba TPC-D se diseñó para probar el rendimiento de los sistemas de bases de datos en consultas de ayuda a la toma de decisiones. Los sistemas de ayuda a la toma de decisiones se están haciendo cada vez más importantes hoy en día. Las pruebas TPC-A, TPC-B y TPC-C miden el rendimiento de las cargas de procesamiento de transacciones y no deben usarse como medida del rendimiento en consultas de ayuda a la toma de decisiones. La D de TPC-D viene de ayuda a la toma de decisiones. El esquema de la prueba TPC-D modela una aplicación de ventas/distribución, con componentes, clientes y pedidos, junto con cierta información auxiliar. El tamaño de las relaciones se define como una relación y el tamaño de la base de datos es el tamaño total de todas las relaciones, expresado en gigabytes. TPC-D con un factor de escala de uno representa la prueba TPC-D para una base de datos de un gigabyte, mientras que el factor de escala diez representa una base de datos de diez gigabytes. La carga de trabajo de la prueba consiste en un conjunto de diecisiete consultas SQL que modelan tareas que se ejecutan frecuentemente en los sistemas de ayuda a la toma de decisiones. Parte de las consultas usan características complejas de SQL, como las consultas de agregación y las consultas anidadas. Los usuarios de las pruebas se dieron cuenta pronto de que las diferentes consultas TPC-D podían acelerarse de manera significativa usando las vistas materializadas y otra información redundante. Hay aplicaciones, como las tareas periódicas de información, donde las consultas se conocen con antelación y las vistas materializadas pueden seleccionarse con cuidado para acelerar las consultas. Resulta necesario, no obstante, tener en cuenta la sobrecarga que supone mantener las vistas materializadas. La prueba TPC-R (donde la R viene de informar—Reporting) supone un refinamiento de la prueba TPC-D. El esquema es el mismo, pero hay veintidós consultas, de las cuales dieciséis provienen de TPC-D. Además, hay dos actualizaciones, un conjunto de inserciones y un conjunto de eliminaciones. Se permite que la base de datos que ejecuta la prueba utilice vistas materializadas y otra información redundante. A diferencia de esto, la prueba TPC-H (donde la H representa ad hoc) usa el mismo esquema y la misma carga de trabajo que TPC-R pero prohíbe las vistas materializadas y otra información redundante y permite las pruebas sólo en las claves principales y ajenas. Esta prueba modela consultas ad hoc donde las consultas no se conocen con anterioridad, por lo que no es posible crear con antelación vistas materializadas adecuadas.

www.detodoprogramacion.com


744

Capítulo 23

Desarrollo avanzado de aplicaciones

Tanto TPC-H como TPC-R miden el rendimiento de esta manera: el test de potencia ejecuta las consultas y las actualizaciones una a una de manera secuencial y tres mil seiscientos segundos divididos por la media geométrica de los tiempos de ejecución de las consultas (en segundos) da una medida de las consultas por hora. El test de productividad ejecuta varias corrientes en paralelo, cada una de las cuales ejecuta las veintidós consultas. También hay una corriente de actualizaciones paralela. Aquí el tiempo total de toda la ejecución se usa para calcular el número de consultas por hora. La métrica compuesta consultas por hora, que es la métrica global, se obtiene como la raíz cuadrada del producto de las métricas de potencia y de productividad. Se define una métrica compuesta precio/rendimiento dividiendo el precio del sistema por la métrica compuesta. La prueba de comercio Web TPC-W es una prueba de extremo a extremo que modela los sitios Web que tienen contenido estático (imágenes, sobre todo) y contenido dinámico generado a partir de una base de datos. Se permite de manera explícita el almacenamiento en caché del contenido dinámico, dado que resulta muy útil para acelerar los sitios Web. La prueba modela una librería electrónica y, como otras pruebas TPC, proporciona diferentes factores de escala. La métrica de rendimiento principal son las interacciones Web por segundo (Web Interactions Per Second, WIPS) y el precio por WIPS. 23.2.4 Las pruebas de rendimiento OODB

La naturaleza de las aplicaciones de las bases de datos orientadas a objetos (OODB, Object Oriented Databases) es diferente de las de las aplicaciones típicas de procesamiento de transacciones. Por tanto, se ha propuesto un conjunto diferente de pruebas para las OODBs. La prueba operaciones con objetos, versión 1, popularmente conocida como prueba OO1, fue una de las primeras propuestas. La prueba OO7 sigue una filosofía diferente de la de las pruebas TPC. Las pruebas TPC proporcionan uno o dos resultados (en términos del promedio de transacciones por segundo y de transacciones por segundo y por dólar); la prueba OO7 proporciona un conjunto de resultados, que contienen un resultado de prueba independiente para cada una de las diferentes clases de operaciones. El motivo de este enfoque es que no está todavía claro lo que es la transacción OODB típica. Está claro que esa transacción llevará a cabo ciertas operaciones, como recorrer un conjunto de objetos conectados o recuperar todos los objetos de una clase, pero no está claro exactamente la mezcla de tales operaciones que se usará. Por tanto, la prueba proporciona resultados separados para cada clase de operaciones; los resultados pueden combinarse de la manera adecuada, en función de la aplicación concreta. 23.3 Normalización

Las normas definen las interfaces de los sistemas de software; por ejemplo, las normas definen la sintaxis y la semántica de los lenguajes de programación o las funciones en la interfaz de los programas de aplicaciones o, incluso, los modelos de datos (como las normas de las bases de datos orientadas a los objetos). Hoy en día los sistemas de bases de datos son complejos y suelen estar constituidos por varias partes creadas de manera independiente que deben interactuar entre sí. Por ejemplo, puede que los programas clientes se creen de manera independiente de los sistemas dorsales, pero todos ellos deben poder interactuar entre sí. Puede que una empresa que tenga varios sistemas de bases de datos heterogéneos necesite intercambiar datos entre las bases de datos. En una situación de este tipo las normas desempeñan un papel importante. Las normas formales son las que han sido desarrolladas por una organización de normalización o por grupos de empresas mediante un procedimiento público. Los productos dominantes se convierten a veces en una norma de facto, en el sentido de que resultan aceptados de manera general como normas sin necesidad de ningún procedimiento formal de reconocimiento. Algunas normas formales, como muchos aspectos de las normas SQL-92 y SQL:1999 son normas anticipativas que lideran el mercado; definen las características que los fabricantes implementan posteriormente en los productos. En otros casos, las normas, o partes de las normas, son normas reaccionarias, en el sentido de que intentan normalizar las características que ya han implementado algunos fabricantes, y que pueden haberse convertido, incluso, en normas de facto. SQL-89 era, en muchos sentidos, reaccionario, dado que estandarizaba características, como la comprobación de la integridad, que ya estaban presentes en la norma SAA SQL de IBM y en otras bases de datos.

www.detodoprogramacion.com


23.3

Normalización

745

Los comités para las normas formales suelen estar compuestos por representantes de los fabricantes y por miembros de grupos de usuarios y de organizaciones de normalización como la Organización internacional de normalización (International Organization for Standardization, ISO) o el Instituto nacional americano de normalización (American National Standards Institute, ANSI) o de organismos profesionales como el Instituto de ingenieros eléctricos y electrónicos (Institute of Electrical and Electronics Engineers, IEEE). Los comités para las normas formales se reúnen de manera periódica y sus componentes presentan propuestas de características de la norma que hay que añadir o modificar. Tras un periodo de discusión (generalmente amplio), de modificaciones de la propuesta y de examen público, los integrantes de los comités votan la aceptación o el rechazo de las características. Tras cierto tiempo de haber definido e implementado de una norma, quedan claras sus carencias y aparecen nuevas necesidades. El proceso de actualización de la norma comienza entonces y tras unos cuantos años suele publicarse una nueva versión de la misma. Este ciclo suele repetirse cada pocos años hasta que, finalmente (quizás muchos años más tarde) la norma se vuelve tecnológicamente irrelevante o pierde su base de usuarios. La norma CODASYL de DBTG para bases de datos en red, formulada por el Grupo de trabajo para bases de datos (Database Task Group, DBTG) fue una de las primeras normas formales en este campo. Los productos de bases de datos de IBM solían establecer las normas de facto, dado que IBM ocupaba gran parte de este mercado. Con el crecimiento de las bases de datos relacionales aparecieron nuevos competidores en el negocio de las bases de datos; por tanto, surgió la necesidad de normas formales. En los últimos años Microsoft ha creado varias especificaciones que también se han convertido en normas de facto. Un ejemplo destacable es ODBC, que se usa actualmente en entornos que no son de Microsoft. JDBC, cuya especificación la creó Sun Microsystems, es otra norma de facto muy usada. Este apartado ofrece una introducción de muy alto nivel a las diferentes normas, concentrándose en los objetivos de cada norma. Las notas bibliográficas al final del capítulo ofrecen referencias de las descripciones detalladas de las normas mencionados en este apartado. 23.3.1 Normas de SQL

Dado que SQL es el lenguaje de consultas más usado se ha trabajado mucho en su normalización. ANSI e ISO, con los diferentes fabricantes de bases de datos, han desempeñado un papel protagonista en esta labor. La norma SQL-86 fue la versión inicial. La norma Arquitectura de aplicaciones de sistemas (Systems Application Architecture, SAA) de IBM para SQL se publicó en 1987. A medida que la gente identificaba la necesidad de más características se desarrollaron versiones actualizadas de la norma formal de SQL, denominadas SQL-89 y SQL-92. La versión SQL:1999 de la norma SQL añadió varias características al lenguaje. Ya se han visto muchas de estas características en los capítulos anteriores. La versión SQL:2003 de la norma SQL es una extenxión menor de la norma SQL:1999. Algunas de las características OLAP (Apartado 18.2.3) de SQL:1999 se especificaron como una enmienda en lugar de esperar a la versión de SQL:2003. La norma SQL:2003 se ha dividido en varias partes: • Parte 1: SQLFramework proporciona una introducción a la norma. • Parte 2: SQL/Foundation define los fundamentos de la norma: tipos, esquemas, tablas, vistas, consultas y sentencias de actualización, expresiones, modelo de seguridad, predicados, reglas de asignación, gestión de transacciones, etc. • Parte 3: SQL/CLI (Call Level Interface) define las interfaces de los programas de aplicaciones con SQL. • Parte 4: SQL/PSM (Persistent Stored Modules) define las extensiones de SQL para hacerlo procedimental. • Parte 9: SQL/MED (Management of External Data) define las normas para la realización de interfaces en los sistemas SQL con orígenes externos. Al escribir envolturas, los diseñadores de los sistemas pueden tratar los orígenes externos de datos, como pueden ser los archivos o los datos de bases de datos no relacionales, como si fueran tablas “externas”. • Parte 10: SQL/OLB (Object Language Bindings) define las normas para la incrustación de SQL en Java.

www.detodoprogramacion.com


746

Capítulo 23

Desarrollo avanzado de aplicaciones

• Parte 11: SQL/Schemata (Information and Definition Schema) define una interfaz estándar para el catálogo. • Parte 13: SQL/JRT (Java Routines and Types) define una norma para el acceso a rutinas y tipos de Java. • Parte 14: SQL/XML define especificaciones relacionadas con XML. Los números que faltan tratan características como los datos temporales, el procesamiento de transacciones distribuidas y los datos multimedia para las que todavía no hay ningún acuerdo sobre las normas.

23.3.2 Normas de conectividad de las bases de datos

La norma ODBC es una norma muy usada para la comunicación entre las aplicaciones clientes y los sistemas de bases de datos. ODBC se basa en las normas SQL Interfaz de nivel de llamada (Call Level Interface, CLI) desarrollados por el consorcio industrial X/Open y el Grupo SQL Access, pero tienen varias extensiones. La API ODBC define una CLI, una definición de sintaxis SQL y reglas sobre las secuencias admisibles de llamadas CLI. La norma también define los niveles de conformidad para la CLI y la sintaxis SQL. Por ejemplo, el nivel central de la CLI tiene comandos para conectarse con bases de datos, para preparar y ejecutar sentencias SQL, para devolver resultados o valores de estado y para administrar transacciones. El siguiente nivel de conformidad (nivel uno) exige el soporte de la recuperación de información de los catálogos y otras características que superan la CLI del nivel central; el nivel dos exige más características, como la capacidad de enviar y recuperar arrays de valores de parámetros y de recuperar información de catálogo más detallada. ODBC permite que un cliente se conecte de manera simultánea con varios orígenes de datos y que conmute entre ellos, pero las transacciones en cada uno de ellos son independientes entre sí; ODBC no soporta el compromiso de dos fases. Los sistemas distribuidos ofrecen un entorno más general que los sistemas cliente–servidor. El consorcio X/Open también ha desarrollado las normas X/Open XA para la interoperación de las bases de datos. Estas normas definen las primitivas de gestión de las transacciones (como pueden ser el comienzo de las transacciones, su compromiso, su anulación y su preparación para el compromiso) que deben proporcionar las bases de datos que cumplan con la norma; los administradores de las transacciones pueden invocar estas primitivas para implementar las transacciones distribuidas mediante compromiso de dos fases. Las normas XA son independientes de los modelos de datos y de las interfaces concretas entre los clientes y las bases de datos para el intercambio de datos. Por tanto, se pueden usar los protocolos XA para implementar sistemas de transacciones distribuidas en los que una sola transacción pueda tener acceso a bases de datos relacionales y orientadas a objetos y que el administrador de transacciones asegure la consistencia global mediante el compromiso de dos fases. Hay muchos orígenes de datos que no son bases de datos relacionales y, de hecho, puede que no sean ni siquiera bases de datos. Ejemplos de esto son los archivos planos y los almacenes de correo electrónico. OLE-DB de Microsoft es una API de C++ con objetivos parecidos a los de ODBC, pero para orígenes de datos que no son bases de datos y que puede que sólo proporcionen servicios limitados de consulta y de actualización. Al igual que ODBC, OLE-DB proporciona estructuras para la conexión con orígenes de datos, el inicio de una sesión, la ejecución de comandos y la devolución de resultados en forma de conjunto de filas, que es un conjunto de filas de resultados. Sin embargo, OLE-DB se diferencia de ODBC en varios aspectos. Para dar soporte a los orígenes de datos con soporte de características limitadas, las características de OLE-DB se dividen entre varias interfaces y cada origen de datos sólo puede implementar un subconjunto de esas interfaces. Los programas OLE-DB pueden negociar con los orígenes de datos para averiguar las interfaces que soportan. En ODBC los comandos siempre están en SQL. En OLE-DB los comandos pueden estar en cualquier lenguaje soportado por el origen de datos; aunque puede que algunos orígenes de datos soporten SQL, o un subconjunto limitado de SQL, puede que otros orígenes sólo ofrezcan posibilidades sencillas como el acceso a los datos de los archivos planos, sin ninguna capacidad de consulta. Otra diferencia importante de OLE-DB con ODBC es que los conjuntos de filas son objetos que pueden compartir varias aplicaciones

www.detodoprogramacion.com


23.3

Normalización

747

mediante la memoria compartida. Los objetos conjuntos de filas los puede actualizar una aplicación, y a las otras aplicaciones que compartan ese objeto se les notificará la modificación. La API objetos activos de datos (Active Data Objects, ADO), también creada por Microsoft, ofrece una interfaz sencilla de usar con la funcionalidad OLE-DB que puede llamarse desde los lenguajes de guiones, como VBScript y JScript. La API más reciente ADO.NET se ha diseñado para las aplicaciones escritas en los lenguaje de .NET; por ejemplo, C# y Visual Basic.NET. Además de proporcionar interfaces simplificados, proporciona una abstracción llamada el DataSet que permite el acceso desconectado a los datos. 23.3.3 Normas de las bases de datos de objetos

Hasta ahora las normas en el área de las bases de datos orientadas a objetos las han impulsado fundamentalmente todo los fabricantes de OODB. El Grupo de gestión de bases de datos de objetos (Object Database Management Group, ODMG) fue un grupo formado por fabricantes de BDOO para normalizar los modelos de datos y las interfaces de lenguaje con las OODBs. La interfaz del lenguaje C++ especificada por ODMG se describió brevemente en el Capítulo 9. ODMG ya no está activo, JDO es una norma para añadir persistencia a Java. El Grupo de administración de objetos (Object Management Group, OMG) es un consorcio de empresas, formado con el objetivo de desarrollar una arquitectura estándar para las aplicaciones de software distribuido basadas en el modelo orientado a objetos. OMG creó el modelo de referencia Arquitectura de gestión de objetos (Object Management Architecture, OMA). El Agente para solicitudes de objetos (Object Request Broker, ORB) es un componente de la arquitectura OMA que proporciona de manera transparente la entrega de mensajes a los objetos distribuidos, de modo que la ubicación física del objeto no tiene importancia. La Arquitectura común de agente para solicitudes de objetos (Common Object Request Broker Architecture, CORBA) proporciona una especificación detallada de ORB, e incluye un Lenguaje de descripción de interfaces (Interface Description Language, IDL), que se usa para definir los tipos de datos usados para el intercambio de datos. IDL ayuda a dar soporte a la conversión de datos cuando se intercambian entre sistemas con diferentes representaciones de los datos. 23.3.4 Normas basadas en XML

Se ha definido una amplia variedad de normas basadas en XML (véase el Capítulo 10) para gran número de aplicaciones. Muchas de estas normas están relacionadas con el comercio electrónico. Entre ellas hay normas promulgadas por consorcios sin ánimo de lucro y esfuerzos por parte de las empresas para crear normas de facto. RosettaNet, que pertenece a la primera categoría, es un consorcio industrial que usa normas basadas en XML para facilitar la gestión de las cadenas de abastecimiento en las industrias informáticas y de tecnologías de la información. Las cadenas de abastecimiento se refieren a las compras del material y de los servicios que una organización necesita para funcionar. En cambio, la gestión de la relación de los clientes se refiere a la parte visible de la interacción con los clientes de una empresa. Las cadenas de abastecimiento requieren la normalización de varias cosas, tales como: • Identificador global de la compañía. RosettaNet especifica un sistema para identificar unívocamente a las compañías, usando un identificador de 9 dígitos denominado sistema de numeración universal de datos (Data Universal Numbering System, DUNS). • Identificador global de productos. RosettaNet especifica el número de 14 dígitos número global de productos comerciales (Global Trade Item Number, GTIN) para identificar productos y servicios. • Identificador global de clases. Se trata de un código jerárquico de 10 dígitos para clasificar productos y servicios denominado código estándar de productos y servicios de las Naciones Unidas (United Nations/Standard Product and Services Code, UN/SPSC). • Interfaces entre los socios implicados. Los procesos de interfaz entre socios (Partner Interface Processes, PIPs) de RosettaNet definen procesos de negocio entre socios. Estos procesos son diálogos entre sistemas basados en XML: definen los formatos y la semántica de los documentos de negocio implicados en el proceso y los pasos implicados en terminar una transacción. Algunos

www.detodoprogramacion.com


748

Capítulo 23

Desarrollo avanzado de aplicaciones

ejemplos de pasos serían conseguir la información de producto y de servicio, los pedidos de compras, facturación de los pedidos, pagos, peticiones del estado de los pedidos, gestión de inventarios, soporte postventa incluyendo garantía del servicio, etc. El intercambio de la información del diseño, configuración, procesos y calidad también es posible para coordinar entre diferentes organizaciones las actividades de fabricación. Los participantes en los mercados electrónicos pueden guardar los datos en gran variedad de sistemas de bases de datos. Puede que estos sistemas utilicen diferentes modelos, formatos y tipos de datos. Además, puede que haya diferencias semánticas (sistema métrico frente a sistema imperial británico, distintas divisas, etc.) en los datos. Las normas para los mercados electrónicos incluyen los métodos para envolver cada uno de estos sistemas heterogéneos con un esquema XML. Estas envolturas XML forman la base de una vista unificada de los datos para todos los participantes del mercado. El protocolo simple de acceso a objetos (Simple Object Access Protocol, SOAP) es una norma para llamadas a procedimientos remotos que usa XML para codificar los datos (tanto los parámetros como los resultados) y usa HTTP como protocolo de transporte; es decir, las llamadas a procedimientos se transforman en solicitudes HTTP. SOAP está apoyado por el Consorcio World Wide Web (World Wide Web Consortium, W3C) y ha logrado una amplia aceptación en la industria. SOAP puede usarse en gran variedad de aplicaciones. Por ejemplo, en el comercio electrónico entre empresas, comercio electrónico, las aplicaciones que se ejecutan en un sitio pueden tener acceso a los datos de otros sitios y ejecutar acciones mediante SOAP. SOAP y los servicios Web se tratan con más detalle en el Apartado 10.7.3. 23.4 Migración de aplicaciones

Los sistemas heredados son sistemas de aplicaciones de generaciones anteriores en uso, pero que la organización desea sustituir por otros. Por ejemplo, muchas organizaciones desarrollaron aplicaciones, pero pueden decidir sustituirlas por productos comerciales. En algunos casos un sistema heredado puede usar tecnologías antiguas incompatibles con las normas y sistemas de la generación actual. Algunos sistemas heredados operativos tienen varias décadas y se basan hoy en tecnologías tales como bases de datos de red o jerárquicas, o usan Cobol y sistemas de ficheros sin base de datos. Estos sistemas pueden contener datos valiosos y pueden dar soporte a aplicaciones críticas. El reemplazamiento de las aplicaciones heredadas por aplicaciones más modernas suele resultar costoso tanto en términos de tiempo como de dinero, dado que suelen ser de tamaño muy grande, con millones de líneas de código desarrolladas por equipos de programadores a lo largo de varias décadas. Contienen grandes cantidades de datos que se deban trasladar a la nueva aplicación, que puede usar un esquema totalmente diferente. El cambio de la aplicación vieja a la nueva implica volver a formar a una gran cantidad de personal. El cambio se debe hacer generalmente sin ninguna interrupción, con los datos incorporados en el viejo sistema disponibles también en el nuevo. Muchas organizaciones intentan evitar reemplazar los sistemas heredados, intentando interoperar con los nuevos sistema. Un enfoque usado para interoperar entre las bases de datos relacionales y las bases de datos heredadas es crear una capa, denominada envoltura, por encima de los sistemas heredados que pueda hacer que el sistema heredado parezca una bases de datos relacional. Puede que la envoltura ofrezca soporte para ODBC u otras normas de interconexión como OLE-DB, que puede usarse para consultar y actualizar el sistema heredado. La envoltura es responsable de la conversión de las consultas y actualizaciones relacionales en consultas y actualizaciones del sistema heredado. Cuando una organización decide sustituir un sistema heredado por otro nuevo puede seguir un proceso denominado ingeniería inversa, que consiste en repasar el código del sistema heredado para obtener el diseño de los esquemas del modelo de datos requerido (como puede ser el modelo E-R o un modelo de datos orientado a los objetos). La ingeniería inversa también examina el código para averiguar los procedimientos y los procesos que se implementan con objeto de obtener un modelo de alto nivel del sistema. La ingeniería inversa es necesaria porque los sistemas heredados no suelen tener documentación de alto nivel de sus esquemas ni del diseño global de sus sistemas. Al presentarse el diseño de un nuevo sistema los desarrolladores repasan el diseño de modo que pueda mejorarse en lugar de volver a implementarlo tal como estaba. Se necesita una amplia labor de codificación para dar soporte

www.detodoprogramacion.com


Términos de repaso

749

a toda la funcionalidad (como pueden ser las interfaces de usuario y los sistemas de información) que proporcionaba el sistema heredado. El proceso completo se denomina reingeniería. Cuando se ha creado y probado el sistema nuevo hay que llenarlo con los datos del sistema heredado y todas las actividades posteriores se deben realizar en el sistema nuevo. No obstante, la transición abrupta al sistema nuevo, que se denomina enfoque gran explosión, conlleva varios riesgos. En primer lugar, puede que los usuarios no estén familiarizados con las interfaces del sistema nuevo. En segundo lugar, puede haber fallos o problemas de rendimiento en el sistema nuevo que no se hayan descubierto al probarlo. Estos problemas pueden provocar grandes pérdidas a las empresas, dado que puede resultar gravemente afectada su capacidad para realizar transacciones críticas como las compras y las ventas. En algunos casos extremos se ha llegado a abandonar el sistema nuevo y se ha vuelto a usar el sistema heredado después de que fallara el intento de cambio. Un enfoque alternativo, denominado enfoque incremental, sustituye la funcionalidad del sistema heredado de manera incremental. Por ejemplo, puede que las nuevas interfaces de usuario se utilicen con el sistema antiguo en el dorsal, o viceversa. Otra opción es usar el sistema nuevo sólo para algunas funcionalidades que puedan desgajarse del sistema heredado. En cualquier caso, los sistemas heredados y los nuevos coexisten durante algún tiempo. Por tanto, existe una necesidad de desarrollo y uso de envolturas del sistema heredado para proporcionar la funcionalidad requerida para interoperar con el sistema nuevo. Este enfoque, por tanto, tiene asociado un coste de desarrollo superior. 23.5 Resumen

• El ajuste de los parámetros del sistema de bases de datos, así como el diseño de nivel superior de la base de datos—como pueden ser el esquema, los índices y las transacciones—resultan importantes para lograr un buen rendimiento. La mejor forma de realizar el ajuste es identificar los cuellos de botella y eliminarlos. • Las pruebas de rendimiento desempeñan un papel importante en las comparaciones entre sistemas de bases de datos, especialmente a medida que cumplen cada vez más las normas. El conjunto de pruebas TPC se usa mucho y las diferentes pruebas TPC resultan útiles para la comparación del rendimiento de las bases de datos con diferentes cargas de trabajo. • Las normas son importantes debido a la complejidad de los sistemas de bases de datos y a la necesidad de interoperatividad. Hay normas formales para SQL. Las normas de facto, como ODBC y JDBC, y las normas adoptadas por grupos de empresas, como CORBA, han desempeñado un papel importante en el crecimiento de los sistemas de bases de datos cliente–servidor. Hay grupos de empresas desarrollando normas para las bases de datos orientadas a objetos, como ODMG. • Los sistemas heredados son sistemas basados en tecnologías de generaciones anteriores como las bases de datos no relacionales o, incluso, directamente en sistemas de archivos. Suele ser importante el establecimiento de las interfaces entre los sistemas heredados y los sistemas de última generación cuando ejecutan sistemas de misión crítica. La migración desde los sistemas heredados a los sistemas de última generación debe realizarse con cuidado para evitar interrupciones, que pueden resultar muy costosas. Términos de repaso

• Ajuste del rendimiento.

• Ajuste del esquema.

• Cuellos de botella.

• Ajuste de los índices.

• Sistemas de colas.

• Vistas materializadas.

• Parámetros ajustables.

• Mantenimiento inmediato de vistas.

• Ajuste del hardware.

• Mantenimiento diferido de vistas.

• Regla de los cinco minutos.

• Ajuste de las transacciones.

• Regla del minuto.

• Mejora de la orientación del conjunto.

www.detodoprogramacion.com


750

Capítulo 23

Desarrollo avanzado de aplicaciones

• Procesamiento de transacciones por minilotes. • Simulación del rendimiento. • Pruebas de rendimiento. • Tiempo de servicio. • Tiempo hasta su finalización. • Clases de aplicaciones de bases de datos. • Pruebas TPC: ¤ ¤ ¤ ¤ ¤ ¤ ¤

TPC-A. TPC-B. TPC-C. TPC-D. TPC-R. TPC-H. TPC-W.

¤ OO7. • Normalización. ¤ Normas formales. ¤ Normas de facto. ¤ Normas anticipativas. ¤ Normas reaccionarias. • Normas de conectividad para bases de datos. ¤ ODBC. ¤ OLE-DB. ¤ Normas X/Open XA. • Normas de bases de datos de objetos: ¤ ODMG. ¤ CORBA. • Normas basadas en XML.

• Interacciones Web por segundo.

• Sistemas heredados.

• Pruebas OODB:

• Ingeniería inversa. • Reingeniería.

¤ OO1. Ejercicios prácticos

23.1 Muchas aplicaciones necesitan generar los números de secuencia para cada transacción. a. Si un contador de secuencia se bloquea en dos fases, puede producirse un cuello de botella en la concurrencia. Explíquese por qué puede ocurrir. b. Muchos sistemas de bases de datos soportan contadores de secuencia predefinidos, que no se bloquean en dos fases; cuando una transacción solicita un número de secuencia, se bloquea el contador, se incrementa y se desbloquea. I . Explíquese cómo pueden mejorar concurrencia estos contadores. II . Explíquese por qué puede haber ausencias en los números de secuencia del conjunto final de transacciones comprometidas. 23.2 Supóngase una relación r(a, b, c). a. Dese un ejemplo de una situación bajo la cual el rendimiento de las consultas de selección con igualdad sobre el atributo a pueda verse seriamente afectada dependiendo de cómo se agrupe r. b. Supóngase que también se tengan consultas de selección de rangos sobre el atributo b. ¿Se puede agrupar r de forma que las consultas de selección con igualdad sobre r.a y las de rango sobre r.b puedan resolverse eficientemente? Explíquese la respuesta. c. Si no es posible este agrupamiento, sugiérase cómo se pueden ejecutar eficientemente ambos tipos de preguntas eligiendo índices apropiados, asumiendo que la base de datos soporta sólo planes con índices (es decir, si toda la información requerida para una consulta está disponible en un índice, la base de datos puede generar un plan que utilice el índice pero sin acceder a la relación). 23.3 Supóngase que una aplicación de la base de datos parece no tener cuellos de botella; es decir, la CPU y el uso de disco son altos y prácticamente todas las consultas de la base de datos están equilibradas. ¿Significa esto que la aplicación no se puede ajustar mejor? Explíquese la respuesta. 23.4 Supóngase que un sistema ejecuta tres tipos de transacciones. Las transacciones de tipo A se ejecutan a razón de cincuenta por segundo, las transacciones de tipo B se ejecutan a cien por segundo y las transacciones de tipo C se ejecutan a doscientas por segundo. Supóngase que la mezcla de transacciones tiene un veinticinco por ciento del tipo A, otro veinticinco por ciento del tipo B y un cincuenta por ciento del tipo C.

www.detodoprogramacion.com


Notas bibliográficas

751

a. ¿Cuál es la productividad promedio de transacciones del sistema, suponiendo que no hay interferencia entre las transacciones? b. ¿Qué factores pueden generar interferencias entre las transacciones de los diferentes tipos, haciendo que la productividad calculada sea incorrecta? 23.5 Indíquense algunas ventajas e inconvenientes de las normas anticipativas frente a las normas reaccionarias. Ejercicios

23.6 Determínese toda la información de rendimiento que proporciona su sistema preferido de bases de datos. Búsquese por lo menos lo siguiente: las consultas que se están ejecutando actualmente o ejecutado recientemente, los recursos que consumió (CPU y E/S) cada una de ellas, la fracción de peticiones que dieron lugar fallos de página en memoria intermedia (para cada consulta, si está disponible) y los bloqueos que tienen un alto grado de la contención. También se puede conseguir la información sobre el uso de la CPU y de E/S del sistema operativo. 23.7

a. ¿Cuáles son los tres niveles principales en los que se puede ajustar un sistema de bases de datos para mejorar su rendimiento? b. Propónganse dos ejemplos del modo en que se puede realizar el ajuste para cada uno de los niveles.

23.8 Al realizar ajuste de rendimiento, ¿se ajustaría primero el hardware (añadiendo discos o memoria) o las transacciones (añadiendo índices o vistas materializadas)? Explíquese la respuesta. 23.9 Supóngase que una aplicación con transacciones por cada acceso y actualización de una única tupla en una relación muy grande almacenada en una organización de archivo B+ . Asúmase que todos los nodos internos del árbol B+ están en memoria, pero solamente una fracción muy pequeña de las páginas hoja puede caber en memoria. Explíquese cómo calcular el número mínimo de discos requeridos para permitir una carga de trabajo de 1.000 transacciones por segundo. Calcúlese también el número requerido de discos usando los valores de los parámetros de disco del Apartado 11.2. 23.10 ¿Cuál es el motivo para separar una transacción de larga duración en una serie de transacciones más cortas? ¿Qué problemas pueden surgir como consecuencia y cómo pueden evitarse? 23.11 Supóngase que el precio de la memoria cae a la mitad y la velocidad de acceso al disco (número de accesos por segundo) se dobla mientras el resto de los factores permanecen iguales. ¿Cuál sería el efecto de este cambio en las reglas de los cinco minutos y del minuto? 23.12 Indíquense al menos cuatro de las características de las pruebas TPC que ayudan a hacerlas medidas realistas y dignas de confianza. 23.13 ¿Por qué se sustituyó TPC-D por las pruebas de rendimiento TPC-H y TPC-R? 23.14 Determínense las características de la aplicación que ayudarían a decidir TPC-C, TPC-H o TPC-R para modelar mejor la aplicación. Notas bibliográ cas

Una de las primeras propuestas de pruebas de calidad de sistemas de bases de datos (la prueba Wisconsin) la realizaron Bitton et al. [1983]. Las pruebas TPC-A, -B y -C se describen en Gray [1991]. Una versión en línea de todas las descripciones de los pruebas TPC, así como de los resultados de estos pruebas, está disponible en World Wide Web en el URL www.tpc.org; el sitio también contiene información actualizada sobre nuevas propuestas de pruebas. Poess y Floyd [2000] dan una introducción de las pruebas TPC-H, TPC-Ry TPC-W. La prueba OO1 para OODBs se describe en Cattell y Skeen [1992]; la prueba OO7 se describe en Carey et al. [1993].

www.detodoprogramacion.com


752

Capítulo 23

Desarrollo avanzado de aplicaciones

Kleinrock [1975] y Kleinrock [1976] es un libro de texto popular de dos volúmenes sobre la teoría de colas. Shasha y Bonnet [2002] ofrecen un tratamiento detallado del ajuste de bases de datos. O’Neil y O’Neil [2000] ofrece un tratamiento de libro de texto de muy buena calidad de la medida del rendimiento y de su ajuste. Las reglas de los cinco minutos y del minuto se describen en Gray y Putzolu [1987] y en Gray y Graefe [1997]. La selección de índices y de vistas materializadas se abordan en Ross et al. [1996], Labio et al. [1997], Gupta [1997], Chaudhuri y Narasayya [1997], Agrawal et al. [2000] y en Mistry et al. [2001]. En Zilio et al. [2004], Dageville et al. [2004] y Agrawal et al. [2004] se describe el ajuste en DB2 de IBM, Oracle y SQL Serverde Microsoft. Para hallar referencias a las normas de SQL véanse las notas bibliográficas del Capítulo 3. Se puede hallar información sobre ODBC, OLE-DB, ADO y ADO.NETen el sitio Web www.microsoft.com/data y en varios libros sobre el tema que pueden encontrarse mediante www.amazon.com. La norma ODMG 3.0 se define en La revista Sigmod Record de ACM, que se publica trimestralmente, tiene una sección fija sobre las normas de bases de datos. Se halla disponible en línea gran cantidad de información sobre las normas basadas en XML en el sitio Web www.w3c.org. La información sobre RosettaNet se puede encontrar en www.rosettanet.org. La reingeniería de procesos de negocio se trata en Cook [1996]. Umar [1997] trata la reingeniería y aspectos del trabajo con sistemas heredados.

www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

24

Tipos de datos avanzados y nuevas aplicaciones

Durante la mayor parte de la historia de las bases de datos, sus tipos de datos eran relativamente sencillos, y esto se reflejó en las primeras versiones de SQL. En los últimos años, sin embargo, ha habido una necesidad creciente de manejar tipos de datos nuevos en las bases de datos, como los datos temporales, los datos espaciales y los datos multimedia. Otra tendencia importante de la última década ha creado sus propios problemas: el auge de la informática móvil, que comenzó con las computadoras portátiles y las agendas de bolsillo, se ha extendido en tiempos más recientes a los teléfonos móviles con capacidad de procesamiento y una gran variedad de computadoras portátiles, que se usan cada vez más en aplicaciones comerciales. En este capítulo se estudian varios tipos nuevos de datos y también se estudian los problemas de las bases de datos relacionados con la informática móvil. 24.1 Motivación

Antes de abordar a fondo cada uno de los temas se resumirá la motivación de cada uno de estos tipos de datos y algunos problemas importantes del trabajo con ellos. • Datos temporales. La mayor parte de los sistemas de bases de datos modelan un estado actual; por ejemplo, los clientes actuales, los estudiantes actuales y los cursos que se están ofertando. En muchas aplicaciones es muy importante almacenar y recuperar la información sobre estados anteriores. La información histórica puede incorporarse de manera manual en el diseño del esquema. No obstante, la tarea se simplifica mucho con el soporte de los datos temporales en las bases de datos, lo cual se estudia en el Apartado 24.2. • Datos espaciales. Entre los datos espaciales están los datos geográficos, como los datos y la información asociada a ellos, y los datos de diseño asistido por computadora, como los diseños de circuitos integrados o los diseños de edificios. Las aplicaciones de datos espaciales en un principio almacenaban los datos como archivos de un sistema de archivos, igual que las aplicaciones de negocios de las primeras generaciones. Pero, a medida que la complejidad y el volumen de los datos, y el número de usuarios, han aumentado, se han mostrado insuficientes para cubrir las necesidades de muchas aplicaciones que usan datos espaciales los enfoques ad hoc para almacenar y recuperar los datos en un sistema de archivos. Las aplicaciones de datos espaciales necesitan los servicios ofrecidos por los sistemas de bases de datos — en especial, la posibilidad de almacenar y consultar de manera eficiente grandes cantidades de datos. Algunas aplicaciones también pueden necesitar otras características de las bases de datos, como las actualizaciones atómicas de parte de los datos almacenados, la durabilidad y el control de concurrencia. En el Apartado 24.3 se estudian las ampliaciones de los sistemas de bases de datos tradicionales necesarias para que soporten los datos espaciales. 753

www.detodoprogramacion.com


754

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

• Datos multimedia. En el Apartado 24.4 se estudian las características necesarias en los sistemas de bases de datos que almacenan datos multimedia como los datos de imágenes, de vídeo o de audio. La principal característica que diferencia a los datos de vídeo y de audio es que la visualización de éstos exige la recuperación a una velocidad predeterminada constante; por tanto, esos datos se denominan datos de medios continuos. • Bases de datos móviles. En el Apartado 24.5 se estudian los requisitos para las bases de datos de la nueva generación de sistemas informáticos portátiles, como las computadoras portátiles y los dispositivos informáticos de bolsillo, que se conectan con las estaciones base mediante redes de comunicación digitales inalámbricas. Estas computadoras necesitan poder operar mientras se hallan desconectadas de la red, a diferencia de los sistemas distribuidos de bases de datos estudiados en el Capítulo 22. También tienen una capacidad de almacenamiento limitada y, por tanto, necesitan técnicas especiales para la administración de la memoria. 24.2 El tiempo en las bases de datos

Las bases de datos modelan el estado de algunos aspectos del mundo real. Generalmente, las bases de datos sólo modelan un estado—el estado actual—del mundo real, y no almacenan información sobre estados anteriores, salvo posiblemente como registro de auditoría. Cuando se modifica el estado del mundo real, se actualiza la base de datos y se pierde la información sobre el estado anterior. Sin embargo, en muchas aplicaciones es importante almacenar y recuperar información sobre estados anteriores. Por ejemplo, una base de datos sobre pacientes debe almacenar información sobre el historial médico de cada paciente. El sistema de control de una fábrica puede almacenar información sobre las lecturas actuales y anteriores de los sensores de la fábrica para su análisis. Las bases de datos que almacenan información sobre los estados del mundo real a lo largo del tiempo se denominan bases de datos temporales. Al considerar el problema del tiempo en los sistemas de bases de datos se distingue entre el tiempo medido por el sistema y el tiempo observado en el mundo real. El tiempo válido de un hecho es el conjunto de intervalos de tiempo en el que el hecho es cierto en el mundo real. El tiempo de transacción de un hecho es el intervalo de tiempo en el que el hecho es actual en el sistema de bases de datos. Este segundo tiempo se basa en el orden de secuenciación de las transacciones y el sistema lo genera de manera automática. Hay que tener en cuenta que los intervalos de tiempo válidos, que son un concepto del tiempo real, no pueden generarse de manera automática y deben proporcionarse al sistema. Una relación temporal es una relación en la que cada tupla tiene un tiempo asociado en que es verdadera; el tiempo puede ser la hora real o el tiempo asociado a la transacción. Por supuesto, pueden almacenarse ambos, en cuyo caso la relación se denomina relación bitemporal. La Figura 24.1 muestra un ejemplo de relación temporal. Para simplificar la representación cada tupla tiene un asociado un único intervalo temporal; así, cada tupla se representa una vez para cada intervalo de tiempo disjunto en que es cierta. Los intervalos se muestran aquí como pares de atributos de y a; una implementación real tendría un tipo estructurado, acaso denominado Intervalo, que contuviera los dos campos. Obsérvese que algunas de la tuplas tienen un asterisco (“*”) en la columna temporal a; esos asteriscos indican que la tupla es verdadera hasta que se modifique el valor de la columna temporal a; así, la tupla es cierta en el momento actual. Aunque los tiempos se muestran en forma textual, se almacenan internamente de una manera más compacta, como el número de segundos desde algún momento de una fecha fija (como las 12:00 A.M., 1 de enero, 1900) que puede volver a traducirse a la forma textual normal. 24.2.1 Especi cación del tiempo en SQL

El estándar SQL define los tipos date, time y timestamp. El tipo date contiene cuatro cifras para los años (1– 9999), dos para los meses (1–12) y dos más para los días (1–31). El tipo time contiene dos cifras para la hora, dos para los minutos y otras dos para los segundos, además de cifras decimales opcionales. El campo de los segundos puede superar el valor de sesenta para tener en cuenta los segundos extra que se añaden algunos años para corregir las pequeñas variaciones de velocidad en la rotación de la Tierra. El tipo timestamp contiene los campos de date y de time con seis cifras decimales para el campo de los segundos.

www.detodoprogramacion.com


24.2

número_cuenta C -101 C -101 C -215 C -215 C -215 C -217

nombre_sucursal C entro C entro Becerril Becerril Becerril G alapagar Figura 24.1

saldo 500 100 700 900 700 750

de 1/ 1/ 1999 24/ 1/ 1999 2/ 6/ 2000 8/ 8/ 2000 5/ 9/ 2000 5/ 7/ 1999

El tiempo en las bases de datos

9:00 11:30 15:30 10:00 8:00 11:00

a 24/ 1/ 1999 * 8/ 8/ 2000 5/ 9/ 2000 * 1/ 5/ 2000

755

11:30 10:00 8:00 16:00

La relación temporal cuenta.

Como las diferentes partes del mundo tienen horas locales diferentes suele darse la necesidad de especificar la zona horaria junto con la hora. La hora universal coordinada (Universal Coordinated Time, UTC) es un punto estándar de referencia para la especificación de la hora y las horas locales se definen como diferencias respecto a UTC. (La abreviatura estándar es UTC, en lugar de UCT—Universal Coordinated Time en inglés—ya que es una abreviatura de “tiempo universal coordinado (Universal Coordinated Time)” escrito en francés como universel temps coordonné). SQL también soporta dos tipos, time with time zone y timestamp with time zone, que especifican la hora como la hora local más la diferencia de la hora local respecto de UTC. Por ejemplo, la hora podría expresarse en términos de la hora estándar del Este de EE.UU. (U.S. Eastern Standard Time), con una diferencia de −6:00, ya que la hora estándar del Este de Estados Unidos va retrasada seis horas respecto de UTC. SQL soporta un tipo denominado interval, que permite hacer referencia a un periodo de tiempo como puede ser “1 día” o “2 días y 5 horas”, sin especificar la hora concreta en que comienza el periodo. Este concepto se diferencia del concepto de intervalo usado anteriormente, que hace referencia a un intervalo de tiempo con horas de comienzo y de final específicos1 .

24.2.2 Lenguajes de consultas temporales

Las relaciones de base de datos sin información temporal se denominan a veces relaciones instantáneas, ya que reflejan el estado del mundo real en una instantánea. Así, una instantánea de una relación temporal en un momento del tiempo t es el conjunto de tuplas de la relación que son ciertas en el momento t, con los atributos de intervalos de tiempo eliminados. La operación instantánea para una relación temporal da la instantánea de la relación en un momento especificado (o en el momento actual, si no se especifica el momento. Una selección temporal es una selección que implica a los atributos de tiempo; una proyección temporal es una proyección en la que las tuplas de la proyección heredan los valores de tiempo de las tuplas de la relación original. Una reunión temporal es una reunión en que los valores temporales de las tuplas del resultado son la intersección de los valores temporales de las tuplas de las que proceden. Si los valores temporales no se intersecan, esas tuplas se eliminan del resultado. Los predicados precede, solapa y contiene pueden aplicarse a los intervalos; sus significados deben quedar claros. La operación intersección puede aplicarse a dos intervalos, para dar un único intervalo (posiblemente vacío). Sin embargo, la unión de dos intervalos puede que no sea un solo intervalo. Las dependencias funcionales deben usarse con cuidado en las relaciones temporales. Aunque puede que el número de cuenta determine funcionalmente el saldo en cualquier momento, evidentemente el τ saldo puede cambiar con el tiempo. Una dependencia funcional temporal X → Y es válida para un esquema de relación R si, para todos los casos legales r de R, todas las instantáneas de r satisfacen la dependencia funcional X → Y . Se han realizado varias propuestas de ampliación de SQL para mejorar su soporte de los datos temporales, pero al menos hasta SQL:2003 no se ha proporcionado ningún soporte especial para los datos temporales aparte de los tipos de datos relativos a la fecha y hora y sus operaciones. 1. Muchos investigadores de bases de datos temporales consideran que este tipo de datos debería haberse denominado span, ya que no especifica un momento inicial ni un momento final exactos, sino tan sólo el tiempo transcurrido entre los dos.

www.detodoprogramacion.com


756

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

24.3 Datos espaciales y geográ cos

El soporte de los datos espaciales en las bases de datos es importante para el almacenaje, indexado y consulta eficientes de los datos basados en las posiciones espaciales. Por ejemplo, supóngase que se desea almacenar un conjunto de polígonos en una base de datos y consultar la base de datos para hallar todos los polígonos que intersecan un polígono dado. No se pueden usar las estructuras estándares de índices como los árboles B o los índices asociativos para responder de manera eficiente esas consultas. El procesamiento eficiente de esas consultas necesita estructuras de índices de finalidades especiales, como los árboles R (que se estudiarán posteriormente). Dos tipos de datos espaciales son especialmente importantes: • Los datos de diseño asistido por computadora (Computer Aided Design, CAD), que incluyen información espacial sobre el modo en que los objetos—como los edificios, los coches o los aviones — están construidos. Otros ejemplos importantes de bases de datos de diseño asistido por computadora son los diseños de circuitos integrados y de dispositivos electrónicos. • Los datos geográficos como los mapas de carreteras, los mapas de uso de la tierra, los mapas topográficos, los mapas políticos que muestran fronteras, los mapas catastrales, etc. Los sistemas de información geográfica son bases de datos de propósito especial adaptadas para el almacenamiento de datos geográficos. El soporte para los datos geográficos se ha añadido a muchos sistemas de bases de datos, como IBM DB2 Spatial Extender, Informix Spatial Datablade u Oracle Spatial. 24.3.1 Representación de la información geométrica

La Figura 24.2 muestra el modo en que se pueden representar de manera normalizada en las bases de datos varias estructuras geométricas. Hay que destacar aquí que la información geométrica puede representarse de varias maneras diferentes, de las que sólo se describen algunas. Un segmento rectilíneo puede representarse mediante las coordinadas de sus extremos. Por ejemplo, en una bases de datos de mapas, las dos coordenadas de un punto serían su latitud y su longitud. Una línea poligonal (también denominada línea quebrada) consiste en una secuencia conectada de segmentos rectilíneos, y pueden representarse mediante una lista que contenga las coordenadas de los extremos de los segmentos, en secuencia. Se puede representar aproximadamente una curva arbitraria mediante líneas poligonales, dividiendo la curva en una serie de segmentos. Esta representación resulta útil para elementos bidimensionales como las carreteras; en este caso, la anchura de la carretera es lo bastante pequeña en relación con el tamaño de todo el mapa que puede considerarse bidimensional. Algunos sistemas también soportan como primitivas los arcos de circunferencia, lo que permite que las curvas se representen como secuencias de arcos. Los polígonos pueden representarse indicando sus vértices en orden, como en la Figura 24.22 . La lista de los vértices especifica la frontera de cada región poligonal. En una representación alternativa cada polígono puede dividirse en un conjunto de triángulos, como se muestra en la Figura 24.2. Este proceso se denomina triangulación, y se puede triangular cualquier polígono. Se concede un identificador a cada polígono complejo, y cada uno de los triángulos en los que se divide lleva el identificador del polígono. Los círculos y las elipses pueden representarse por los tipos correspondientes, o aproximarse mediante polígonos. Las representaciones de las líneas poligonales o de los polígonos basadas en listas suelen resultar convenientes para el procesamiento de consultas. Esas representaciones que no están en la primera forma normal se usan cuando están soportadas por la base de datos subyacente. Con objeto de que se puedan usar tuplas de tamaño fijo (en la primera forma normal) para la representación de líneas poligonales se puede dar a la línea poligonal o a la curva un identificador, y se puede representar cada segmento como una tupla separada que también lleva el identificador de la línea poligonal o de la curva. De manera parecida, la representación triangulada de los polígonos permite una representación relacional de los polígonos en su primera forma normal. 2. Algunas referencias usan el término polígono cerrado para hacer referencia a lo que aquí se denominan polígonos y se refieren a las líneas poligonales abiertas como polígonos abiertos.

www.detodoprogramacion.com


Datos espaciales y geogrĂĄficos

24.3

757

Figura 24.2

!

"

#

!

$

#

!

%

!

&

"

'

(

)

*

&

RepresentaciĂłn de estructuras geomĂŠtricas.

La representación de los puntos y de los segmentos rectilíneos en el espacio tridimensional es parecida a su representación en el espacio bidimensional, siendo la única diferencia que los puntos tienen un componente z adicional. De manera parecida, la representación de las figuras planas —como los triångulos, los rectångulos y otros polígonos—no cambia mucho cuando se consideran tres dimensiones. Los tetraedros y los paralelepípedos pueden representarse de la misma manera que los triångulos y los rectångulos. Es posible representar poliedros arbitrarios dividiÊndolos en tetraedros, igual que se triangulan los polígonos. TambiÊn se pueden representar indicando las caras, cada una de las cuales es, en sí misma, un polígono, junto con una indicación del lado de la cara que estå por dentro del poliedro. 24.3.2 Bases de datos para diseùo

Los sistemas de diseĂąo asistido por computadora (Computer Aided Design, CAD) tradicionalmente almacenaban los datos en la memoria durante su ediciĂłn u otro tipo de procesamiento y los volvĂ­an a escribir en archivos al final de la sesiĂłn de ediciĂłn. Entre los inconvenientes de este esquema estĂĄn el coste (la complejidad de programaciĂłn y el coste temporal) de transformar los datos de una forma a otra, y la necesidad de leer todo un archivo aunque sĂłlo sea necesaria una parte. Para los diseĂąos de gran tamaĂąo, como el diseĂąo de circuitos integrados a gran escala o el diseĂąo de todo un aviĂłn, puede que resulte imposible guardar en la memoria el diseĂąo completo. Los diseĂąadores de bases de datos orientadas a objetos estaban motivados en gran parte por las necesidades de los sistemas de CAD. Las bases de datos orientadas a objetos representan los componentes del diseĂąo como objetos y las conexiones entre los objetos indican el modo en que estĂĄ estructurado el diseĂąo. Los objetos almacenados en las bases de datos de diseĂąo suelen ser objetos geomĂŠtricos. Entre los objetos geomĂŠtricos bidimensionales sencillos se encuentran los puntos, las lĂ­neas, los triĂĄngulos, los

www.detodoprogramacion.com


758

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

rectángulos y los polígonos en general. Los objetos bidimensionales complejos pueden formarse a partir de objetos sencillos mediante las operaciones de unión, intersección y diferencia. De manera parecida, los objetos tridimensionales complejos pueden formarse a partir de objetos más sencillos como las esferas, los cilindros y los paralelepípedos mediante las operaciones unión, intersección y diferencia, como en la Figura 24.3. Las superficies tridimensionales también pueden representarse mediante modelos de alambres, que esencialmente modelan las superficies como conjuntos de objetos más sencillos, como segmentos rectilíneos, triángulos y rectángulos. Las bases de datos de diseño también almacenan información no espacial sobre los objetos, como el material del que están construidos. Esa información se suele poder modelar mediante técnicas estándar de modelado de datos. Aquí se centrará la atención únicamente en los aspectos espaciales. Al diseñar hay que realizar varias operaciones espaciales. Por ejemplo, puede que el diseñador desee recuperar la parte del diseño que corresponde a una región de interés determinada. Las estructuras espaciales de índices, estudiadas en el Apartado 24.3.5, resultan útiles para estas tareas. Las estructuras espaciales de índices son multidimensionales, trabajan con datos de dos y de tres dimensiones, en vez de trabajar solamente con la sencilla ordenación unidimensional que proporcionan los árboles B+ . Las restricciones de integridad espacial, como “dos tuberías no deben estar en la misma ubicación”, son importantes en las bases de datos de diseño para evitar errores por interferencias. Estos errores suelen producirse si el diseño se realiza a mano y sólo se detectan al construir un prototipo. En consecuencia, estos errores pueden resultar costosos de reparar. El soporte de las bases de datos para las restricciones de integridad espacial ayuda a los usuarios a evitar los errores de diseño, con lo que hacen que el diseño sea consistente. La implementación de esas verificaciones de integridad depende una vez más de la disponibilidad de estructuras multidimensionales de índices eficientes. 24.3.3 Datos geográ cos

Los datos geográficos son de naturaleza espacial, pero se diferencian de los datos de diseño en ciertos aspectos. Los mapas y las imágenes de satélite son ejemplos típicos de datos geográficos. Los mapas pueden proporcionar no sólo información sobre la ubicación—sobre fronteras, ríos y carreteras, por ejemplo— sino también información mucho más detallada asociada con la ubicación, como la elevación, el tipo de suelo, el uso de la tierra y la cantidad anual de lluvia. Los datos geográficos pueden clasificarse en dos tipos: • Datos por líneas. Estos datos consisten en mapas de bits o en mapas de píxeles en dos o más dimensiones. Un ejemplo típico de imagen de líneas bidimensional son las imágenes de satélite de cobertura nubosa, en las que cada píxel almacena la visibilidad de nubes en un área concreta. Estos datos pueden ser tridimensionales—por ejemplo, la temperatura a diferentes altitudes en distintas regiones, también medidas con la ayuda de un satélite. El tiempo puede formar otra dimensión — por ejemplo, las medidas de la temperatura superficial en diferentes momentos. Las bases de datos de diseño no suelen almacenar datos por líneas.

(a) Diferencia de cilindros Figura 24.3

(b) Unión de cilindros

Objetos tridimensionales complejos.

www.detodoprogramacion.com


24.3

Datos espaciales y geográficos

759

• Datos vectoriales. Los datos vectoriales están formados a partir de objetos geométricos básicos como los puntos, los segmentos rectilíneos, los triángulos y otros polígonos en dos dimensiones y los cilindros, las esferas, los paralelepípedos y otros poliedros en tres dimensiones. Los datos cartográficos suelen representarse en formato vectorial. Los ríos y las carreteras pueden representarse como uniones de varios segmentos rectilíneos. Los estados y los países pueden representarse como polígonos. La información topológica como la altura puede representarse mediante una superficie dividida en polígonos que cubren las regiones de igual altura, con un valor de altura asociado a cada polígono. 24.3.3.1 Representación de los datos geográ cos

Los accidentes geográficos, como los estados y los grandes lagos, se representan como polígonos complejos. Algunos accidentes, como los ríos, pueden representarse como curvas complejas o como polígonos complejos, en función de si su anchura es importante o no. La información geográfica relativa a las regiones, como la cantidad anual de lluvia, puede representarse como un array — es decir, en forma de líneas. Para reducir el espacio necesario, el array se puede almacenar de manera comprimida. En el Apartado 24.3.5 se estudia una representación alternativa de estas arrays mediante una estructura de datos denominada árbol cuadrático. Como se indicó en el Apartado 24.3.3, se puede representar la información regional en forma vectorial usando polígonos, cada uno de los cuales es una región en la que el valor del array es el mismo. La representación vectorial es más compacta que la de líneas en algunas aplicaciones. También es más precisa para algunas tareas, como el dibujo de carreteras, en que la división de la región en píxeles (que pueden ser bastante grandes) lleva a una pérdida de precisión en la información de ubicación. No obstante, la representación vectorial resulta inadecuada para las aplicaciones en que los datos se basan en líneas de manera intrínseca, como las imágenes de satélite. 24.3.3.2 Aplicaciones de los datos geográ cos

Las bases de datos geográficas tienen gran variedad de usos, incluidos los servicios de mapas en línea, los sistemas de navegación para vehículos, la información de redes de distribución para las empresas de servicios públicos como son los sistemas de telefonía, electricidad y suministro de agua y la información de uso de la tierra para ecologistas y planificadores. Los servicios de mapas de carreteras basados en Web constituyen una aplicación muy usada de datos cartográficos. En su nivel más sencillo estos sistemas pueden usarse para generar mapas de carreteras en línea de la región deseada. Una ventaja importante de los mapas interactivos es que resulta sencillo dimensionar los mapas al tamaño deseado—es decir, acercarse y alejarse para ubicar los accidentes importantes. Los servicios de mapas de carretera también almacenan información sobre carreteras y servicios, como el trazado de las carreteras, los límites de velocidad, las condiciones de las vías, las conexiones entre carreteras y los tramos de sentido único. Con esta información adicional sobre las carreteras se pueden usar los mapas para obtener indicaciones para desplazarse de un sitio a otro y para localizar, por ejemplo, hoteles, gasolineras o restaurantes con las ofertas y gamas de precios deseadas. Los sistemas de navegación para los vehículos son sistemas montados en automóviles que proporcionan mapas de carreteras y servicios para la planificación de los viajes. Un añadido útil a los sistemas de información geográfica móviles como los sistemas de navegación de los vehículos es una unidad del sistema de posicionamiento global (Global Positioning System, GPS), que usa la información emitida por los satélites GPS para hallar la ubicación actual con una precisión de decenas de metros. Con estos sistemas el conductor no puede perderse nunca3 —la unidad GPS halla la ubicación en términos de latitud, longitud y elevación y el sistema de navegación puede consultar la base de datos geográfica para hallar el lugar en que se encuentra y la carretera en que se halla el vehículo. Las bases de datos geográficas para información de utilidad pública se están volviendo cada vez más importantes a medida que crece la red de cables y tuberías enterrados. Sin mapas detallados las obras realizadas por una empresa de servicio público pueden dañar los cables de otra, lo que daría lugar a una 3. Bueno, ¡casi nunca!

www.detodoprogramacion.com


760

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

interrupción del servicio a gran escala. Las bases de datos geográficas, junto con los sistemas precisos de determinación de la posición, pueden ayudar a evitar estos problemas. Hasta ahora se ha explicado el motivo de que las bases de datos espaciales resulten útiles. En el resto del apartado se estudiarán los detalles técnicos, como la representación y el indexado de la información espacial. 24.3.4 Consultas espaciales

Existen varios tipos de consultas con referencia a ubicaciones espaciales. • Las consultas de proximidad solicitan objetos que se hallen cerca de una ubicación especificada. La consulta para hallar todos los restaurantes que se hallan a menos de una distancia dada de un determinado punto es un ejemplo de consulta de proximidad. La consulta de vecino más próximo solicita el objeto que se halla más próximo al punto especificado. Por ejemplo, puede que se desee hallar la gasolinera más cercana. Obsérvese que esta consulta no tiene que especificar un límite para la distancia y, por tanto, se puede formular aunque no se tenga idea de la distancia a la que se halla la gasolinera más próxima. • Las consultas regionales tratan de regiones espaciales. Estas consultas pueden preguntar por objetos que se hallen parcial o totalmente en el interior de la región especificada. Un ejemplo es la consulta para hallar todas las tiendas minoristas dentro de los límites geográficos de una ciudad dada. • Puede que las consultas también soliciten intersecciones y uniones de regiones. Por ejemplo, dada la información regional, como pueden ser la lluvia anual y la densidad de población, una consulta puede solicitar todas las regiones con una baja cantidad de lluvia anual y una elevada densidad de población. Las consultas que calculan las intersecciones de regiones pueden considerarse como si calcularan la reunión espacial de dos relaciones espaciales—por ejemplo, una que represente la cantidad de lluvia y otra que represente la densidad de población—con la ubicación en el papel de atributo de reunión. En general, dadas dos relaciones, cada una de las cuales contiene objetos espaciales, la reunión espacial de las dos relaciones genera, o bien pares de objetos que se intersectan o bien las regiones de intersección de esos pares. Existen diferentes algoritmos de reunión que calculan eficazmente las reuniones espaciales de datos vectoriales. Aunque se pueden usar las reuniones de bucles anidados o de bucles anidados indexados (con índices espaciales), las reuniones de asociación y las reuniones por mezcla–ordenación no pueden usarse con datos espaciales. Los investigadores han propuesto técnicas de reunión basadas en el recorrido coordinado de las estructuras espaciales de los índices de las dos relaciones. Véanse las notas bibliográficas para obtener más información. En general, las consultas de datos espaciales pueden tener una combinación de requisitos espaciales y no espaciales. Por ejemplo, puede que se desee averiguar el restaurante más cercano que tenga menú vegetariano y que cueste menos de diez euros por comida. Dado que los datos espaciales son inherentemente gráficos, se suelen consultar mediante un lenguaje gráfico de consulta. El resultado de esas consultas también se muestra gráficamente, en vez de mostrarse en tablas. El usuario puede realizar varias operaciones con la interfaz, como escoger el área que desea ver (por ejemplo, apuntando y pulsando en los barrios del oeste de Arganzuela), acercarse y alejarse, escoger lo que desea mostrar de acuerdo con las condiciones de selección (por ejemplo, casas con más de tres habitaciones), superponer varios mapas (por ejemplo, las casas con más de tres habitaciones superpuestas sobre un mapa que muestre las zonas con bajas tasas de delincuencia), etc. La interfaz gráfica constituye la parte visible para el usuario. Se han propuesto extensiones de SQL para permitir que las bases de datos relacionales almacenen y recuperen información espacial de manera eficiente y también permitir que las consultas mezclen las condiciones espaciales con las no espaciales. Las extensiones incluyen la autorización de tipos de datos abstractos como las líneas, los polígonos y los mapas de bits y la autorización de condiciones espaciales como contiene o solapa.

www.detodoprogramacion.com


24.3

Datos espaciales y geográficos

761

24.3.5 Índices sobre los datos espaciales

Los índices son necesarios para el acceso eficiente a los datos espaciales. Las estructuras de índices tradicionales, como los índices de asociación y los árboles B, no resultan adecuadas, ya que únicamente trabajan con datos unidimensionales, mientras que los datos espaciales suelen ser de dos o más dimensiones.

24.3.5.1 Los árboles k-d

Para comprender el modo de indexar los datos espaciales que constan de dos o más dimensiones se considera en primer lugar el indexado de los puntos de los datos unidimensionales. Las estructuras arbóreas, como los árboles binarios y los árboles B, operan dividiendo el espacio en partes más pequeñas de manera sucesiva. Por ejemplo, cada nodo interno de un árbol binario divide un intervalo unidimensional en dos. Los puntos que quedan en la partición izquierda van al subárbol izquierdo; los puntos que quedan en la partición de la derecha van al subárbol derecho. En los árboles binarios equilibrados la partición se escoge de modo que, aproximadamente, la mitad de los puntos almacenados en el subárbol caigan en cada partición. De manera parecida, cada nivel de un árbol B divide un intervalo unidimensional en varias partes. Se puede usar esa intuición para crear estructuras arbóreas para el espacio bidimensional, así como para espacios de más dimensiones. Una estructura arbórea denominada árbol k-d fue una de las primeras estructuras usadas para la indexación en varias dimensiones. Cada nivel de un árbol k-d divide el espacio en dos. La división se realiza según una dimensión en el nodo del nivel superior del árbol, según otra dimensión en los nodos del nivel siguiente, etc., alternando cíclicamente las dimensiones. La división se realiza de tal modo que, en cada nodo, aproximadamente la mitad de los puntos almacenados en el subárbol cae a un lado y la otra mitad al otro. La división se detiene cuando un nodo tiene menos puntos que un valor máximo dado. La Figura 24.4 muestra un conjunto de puntos en el espacio bidimensional y una representación en árbol k-d de ese conjunto de puntos. Cada línea corresponde a un nodo del árbol, y el número máximo de puntos en cada nodo hoja se ha definido como uno. Cada línea de la figura (aparte del marco exterior) corresponde a un nodo del árbol k-d. La numeración de las líneas en la figura indica el nivel del árbol en el que aparece el nodo correspondiente. El árbol k-d B extiende el árbol k-d para permitir varios nodos hijo por cada nodo interno, igual que los árboles B extienden los árboles binarios, para reducir la altura del árbol, los árboles k-dB están mejor adaptados al almacenamiento secundario que los árboles k-d.

3

3

2

2

3 Figura 24.4

1

3

División del espacio por un árbol k-d.

www.detodoprogramacion.com


762

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

Figura 24.5

División del espacio por un árbol cuadrático.

24.3.5.2 Árboles cuadráticos

Una representación alternativa de los datos bidimensionales son los árboles cuadráticos. En la Figura 24.5 aparece un ejemplo de la división del espacio mediante un árbol cuadrático. El conjunto de puntos es el mismo que en la Figura 24.4. Cada nodo de un árbol cuadrático está asociado con una región rectangular del espacio. El nodo superior está asociado con todo el espacio objetivo. Cada nodo que no sea un nodo hoja del árbol cuadrático divide su región en cuatro cuadrantes del mismo tamaño y, a su vez, cada uno de esos nodos tiene cuatro nodos hijo correspondientes a los cuatro cuadrantes. Los nodos hoja tienen un número de puntos que varía entre cero y un número máximo fijado. A su vez, si la región correspondiente a un nodo tiene más puntos que el máximo fijado, se crean nodos hijo para ese nodo. En el ejemplo de la Figura 24.5, el número máximo de puntos de cada nodo hoja está fijado en uno. Este tipo de árbol cuadrático se denomina árbol cuadrático PR, para indicar que almacena los puntos y que la división del espacio se basa en regiones, en vez de en el conjunto real de puntos almacenados. Se pueden usar árboles cuadráticos regionales para almacenar información de arrays (de líneas). Cada nodo de los árboles cuadráticos regionales es un nodo hoja si todos los valores del array de la región que abarca son iguales. En caso contrario, se vuelve a subdividir en cuatro nodos hijo con la misma área y es, por tanto, un nodo interno. Cada nodo del árbol cuadrático regional corresponde a un subarray de valores. Los subarrays correspondientes a las hojas contienen un solo elemento del array o varios, todos ellos con el mismo valor. El indexado de los segmentos rectilíneos y de los polígonos presenta problemas nuevos. Hay extensiones de los árboles k-d y de los árboles cuadráticos para esta labor. No obstante, un segmento rectilíneo o un polígono puede cruzar una línea divisoria. Si lo hace, hay que dividirlo y representarlo en cada uno de los subárboles en que aparezcan sus fragmentos. La aparición múltiple de un segmento lineal o de un polígono puede dar lugar a ineficiencias en el almacenamiento, así como a ineficiencias en las consultas. 24.3.5.3 Árboles R

La estructura de almacenamiento denominada árbol R resulta útil para el indexado de objetos como puntos, segmentos de línea, rectángulos y otros polígonos. Un árbol R es una estructura arbórea equilibrada con los objetos indexados almacenados en los nodos hoja, de manera parecida a los árboles B+ . No obstante, en lugar de un rango de valores, se asocia una caja límite con cada nodo del árbol. La caja límite de un nodo hoja es el rectángulo mínimo paralelo a los ejes que contiene todos los objetos almacenados en el nodo hoja. La caja límite de los nodos internos, de manera parecida, es el rectángulo mínimo paralelo a los ejes que contiene las cajas límite de sus nodos hijo. La caja límite de un objeto (como un polígono) viene definida, de manera parecida, como el rectángulo mínimo paralelo a los ejes que contiene al objeto.

www.detodoprogramacion.com


Datos espaciales y geogrĂĄficos

24.3

763

Figura 24.6

Ă rbol R.

Cada nodo interno almacena las cajas límite de los nodos hijo junto con los punteros para los nodos hijo. Cada nodo hijo almacena los objetos indexados y puede que, opcionalmente, almacene las cajas límite de esos objetos; las cajas límite ayudan a acelerar las comprobaciones de solapamientos de los rectångulos con los objetos indexados—si el rectångulo de una consulta no se solapa con la caja límite de un objeto, o se puede solapar tampoco el objeto (si los objetos indexados son rectångulos, por supuesto no hace falta almacenar las cajas límite, ya que son idÊnticas a los rectångulos). La Figura 24.6 muestra el ejemplo de un conjunto de rectångulos (dibujados con línea continua) y de sus cajas límite (dibujadas con línea discontinua) de los nodos de un årbol R para el conjunto de rectångulos. Hay que tener en cuenta que las cajas límite se muestran con espacio adicional en su interior, para hacerlas visibles en el dibujo. En realidad, las cajas son menores y se ajustan fielmente a los objetos que contienen; es decir, cada cara de una caja límite C toca como mínimo uno de los objetos o de las cajas límite que se contienen en C. El årbol R en sí se halla a la derecha de la Figura 24.6. La figura hace referencia a las coordenadas de la caja límite i como CLi . Ahora se verå el modo de implementar las operaciones de búsqueda, inserción y eliminación en los årboles R. • Búsqueda. Como muestra la figura, las cajas límite con nodos hermanos pueden solaparse; en los årboles B+ , los årboles k-d y los årboles cuadråticos, sin embargo, los rangos no se solapan. La búsqueda de objetos que contengan un punto, por tanto, tiene que seguir todos los nodos hijo cuyas cajas limites asociadas contengan el punto; en consecuencia, puede que haya que buscar por varios caminos. De manera parecida, una consulta para buscar todos los objetos que intersecten con uno dado tiene que bajar por todos los nodos en que el rectångulo asociado intersecte al objeto dado. • Inserción. Cuando se inserta un objeto en un årbol R se selecciona un nodo hoja para que lo guarde. Lo ideal sería seleccionar un nodo hoja que tuviera espacio para guardar una nueva entrada, y cuya caja límite contuviera a la caja límite del objeto. Sin embargo, puede que ese nodo no exista; aunque exista, hallarlo puede resultar muy costoso, ya que no es posible hallarlo mediante un solo recorrido desde la raíz. En cada nodo interno se pueden encontrar varios nodos hijo cuyas cajas límite contengan la caja límite del objeto, y hay que explorar cada uno de esos nodos hijo. Por tanto, como norma heurística, en un recorrido desde la raíz, si alguno de los nodos hijo tiene una caja límite que contenga a la caja límite del objeto, el algoritmo del årbol R escoge una de ellas de manera arbitraria. Si ninguno de los nodos hijo satisface esta condición, el algoritmo escoge un nodo hijo cuya caja límite tenga el solapamiento måximo con la caja límite del objeto para continuar el recorrido.

www.detodoprogramacion.com


764

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

Una vez que se ha llegado al nodo hoja, si el nodo ya está lleno, el algoritmo lleva a cabo una división del nodo (y propaga hacia arriba la división si es necesario) de manera muy parecida a la inserción de los árboles B+ . Igual que con la inserción en los árboles B+ , el algoritmo de inserción de los árboles R asegura que el árbol siga equilibrado. Además, asegura que las cajas límite de los nodos hoja, así como los nodos internos, sigan siendo consistentes; es decir, las cajas límite de los nodos hoja contienen todas las cajas limites de los polígonos almacenados en el nodo hoja, mientras que las cajas límite de los nodos internos contienen todas las cajas límite de los nodos hijo. La principal diferencia del procedimiento de inserción con la inserción en los árboles B+ radica en el modo en que se dividen los nodos. En los árboles B+ es posible hallar un valor tal que la mitad de los de las entradas sea menor que el punto medio y la mitad sea mayor que el valor. Esta propiedad no se generaliza más allá de una dimensión; es decir, para más de una dimensión, no siempre es posible dividir las entradas en dos conjuntos tales que sus cajas límite no se solapen. En lugar de eso, como norma heurística, el conjunto de entradas S puede dividirse en dos conjuntos disjuntos S1 y S2 tales que las cajas límite de S1 y S2 tengan un área total mínima; otra norma heurística sería dividir las entradas en dos conjuntos S1 y S2 de modo que S1 y S2 tengan un solapamiento mínimo. Los dos nodos resultantes de la división contendrían las entradas de S1 y S2 , respectivamente. El coste de hallar las divisiones con área total o solapamiento mínimos puede ser elevado, por lo que se usan normas heurísticas más económicas, como la heurística de la división cuadrática (la heurística recibe el nombre del hecho de que toma el cuadrado del tiempo en el número de entradas). La principal diferencia del procedimiento de inserción con la inserción en los árboles B+ radica en el modo en que se dividen los nodos. En los árboles B+ es posible hallar un valor tal que la mitad de los de las entradas sea menor que el punto medio y la mitad sea mayor que el valor. Esta propiedad no se generaliza más allá de una dimensión; es decir, para más de una dimensión, no siempre es posible dividir las entradas en dos conjuntos tales que sus cajas límite no se solapen. En lugar de eso, como norma heurística, el conjunto de entradas S puede dividirse en dos conjuntos disjuntos S1 y S2 tales que las cajas límite de S1 y S2 tengan un área total mínima; otra norma heurística sería dividir las entradas en dos conjuntos S1 y S2 de modo que S1 y S2 tengan un solapamiento mínimo. Los dos nodos resultantes de la división contendrían las entradas de S1 y S2 , respectivamente. El coste de hallar las divisiones con área total o solapamiento mínimos puede ser elevado, por lo que se usan normas heurísticas más económicas, como la heurística de la división cuadrática (la heurística recibe el nombre del hecho de que toma el cuadrado del tiempo en el número de entradas). La heurística de la división cuadrática funciona de esta manera: en primer lugar, selecciona un par de entradas a y b de S tales que al ponerlas en el mismo nodo den lugar a una caja límite con el máximo de espacio desaprovechado; es decir, el área de la caja límite mínima de a y b menos la suma de las áreas de a y b es máxima. La heurística sitúa las entradas a y b en los conjuntos S1 y S2 , respectivamente. Luego añade iterativamente las entradas restantes, una por cada iteración, a uno de los dos conjuntos S1 o S2 . En cada iteración, para cada entrada restante e, ie,1 denota el incremento en el tamaño de la caja límite de S1 si e se añade a S1 e ie,2 denota el incremento correspondiente de S2 . En cada iteración la heurística escoge una de las entradas con la máxima diferencia entre ie,1 e ie,2 y la añade a S1 si ie,1 es menor que ie,2 , y a S2 en caso contrario. Es decir, se escoge en cada iteración una entrada con “preferencia máxima” por S1 o S2 . Las iteraciones se detienen cuando se han asignado todas las entradas o cuando uno de los conjuntos S1 o S2 tiene entradas suficientes como para que todas las demás entradas haya que añadirlas al otro conjunto de modo que los nodos creados a partir de S1 y S2 tengan la ocupación mínima exigida. La heurística añade luego todas las entradas no asignadas al conjunto con menos entradas.

• Eliminación. La eliminación puede llevarse a cabo como si fuera una eliminación de árbol B+ , tomando prestadas las entradas de los nodos hermanos, o mezclando nodos hermanos si un nodo se queda menos lleno de lo exigido. Un enfoque alternativo redistribuye todas las entradas

www.detodoprogramacion.com


24.4

Bases de datos multimedia

765

de los nodos menos llenos de lo necesario a los nodos hermanos, con el objetivo de mejorar el agrupamiento de las entradas en el árbol R. Véanse las referencias bibliográficas para obtener más detalles de las operaciones de inserción y de eliminación en los árboles R, así como de las variantes de los árboles R, denominados árboles R∗ o árboles R+ . La eficiencia del almacenamiento de los árboles R es mayor que la de los árboles k-d y que la de los árboles cuadráticos, ya que cada polígono sólo se almacena una vez, y se puede asegurar que cada nodo está, como mínimo, medio lleno. No obstante, las consultas pueden resultar más lentas, ya que hay que buscar por varios caminos. Las reuniones espaciales son más sencillas con los árboles cuadráticos que con los árboles R, ya que todos los árboles cuadráticos de cada región están divididos de la misma manera. Sin embargo, debido a su mayor eficiencia de almacenamiento, y a su parecido con los árboles B, los árboles R y sus variantes se han hecho populares en los sistemas de bases de datos que soportan datos espaciales.

24.4 Bases de datos multimedia

Los datos multimedia, como las imágenes, el sonido y el vídeo—una modalidad de datos cada vez más popular— se almacenan hoy en día casi siempre fuera de las bases de datos, en sistemas de archivos. Este tipo de almacenamiento no supone ningún problema cuando el número de objetos multimedia es relativamente pequeño, ya que las características proporcionadas por las bases de datos no suelen ser importantes. Sin embargo, las características de las bases de datos se vuelven importantes cuando el número de objetos multimedia almacenados es grande. Aspectos como las actualizaciones transaccionales, las facilidades de consulta y el indexado se vuelven importantes. Los objetos multimedia suelen tener atributos descriptivos, como los que indican su fecha de creación, su creador y la categoría a la que pertenecen. Un enfoque de la creación de una base de datos para esos objetos multimedia es usar las bases de datos para almacenar los atributos descriptivos y realizar un seguimiento de los archivos en los que se almacenan los objetos multimedia. Sin embargo, el almacenamiento de los objetos multimedia fuera de la base de datos hace más difícil proporcionar la funcionalidad de la base de datos, como el indexado con base en el contenido real de datos multimedia. También puede llevar a inconsistencias, como que un archivo esté registrado en la base de datos pero que sus contenidos falten, o viceversa. Por tanto, resulta deseable almacenar los propios datos en la base de datos. Hay que abordar varios aspectos si se pretende almacenar los datos multimedia en una base de datos. • La base de datos debe soportar objetos de gran tamaño, ya que los datos multimedia como los vídeos pueden ocupar varios gigabytes de espacio de almacenamiento. Los objetos de mayor tamaño pueden dividirse en fragmentos menores y almacenarse en la base de datos. De manera alternativa, los objetos multimedia pueden almacenarse en un sistema de archivos, pero la base de datos puede contener un puntero hacia el objeto; el puntero suele ser un nombre de archivo. El estándar SQL/MED (MED significa Management of External Data, gestión de datos externos) permite que los datos externos, como los archivos, se traten como si formaran parte de la base de datos. Con SQL/MED parece que los objetos son parte de la base de datos, pero pueden almacenarse externamente. Los formatos de los datos multimedia se estudian en el Apartado 24.4.1. • La recuperación de algunos tipos de datos, como los de sonido y los de vídeo, tiene la exigencia de que la entrega de los datos debe realizarse a una velocidad constante garantizada. Estos datos se denominan a veces datos isócronos o datos de medios continuos. Por ejemplo, si los datos de sonido no se proporcionan a tiempo, habrá saltos en el sonido. Si los datos se proporcionan demasiado deprisa, se pueden desbordar las memorias intermedias, lo que dará lugar a la pérdida de datos. Los datos de medios continuos se estudian en el Apartado 24.4.2.

www.detodoprogramacion.com


766

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

• La recuperación basada en la semejanza es necesaria en muchas aplicaciones de bases de datos multimedia. Por ejemplo, en una base de datos que almacene imágenes de huellas digitales, se proporciona una consulta de la imagen de una huella dactilar y hay que recuperar las huellas dactilares de la base de datos que sean parecidas a la huella dactilar de la consulta. Las estructuras de índices como los árboles B+ y los árboles R no se pueden usar para esta finalidad; hay que crear estructuras especiales de índices. La recuperación basada en el parecido se estudia en el Apartado 24.4.3 24.4.1 Formatos de datos multimedia

Debido al gran número de bytes necesarios para representar los datos multimedia es fundamental que se almacenen y transmitan de manera comprimida. Para los datos de imágenes el formato más usado es JPEG, que recibe su nombre del organismo de normalización que lo creó: el grupo conjunto de expertos en imágenes (Joint Picture Experts Group). Se pueden almacenar los datos de vídeo codificando cada fotograma de vídeo en formato JPEG, pero esa codificación supone un desperdicio, ya que los fotogramas de vídeo sucesivos suelen ser casi iguales. El grupo de expertos en películas (Moving Picture Experts Group) desarrolló la serie de estándares MPEG para codificar los datos de vídeo y de sonido; estas codificaciones aprovechan las similitudes de las secuencias de fotogramas para conseguir un grado de compresión mayor. El estándar MPEG-1 almacena un minuto de vídeo y sonido a treinta fotogramas por segundo en unos 12.5 megabytes (en comparación con los aproximadamente 75 megabytes sólo para vídeo en JPEG). No obstante, la codificación MPEG-1 introduce alguna pérdida de calidad del vídeo, a un nivel aproximadamente equivalente al de las cintas de vídeo VHS. El estándar MPEG-2 se diseñó para los sistemas de radiodifusión digitales y para los discos de vídeo digitales (DVD); sólo introduce una pérdida de calidad de vídeo despreciable. MPEG-2 comprime un minuto de vídeo y de sonido en aproximadamente 17 megabytes. MPEG-4 proporciona técnicas de mayor compresión de vídeo con ancho de banda variable para proporcionar la difusión de vídeo en redes con un amplio rango de anchos de banda. Se usan varios estándares competidores para la codificación de sonido, entre ellos MP3 (que significa MPEG-1 Capa 3), RealAudio y otros formatos. 24.4.2 Datos de medios continuos

Los tipos más importantes de datos de medios continuos son los datos de vídeo y los de sonido (por ejemplo, una base de datos de películas). Los sistemas de medios continuos se caracterizan por sus requisitos de entrega de información en tiempo real: • Los datos deben entregarse lo bastante rápido como para que no haya saltos en el resultado de sonido o de vídeo. • Los datos deben entregarse a una velocidad que no cause un desbordamiento de las memorias intermedias del sistema. • La sincronización entre los distintos flujos de datos debe conservarse. Esta necesidad surge, por ejemplo, cuando el vídeo de una persona que habla muestra sus labios moviéndose de manera sincronizada con el sonido de su voz. Para proporcionar los datos de manera predecible en el momento correcto a un gran número de consumidores de los datos la captura de los datos desde el disco debe coordinarse cuidadosamente. Generalmente los datos se capturan en ciclos periódicos. En cada ciclo, digamos de n segundos, se capturan n segundos de datos para cada consumidor y se almacenan en las memorias intermedias, mientras los datos capturados en el ciclo anterior se envían a los consumidores desde las memorias intermedias. El periodo de los ciclos es un compromiso: un periodo corto usa menos memoria pero necesita más movimientos del brazo del disco, lo que supone un desperdicio de recursos, mientras que un periodo largo reduce el movimiento del brazo del disco pero aumenta las necesidades de memoria y puede retrasar la entrega inicial de datos. Cuando llega una nueva solicitud entra en acción el control de admisión: es decir, el sistema comprueba si se puede satisfacer la solicitud con los recursos disponibles (en cada periodo); si es así, se admite; en caso contrario, se rechaza.

www.detodoprogramacion.com


24.5

Computadoras portátiles y bases de datos personales

767

La extensa investigación realizada sobre la entrega de datos de medios continuos ha tratado aspectos como el manejo de arrays de discos y el tratamiento de los fallos de los discos. Véanse las referencias bibliográficas para obtener más detalles. Varios fabricantes ofrecen servidores de vídeo bajo demanda. Los sistemas actuales están basados en los sistemas de archivos, ya que los sistemas de bases de datos existentes no proporcionan la respuesta en tiempo real que necesitan estas aplicaciones. La arquitectura básica de un sistema de vídeo bajo demanda comprende: • Servidor de vídeo. Los datos multimedia se almacenan en varios discos (generalmente en una configuración RAID). Puede que los sistemas que contienen un gran volumen de datos utilicen medios de almacenamiento terciario para los datos a los que se tiene acceso con menor frecuencia. • Terminales. Los datos multimedia se examinan mediante varios dispositivos, colectivamente denominados terminales. Ejemplos son las computadoras personales y los televisores conectados a una computadora pequeña y de coste reducido denominada microcomputadora. • Red. La transmisión de los datos multimedia desde el servidor hasta los terminales necesita una red de gran capacidad. El servicio de vídeo bajo demanda en redes de cable está disponible en muchos lugares actualmente y acabará siendo ubicuo, igual que lo son ahora la televisión por ondas hercianas y la televisión por cable. 24.4.3 Recuperación basada en la semejanza

En muchas aplicaciones multimedia los datos sólo se describen en la base de datos de manera aproximada. Un ejemplo son los datos de huellas dactilares del Apartado 24.4. Otros ejemplos son: • Datos gráficos. Dos gráficos o imágenes que sean ligeramente diferentes en su representación en la base de datos pueden ser considerados iguales por un usuario. Por ejemplo, una base de datos puede almacenar diseños de marcas comerciales. Cuando haya que registrar una nueva marca puede que el sistema necesite identificar antes todas las marcas parecidas que se registraron anteriormente. • Datos de sonido. Se están desarrollando interfaces de usuario basadas en el reconocimiento de la voz que permiten a los usuarios dar un comando o identificar un elemento de datos por la voz. Debe comprobarse la semejanza de la entrada del usuario con los comandos o los elementos de datos almacenados en el sistema. • Datos manuscritos. La entrada manuscrita puede usarse para identificar un elemento de datos manuscrito o una orden manuscrita almacenados en la base de datos. Una vez más, se necesita comprobar la semejanza. El concepto de semejanza suele ser subjetivo y específico del usuario. No obstante, la verificación de la semejanza suele tener más éxito que el reconocimiento de voz o de letras manuscritas, ya que la entrada puede compararse con datos que ya se hallan en el sistema y, por tanto, el conjunto de opciones disponibles para el sistema es limitado. Existen varios algoritmos para hallar las mejores coincidencias con una entrada dada mediante la comprobación de la semejanza. Algunos sistemas, incluidos un sistema telefónico de llamada por nombre activado por la voz, se han distribuido comercialmente. Véanse las notas bibliográficas para hallar más referencias. 24.5 Computadoras portátiles y bases de datos personales

Las bases de datos comerciales de gran tamaño se han almacenado tradicionalmente en las instalaciones informáticas centrales. En las aplicaciones de bases de datos distribuidas ha habido generalmente una fuerte administración central de las bases de datos y de la red. Se han combinado las siguientes ten-

www.detodoprogramacion.com


768

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

dencias tecnológicas para crear aplicaciones en las cuales la suposición de una administración y de un control centralizados no es completamente correcta: 1. El uso cada vez más extendido de computadoras personales y, sobre todo, de computadoras portátiles. 2. El desarrollo de una infraestructura inalámbrica de comunicaciones digitales de coste relativamente bajo, basada en redes inalámbricas de área local, redes celulares de paquetes digitales y otras tecnologías. La informática móvil se ha mostrado útil en muchas aplicaciones. Muchos profesionales usan computadoras portátiles para poder trabajar y tener acceso a los datos durante sus viajes. Los servicios de mensajería usan computadoras portátiles para ayudar al seguimiento de los paquetes. Los servicios de emergencia usan computadoras portátiles en el escenario de los desastres, en las emergencias médicas y similares para tener acceso a la información y para introducir datos relativos a la situación. Los teléfonos móviles (celulares) se están convirtiendo en dispositivos que no sólo proporcionan servicios de telefonía, sino que permiten el correo electrónico y el acceso Web. Siguen surgiendo nuevas aplicaciones de las computadoras portátiles. Las computadoras comunicadas por radio crean una situación en que las máquinas ya no tienen ubicaciones fijas ni direcciones de red. Las consultas dependientes de la ubicación son una clase interesante de consultas que está motivada por las computadoras portátiles; en estas consultas la ubicación del usuario (computadora) es un parámetro de la consulta. El valor del parámetro de ubicación lo proporciona el usuario o, cada vez más, un sistema de posicionamiento global (GPS). Un ejemplo son los sistemas de información para viajeros que proporcionan a los conductores datos sobre los hoteles, los servicios de carretera y similares. El procesamiento de las consultas sobre los servicios que se hallan más adelante en la ruta actual debe basarse en la ubicación del usuario, en su dirección de movimiento y en su velocidad. Se ofrecen cada vez más ayudas a la navegación como una característica integrada en los automóviles. La energía (la carga de las baterías) es un recurso escaso para la mayor parte de las computadoras portátiles. Esta limitación influye en muchos aspectos del diseño de los sistemas. Entre las consecuencias más interesantes de la necesidad de eficiencia energética es que los pequeños dispositivos móviles emplean la mayor parte del tiempo hibernándose, despertándose durante una fracción de segundo cada segundo aproximadamente para comprobar si hay datos entrantes y para enviar datos. Este comportamiento tiene un impacto significativo en los protocolos usados para comunicarse con los dispositivos móviles. El uso de emisiones programadas de datos en los sistemas móviles para reducir la necesidad de transmisión de consultas es otra forma de reducir los requisitos de energía. Cantidades cada vez mayores de datos residen en máquinas administradas por los usuarios en lugar de por administradores de bases de datos. Además, estas máquinas pueden estar, a veces, desconectadas de la red. En muchos casos hay un conflicto entre la necesidad del usuario de seguir trabajando mientras está desconectado y la necesidad de consistencia global de los datos. En los Apartados 24.5.1 a 24.5.4 se estudian técnicas en uso y en desarrollo para tratar los problemas de las computadoras portátiles y de la informática personal.

24.5.1 Un modelo de informática móvil

El entorno de la informática móvil consiste en computadoras portátiles, denominadas anfitriones móviles, y una red de computadoras conectadas por cable. Los anfitriones móviles se comunican con la red de cable mediante computadoras denominadas estaciones para el soporte de movilidad. Cada estación para el soporte de movilidad gestiona los anfitriones móviles de su celda—es decir, del área geográfica que cubre. Los anfitriones móviles pueden moverse de unas celdas a otras, por lo que necesitan el relevo del control de una estación para el soporte de movilidad a otra. Dado que los anfitriones móviles pueden, a veces, estar apagados, un anfitrión puede abandonar una celda y aparecer más tarde en otra distante. Por tanto, los movimientos de unas celdas a otras no se realizan necesariamente entre celdas adyacentes. Dentro de un área pequeña, como un edificio, los anfitriones móviles pueden conectarse

www.detodoprogramacion.com


24.5

Computadoras portátiles y bases de datos personales

769

mediante una red inalámbrica de área local que proporciona conectividad de coste más reducido que las redes celulares de área amplia, y que reduce la sobrecarga de entregas. Es posible que los anfitriones móviles se comuniquen directamente sin intervención de ninguna estación para el soporte de movilidad. No obstante, esa comunicación sólo puede ocurrir entre anfitriones cercanos. Estas formas directas de comunicación se están haciendo más frecuentes con la llegada del estándar Bluetooth. Bluetooth usa radio digital de corto alcance para permitir la conectividad por radio a alta velocidad (hasta 721 kilobits por segundo) a distancias inferiores a diez metros. Concebido inicialmente como una sustitución de los cables, lo más prometedor de Bluetooth es la conexión ad hoc sencilla entre computadoras portátiles, PDAs, teléfonos celulares y las denominadas aplicaciones inteligentes. Los sistemas de redes de área local inalámbricas basados en las normas 801.11 (a/b/g) se usan mucho actualmente y los sistemas basados en 802.16 (Wi-Max) aparecieron en 2005. La infraestructura de red para la informática móvil consiste en gran parte en dos tecnologías: redes inalámbricas locales y redes de telefonía celular basadas en paquetes. Los primeros sistemas celulares usaban tecnología analógica y estaban diseñados para la comunicación de voz. Los sistemas digitales de segunda generación siguieron centrándose en las aplicaciones de voz. Los sistemas de tercera generación (3G) y los denominados sistemas 2.5G usan redes basadas en paquetes y están más adaptados a las aplicaciones de datos. En estas redes la voz es sólo una más de las aplicaciones (aunque una económicamente importante). Bluetooth, las redes de área local inalámbricas y las redes celulares 2.5G y 3G hacen posible que se comuniquen a bajo coste gran variedad de dispositivos. Aunque esta comunicación en sí misma no encaja en el dominio de las aplicaciones habituales de bases de datos, los datos de la contabilidad, del control y de la administración correspondientes a esta comunicación generan bases de datos enormes. La inmediatez de la comunicación por radio genera la necesidad de acceso en tiempo real a muchas de estas bases de datos. Esta necesidad de inmediatez añade otra dimensión a las restricciones del sistema —un asunto que se abordará en profundidad en el Apartado 24.3. El tamaño y las limitaciones de potencia de muchas computadoras portátiles han llevado a la creación de jerarquías de memoria alternativas. En lugar de, o además de, el almacenamiento en disco, puede incluirse la memoria flash, que se estudió en el Apartado 11.1. Si el anfitrión móvil incluye un disco duro, puede que se permita que el disco deje de girar cuando no se utilice, para ahorrar energía. Las mismas consideraciones de tamaño y de energía limitan el tipo y el tamaño de las pantallas usadas en los dispositivos portátiles. Los diseñadores de los dispositivos portátiles suelen crear interfaces de usuario especiales para trabajar con estas restricciones. No obstante, la necesidad de presentar datos basados en Web ha exigido la creación de estándares para presentaciones. El protocolo de aplicaciones inalámbrico (Wireless Application Protocol, WAP) es un estándar para el acceso inalámbrico a Internet. Los exploradores basados en WAP tienen acceso a páginas Web especiales que usan el lenguaje de marcas inalámbrico (Wireless Markup Language, WML), un lenguaje basado en XML diseñado para las restricciones de la exploración Web móvil e inalámbrica.

24.5.2 Encaminamiento y procesamiento de consultas

La ruta entre cada par de anfitriones puede cambiar con el tiempo si alguno de los dos anfitriones es móvil. Este sencillo hecho tiene un efecto espectacular en el nivel de la red, ya que las direcciones de red basadas en las ubicaciones ya no son constantes en el sistema. La informática móvil también afecta directamente al procesamiento de consultas de las bases de datos. Como se vio en el Capítulo 22, hay que considerar los costes de comunicación cuando se escoge una estrategia de procesamiento distribuido de las consultas. La informática móvil hace que los costes de comunicación cambien de manera dinámica, lo que complica el proceso de optimización. Además, varios conceptos de coste que hay que considerar en relación con los demás: • El tiempo del usuario es una materia prima muy valiosa en muchas aplicaciones profesionales. • El tiempo de conexión es la unidad por la que se asignan los costes monetarios en algunos sistemas de telefonía celular.

www.detodoprogramacion.com


770

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

• El número de bytes, o de paquetes, transferidos es la unidad por la que se calculan los costes en algunos sistemas de telefonía celular digital. • Los costes basados en la hora del día varían, en función de si la comunicación se produce durante los periodos pico o durante los periodos valle. • La energía es limitada. A menudo la energía de las baterías es un recurso escaso cuyo uso debe optimizarse. Un principio básico de las comunicaciones inalámbricas es que hace falta menos energía para recibir señales de radio que para emitirlas. Así, la transmisión y la recepción de los datos imponen demandas de energía diferentes al anfitrión móvil. 24.5.3 Datos de difusión

Suele ser deseable para los datos que se solicitan con frecuencia que los transmitan las estaciones de soporte de las computadoras portátiles en un ciclo continuo, en lugar de que se transmitan a los anfitriones móviles a petición de éstos. Una aplicación típica de estos datos de difusión es la información de las cotizaciones bursátiles. Hay dos motivos para usar los datos de difusión. En primer lugar, los anfitriones móviles evitan el coste energético de transmitir las solicitudes de datos. En segundo lugar, los datos de difusión pueden recibirlos simultáneamente gran número de anfitriones móviles, sin coste adicional. Por tanto, el ancho de banda disponible para transmisiones se usa de manera más efectiva. Así, los anfitriones móviles pueden recibir los datos a medida que se transmiten, en lugar de consumir energía transmitiendo solicitudes. Puede que los anfitriones móviles tengan almacenamiento no volátil disponible para guardar en la caché los datos de difusión para su uso posterior. Dada una consulta, los anfitriones móviles pueden minimizar los costes energéticos determinando si pueden procesarla sólo con los datos guardados en la caché. Si los datos guardados en la caché son insuficientes, hay dos opciones: esperar a que los datos se transmitan o transmitir una solicitud de datos. Para tomar esta decisión los anfitriones móviles deben conocer el momento en que se transmitirán los datos en cuestión. Los datos de difusión pueden transmitirse de acuerdo con una programación fija o según una programación variable. En el primer caso, los anfitriones móviles usan la programación fija conocida para determinar el momento en que se transmitirán los datos en cuestión. En el segundo caso, se debe transmitir la propia programación de transmisiones en una frecuencia de radio conocida y a intervalos de tiempos conocidos. En efecto, el medio transmitido puede modelarse como un disco con una latencia elevada. Las solicitudes de datos pueden considerarse atendidas cuando los datos solicitados se transmiten. Las programaciones de transmisión se comportan como los índices de los discos. Las notas bibliográficas citan trabajos de investigación recientes en el área de administración de los datos de difusión. 24.5.4 Desconexiones y consistencia

Dado que puede que las comunicaciones inalámbricas se paguen con arreglo al tiempo de conexión, hay un incentivo para que se desconecten determinados anfitriones móviles durante periodos de tiempo considerables. Las computadoras portátiles sin conectividad inalámbrica están desconectadas la mayor parte del tiempo en que se usan, excepto cuando se conectan de manera periódica a sus computadoras anfitrionas, físicamente o mediante una red informática. Durante esos periodos de desconexión puede que el anfitrión móvil siga operativo. Puede que el usuario del anfitrión móvil formule consultas y solicite actualizaciones de los datos que residen localmente o que se han guardado en la caché local. Esta situación crea varios problemas, en especial: • Recuperabilidad. Las actualizaciones introducidas en una máquina desconectada pueden perderse si el anfitrión móvil sufre un fallo catastrófico. Dado que el anfitrión móvil representa un único punto de fallo, no se puede simular bien el almacenamiento estable. • Consistencia. Los datos guardados en la caché local pueden quedar obsoletos, pero el anfitrión móvil no puede descubrir la situación hasta que vuelva a conectarse. De manera parecida, las actualizaciones que se produzcan en el anfitrión móvil no pueden transmitirse hasta que no se produzca de nuevo la conexión.

www.detodoprogramacion.com


24.5

Computadoras portátiles y bases de datos personales

771

El problema de la consistencia se estudió en el Capítulo 22, donde se estudiaron las particiones de la red, y aquí se partirá de esa base. En los sistemas distribuidos conectados por redes físicas las particiones se consideran un modo de fallo; en la informática móvil las particiones mediante desconexiones son parte del modo de operación normal. Por tanto, es necesario permitir que continúe el acceso a los datos a pesar de las particiones, pese al riesgo de que se produzca una pérdida de consistencia. Para los datos actualizados sólo por el anfitrión móvil, es sencillo transmitir las actualizaciones cuando el anfitrión móvil vuelve a conectarse. No obstante, si el anfitrión móvil guarda en la caché copias de los datos sólo para lectura que pueden actualizar otras computadoras, puede que los datos guardados en la caché acaben siendo inconsistentes. Cuando se conecta el anfitrión móvil, puede recibir informes de invalidación que lo informen de las entradas de la caché que están obsoletas. No obstante, cuando el anfitrión móvil esté desconectado puede perder algún informe de invalidación. Una solución sencilla a este problema es invalidar toda la caché al volver a conectar el anfitrión móvil, pero una solución tan extrema resulta muy costosa. En las notas bibliográficas se citan varios esquemas para el almacenamiento en la caché. Si se pueden producir actualizaciones tanto en el anfitrión móvil como en el resto del sistema, la detección de las actualizaciones conflictivas resulta más difícil. Los esquemas basados en la numeración de versiones permiten las actualizaciones de los archivos compartidos desde los anfitriones desconectados. Estos esquemas no garantizan que las actualizaciones sean consistentes. Más bien, garantizan que, si dos anfitriones actualizan de manera independiente la misma versión del documento, el conflicto se acabará descubriendo, cuando los anfitriones intercambien información directamente o mediante un anfitrión común. El esquema del vector de versiones detecta las inconsistencias cuando las copias de un documento se actualizan de manera independiente. Este esquema permite que las copias de un documento se almacenen en varios anfitriones. Aunque se utilice el término documento, el esquema puede aplicarse a otros elementos de datos, como las tuplas de una relación. La idea básica es que cada anfitrión i almacene, con su copia de cada documento d, un vector de versiones—es decir, un conjunto de números de versiones {Vd,i [j]}, con una entrada para cada uno de los demás anfitriones d en los que se puede actualizar potencialmente el documento. Cuando un anfitrión i actualiza un documento d, incrementa el número de versión Vd,i [i] en una unidad. Siempre que dos anfitriones i y d se conectan entre sí, intercambian los documentos actualizados, de modo que los dos obtienen versiones nuevas de los documentos. No obstante, antes de intercambiar los documentos, los anfitriones tienen que averiguar si las copias son consistentes: 1. Si los vectores de versiones son iguales en los dos anfitriones—es decir, si para cada k, Vd,i [k] = Vd,j [k] —las copias del documento d son idénticas. 2. Si, para cada k, Vd,i [k] ≤ Vd,j [k] y los vectores de versiones no son idénticos, la copia del documento d del anfitrión i es más antigua que la del anfitrión d. Es decir, la copia del documento d del anfitrión d se obtuvo mediante una o más modificaciones de la copia del documento del anfitrión i. El anfitrión i sustituye su copia de d, así como su copia del vector de versiones de d, por las copias del anfitrión d. 3. Si hay un par de anfitriones k y m tales que Vd,i [k] < Vd,j [k] y Vd,i [m] > Vd,j [m], las copias son inconsistentes; es decir, la copia de d de i contiene actualizaciones realizadas por el anfitrión k que no se han transmitido al anfitrión d y, de manera parecida, la copia de d de d contiene actualizaciones llevadas a cabo por el anfitrión m que no se han transmitido al anfitrión i. Entonces, las copias de d son inconsistentes, ya que se han realizado de manera independiente dos o más actualizaciones de d. Puede que se necesite la intervención manual para mezclar las actualizaciones. El esquema de vectores de versiones se diseñó inicialmente para tratar los fallos en los sistemas de archivos distribuidos. El esquema adquirió mayor importancia porque las computadoras portátiles suelen almacenar copias de los archivos que también se hallan presentes en los sistemas servidores, lo que constituye de facto un sistema de archivos distribuido que suele estar desconectado. Otra aplicaciones de este esquema son los sistemas en grupo, en que los anfitriones se conectan de manera periódica, en lugar de hacerlo de manera continua, y deben intercambiar los documentos actualizados. El esquema del vector de versiones también tiene aplicaciones en las bases de datos replicadas.

www.detodoprogramacion.com


772

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

No obstante, el esquema del vector de versiones no logra abordar el problema más difícil e importante que plantean las actualizaciones de los datos compartidos—la reconciliación de las copias inconsistentes de los datos. Muchas aplicaciones pueden llevar a cabo de manera automática la reconciliación ejecutando en cada computadora las operaciones que han conducido a las actualizaciones en las computadoras remotas durante el periodo de desconexión. Esta solución funciona si las operaciones de actualización conmutan— es decir, generan el mismo resultado, independientemente del orden en que se ejecuten. Puede que se disponga de técnicas alternativas en ciertas aplicaciones; en el peor de los casos, no obstante, debe dejarse a los usuarios que resuelvan las inconsistencias. El tratamiento automático de estas inconsistencias y la ayuda a los usuarios para que resuelvan las que no puedan tratarse de manera automática sigue siendo un área de investigación. Otra debilidad es que el esquema del vector de versiones exige una comunicación sustancial entre el anfitrión móvil que vuelve a conectarse y su estación para el soporte de movilidad. Las verificaciones de la consistencia pueden posponerse hasta que se necesiten los datos, aunque este retraso puede incrementar la inconsistencia global de la base de datos. La posibilidad de desconexión y el coste de las comunicaciones inalámbricas limitan el aspecto práctico de las técnicas de procesamiento de las transacciones para los sistemas distribuidos estudiadas en el Capítulo 22. A menudo resulta preferible dejar que los usuarios preparen las transacciones en los anfitriones móviles y exigir que, en lugar de ejecutarlas localmente, las remitan al servidor para su ejecución. Las transacciones que afectan a más de una computadora y que incluyen un anfitrión móvil afrontan bloqueos de larga duración durante el compromiso de la transacción, a menos que las desconexiones sean raras o predecibles. 24.6 Resumen

• El tiempo desempeña un papel importante en los sistemas de bases de datos. Las bases de datos son modelos del mundo real. Aunque la mayor parte de las bases de datos modelan el estado del mundo real en un momento dado (en el momento actual), las bases de datos temporales modelan los estados del mundo real a lo largo del tiempo. • Los hechos de las relaciones temporales tienen momentos asociados cuando son válidos, que pueden representarse como una unión de intervalos. Los lenguajes de consultas temporales simplifican el modelado del tiempo, así como las consultas relacionadas con el tiempo. • Las bases de datos espaciales se usan cada vez más hoy en día para almacenar datos de diseño asistido por computadora y datos geográficos. • Los datos de diseño se almacenan sobre todo como datos vectoriales; los datos geográficos consisten en una combinación de datos vectoriales y lineales. Las restricciones de integridad espacial son importantes para los datos de diseño. • Los datos vectoriales pueden codificarse como datos de la primera forma normal o almacenarse mediante estructuras que no sean la primera forma normal, como las listas. Las estructuras de índices de finalidad espacial resultan especialmente importantes para tener acceso a los datos espaciales y para procesar las consultas espaciales. • Los árboles R son una extensión multidimensional de los árboles B; con variantes como los árboles R+ y los árboles R∗ , se han hecho populares en las bases de datos espaciales. Las estructuras de índices que dividen el espacio de manera regular, como los árboles cuadráticos, ayudan a procesar las consultas de mezcla espaciales. • Las bases de datos multimedia están aumentando de importancia. Problemas como la recuperación basada en la semejanza y la entrega de datos a velocidades garantizadas son temas de investigación actuales. • Los sistemas de informática móvil se han vuelto de uso común, lo que ha llevado al interés por los sistemas de bases de datos que pueden ejecutarse en ellos. El procesamiento de las consultas en estos sistemas puede implicar la búsqueda en las bases de datos de los servidores. El modelo

www.detodoprogramacion.com


Ejercicios prácticos

773

de coste de las consultas debe incluir el coste de la comunicación, incluido el coste monetario y el coste de la energía de las baterías, que resulta relativamente elevado para los sistemas portátiles. • La transmisión resulta mucho más económica por receptor que la comunicación punto a punto, y la transmisión de datos como los datos bursátiles ayuda a los sistemas portátiles a recoger los datos de manera económica. • La operación en desconexión, el uso de los datos de difusión y el almacenamiento de los datos en la caché son tres problemas importantes que se están abordando hoy en día en la informática móvil. Términos de repaso

• Consultas regionales. • Reunión espacial.

• Datos temporales. • Tiempo válido. • Tiempo de transacción. • Relación temporal. • Relación bitemporal. • Tiempo universal coordinado (UTC).

• • • •

• Relación instantánea. • Lenguajes de consultas temporales. •

• Selección temporal. • Proyección temporal. • Reunión temporal. • Mezcla temporal. • Datos espaciales y geográficos. • Datos de diseño asistido por computadora (Computer Aided Design, CAD). • Datos geográficos. • Sistemas de información geográfica. • Triangulación. • Bases de datos de diseño. • Datos geográficos. • Datos por líneas (raster). • Datos vectoriales. • Sistema de posicionamiento global (Global Positioning System, GPS). • Consultas espaciales. • Consultas de proximidad. • Consultas de vecino más próximo.

• • • • • •

Indexado de los datos espaciales. Árboles k-d. Árboles k-d B. Árboles cuadráticos: ¤ PR. ¤ Regional. Árboles R. ¤ Caja límite. ¤ División cuadrática. Bases de datos multimedia. Datos isócronos. Datos de medios continuos. Recuperación basada en la semejanza. Formatos de datos multimedia. Servidores de vídeo.

• Informática móvil. ¤ Anfitriones móviles. ¤ Estaciones de soporte de las computadoras portátiles. ¤ Celda. ¤ Relevo. • Consultas dependientes de la ubicación. • Datos de difusión. • Consistencia. ¤ Informes de invalidación. ¤ Esquema del vector de versiones.

Ejercicios prácticos

24.1 Indíquense los dos tipos de tiempo y en lo que se diferencian. Explíquese el motivo de que haya dos tipos de tiempo asociados con cada tupla. 24.2 Supóngase que se tiene una relación que contiene las coordenadas x, y y los nombres de varios restaurantes. Supóngase también que las únicas consultas que se formularán serán de la forma

www.detodoprogramacion.com


774

Capítulo 24

Tipos de datos avanzados y nuevas aplicaciones

siguiente: la consulta especifica un punto y pregunta si hay algún restaurante exactamente en ese punto. Indíquese el tipo de índice que sería preferible, árbol R o árbol B. Explíquese el motivo. 24.3 Supóngase que se dispone de una base de datos espacial que soporta consultas regionales (con regiones circulares) pero no consultas de vecino más próximo. Descríbase un algoritmo para hallar el vecino más próximo haciendo uso de varias consultas regionales. 24.4 Supóngase que se desean almacenar segmentos rectilíneos en un árbol R. Si un segmento rectilíneo no es paralelo a los ejes, su caja límite puede ser grande y contener una gran área vacía. • Descríbase el efecto en el rendimiento de tener cajas límite de gran tamaño en las consultas que piden los segmentos rectilíneos que intersectan una región dada. • Descríbase brevemente una técnica para mejorar el rendimiento de esas consultas y dese un ejemplo de sus ventajas. Sugerencia: se pueden dividir los segmentos en partes más pequeñas. 24.5 Dese un procedimiento recursivo para calcular de manera eficiente la mezcla espacial de dos relaciones con índices de árbol R. Sugerencia: úsense cajas límite para comprobar si las entradas hojas bajo un par de nodos internos pueden intersectarse. 24.6 Descríbase el modo en que las ideas subyacentes a la organización RAID (Apartado 11.3) pueden usarse en un entorno de datos de difusión, donde puede que haya ocasionalmente ruido que impida la recepción de parte de los datos que se están transmitiendo. 24.7 Defínase un modelo en que se difundan repetidamente los datos en el que el medio de transmisión se modele como un disco virtual. Descríbase el modo en que el tiempo de acceso y la velocidad de transferencia de datos del disco virtual se diferencian de los valores correspondientes a un disco duro normal. 24.8 Considérese una base de datos de documentos en la que todos los documentos se conserven en una base de datos central. En las computadoras portátiles se guardan copias de algunos documentos. Supóngase que la computadora portátil A actualiza una copia del documento 1 mientras está desconectada y que, al mismo tiempo, la computadora portátil B actualiza una copia del documento 2 mientras está desconectada. Muéstrese el modo en que el esquema del vector versión puede asegurar la actualización adecuada de la base de datos central y de las computadoras portátiles cuando se vuelva a conectar una computadora portátil.

Ejercicios

24.9 Indíquese si se conservarán las dependencias funcionales si se convierte una relación en una relación temporal añadiéndole un atributo temporal. Indíquese el modo en que se resuelve el problema en las bases de datos temporales. 24.10 Considérense dos datos vectoriales bidimensionales en que los elementos de datos no se solapan. Indíquese si es posible convertir esos datos vectoriales en datos lineales. En caso de que sea posible, indíquense los inconvenientes de almacenar los datos lineales obtenidos de esa conversión en lugar de los datos vectoriales originales. 24.11 Estúdiese el soporte de los datos espaciales ofrecido por el sistema de bases de datos que se está usando e impleméntese lo siguiente: a. Un esquema para representar la ubicación geográfica de los restaurantes y características como la cocina que se sirve en cada restaurante y su nivel de precios. b. Una consulta para hallar los restaurantes económicos que sirven comida india y que se hallan a menos de nueve kilómetros de casa del lector (supóngase cualquier ubicación para la casa del lector). c. Una consulta para hallar para cada restaurante su distancia al restaurante más cercano que sirve la misma cocina y con el mismo nivel de precios.

www.detodoprogramacion.com


Notas bibliográficas

775

24.12 Indíquense los problemas que se producen en un sistema de medios continuos si los datos se entregan demasiado lento o demasiado rápido. 24.13 Indíquense tres características principales de la informática móvil en redes inalámbricas que son diferentes de las de los sistemas distribuidos tradicionales. 24.14 Indíquense tres factores que haya que considerar en la optimización de las consultas para la informática móvil que no se consideren en los optimizadores de consultas tradicionales. 24.15 Dese un ejemplo para mostrar que el esquema del vector versión no asegura la secuenciabilidad. Sugerencia: utilícese el ejemplo del Ejercicio práctico 24.8, con la suposición de que los documentos 1 y 2 están disponibles en las dos computadoras portátiles A y B, y téngase en cuenta la posibilidad de que un documento pueda leerse sin que se actualice. Notas bibliográ cas

Stam y Snodgrass [1988] y Soo [1991] proporcionan estudios sobre la administración de los datos temporales. Jensen et al. [1994] presentan un glosario de conceptos de las bases de datos temporales, con la intención de unificar la terminología. Tansel et al. [1993] es una colección de artículos sobre diferentes aspectos de las bases de datos temporales. Chomicki [1995] presenta técnicas para administrar las restricciones para la integridad temporal. Heywood et al. [2002] es un libro que estudia los sistemas de información geográfica. Samet [1995b] proporciona una introducción a la gran cantidad de trabajo realizado sobre las estructuras espaciales de índices. Samet [1990] proporciona una cobertura en el nivel de los libros de texto de las estructuras espaciales de datos. Una de las primeras descripciones de los árboles cuadráticos se proporciona en Finkel y Bentley [1974]. Samet [1990] y Samet [1995b] describen numerosas variantes de los árboles cuadráticos. Bentley [1975] describe los árboles k-d, y Robinson [1981] describe los árboles k-d B. Los árboles R se presentaron originalmente en Guttman [1984]. Las extensiones de los árboles R se presentan en Sellis et al. [1987], que describen los árboles R+ , y Beckmann et al. [1990], que describen los árboles R∗ tree. Brinkhoff et al. [1993] estudian una implementación de las mezclas espaciales mediante árboles R. Lo y Ravishankar [1996] y Patel y DeWitt [1996] presentan los métodos basados en las particiones para el cálculo de las mezclas espaciales. Samet y Aref [1995] proporcionan una introducción de los modelos espaciales de datos, de las operaciones espaciales y de la integración de los datos espaciales con los no espaciales. Revesz [2002] es un libro que estudia el área de las bases de datos con restricciones; los intervalos temporales y las regiones espaciales se pueden pensar como un caso especial de restricciones. Samet [1995a] describe los campos de investigación en las bases de datos multimedia. El indexado de los datos multimedia se estudia en Faloutsos y Lin [1995]. Dashti et al. [2003] es un libro que describe el diseño de servidores de flujos de datos de medios, incluyendo un estudio extensivo de la organización de datos en subsistemas de discos. Los servidores de vídeo se estudian en Anderson et al. [1992], Rangan et al. [1992], Ozden et al. [1994], Freedman y DeWitt [1995] y Ozden et al. [1996b]. La tolerancia a los fallos se estudia en Berson et al. [1995] y Ozden et al. [1996a]. La administración de la información en los sistemas que incluyen computadoras portátiles se estudia en Alonso y Korth [1993] y en Imielinski y Badrinath [1994]. Imielinski y Korth [1996] presentan una introducción a la informática móvil y una colección de trabajos de investigación sobre el tema. El esquema del vector de versiones para la detección de la inconsistencia en los sistemas de archivos distribuidos se describe en Popek et al. [1981] y en Parker et al. [1983].

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

25

Procesamiento avanzado de transacciones

En los Capítulos 15, 16 y 17 se introdujo el concepto de transacción, que es una unidad de programa que tiene acceso — y posiblemente actualiza—varios elementos de datos, y cuya ejecución asegura la conservación de las propiedades ACID. En esos capítulos se estudiaron gran variedad de esquemas para asegurar las propiedades ACID en entornos en los que pueden producirse fallos, y en los que las transacciones pueden ejecutarse de manera concurrente. En este capítulo se irá más allá de los esquemas básicos estudiados anteriormente y se abordarán los conceptos del procesamiento avanzado de las transacciones, incluidos los monitores de procesamiento de transacciones, los flujos de trabajo de las transacciones y el procesamiento de transacciones en el contexto del comercio electrónico. También se estudian las bases de datos en memoria principal, las bases de datos en tiempo real, las transacciones de larga duración, las transacciones anidadas y las transacciones con múltiples bases de datos. 25.1 Monitores de procesamiento de transacciones

Los monitores de procesamiento de transacciones (Transaction Processing monitors, monitores TP) son sistemas que se desarrollaron en los años setenta y ochenta del siglo pasado, inicialmente como respuesta a la necesidad de soportar gran número de terminales remotas (como los terminales de reserva de las líneas aéreas) desde una sola computadora. El término monitor TP significaba inicialmente monitor de teleprocesamiento (Teleprocessing Monitor). Los monitores TP han evolucionado desde entonces para ofrecer el soporte central para el procesamiento distribuido de las transacciones, y el término monitor TP ha adquirido su significado actual. El monitor TP CICS de IBM fue uno de los primeros monitores TP, y se ha usado mucho. Entre los monitores TP de la generación actual están Tuxedo y Top End (los dos actualmente de BEA Systems), Encina (de Transarc, que ahora forma parte de IBM) y Transaction Server (de Microsoft). Las arquitecturas de servidores de aplicaciones Web, incluyendo los servlets, que se estudiaron anteriormente en el Apartado 8.4, proporcionan soporte a muchas de las características de los monitores TP y se conocen a veces como “TP ligeros”. Los servidores de aplicaciones Web se usan ampliamente y han reemplazado a los monitores TP tradicionales para muchas aplicaciones. Sin embargo, los conceptos subyacentes en ellos, que se estudian en este apartado, son esencialmente iguales. 25.1.1 Arquitecturas de los monitores TP

Los sistemas de procesamiento de transacciones a gran escala se construyen en torno a una arquitectura cliente– servidor. Una manera de crear estos sistemas es tener un proceso servidor para cada cliente; el servidor realiza la autentificación, y luego ejecuta las acciones solicitadas por el cliente. Este modelo de proceso por cliente se ilustra en la Figura 25.1a. Este modelo presenta varios problemas con respecto al uso de la memoria y a la velocidad de procesamiento: 777

www.detodoprogramacion.com


778

Capítulo 25

Procesamiento avanzado de transacciones

clientes remotos

servidor

archivos

clientes remotos

(a) Modelo de procesos por cliente

servidor

archivos

(b) Modelo de servidor único monitor

clientes remotos

encaminador servidores

encaminadores servidores archivos clientes remotos

(c) Modelo de muchos servidores y un solo encaminador Figura 25.1

archivos

(d) Modelo de muchos servidores y muchos encaminadores

Arquitecturas de los monitores TP.

• Los requisitos de memoria para cada proceso son elevados. Aunque se comparta la memoria para el código de los programas entre todos los procesos, cada proceso consume memoria para los datos locales y los descriptores de los archivos abiertos, así como para la sobrecarga del sistema operativo, como las tablas de páginas para soportar la memoria virtual. • El sistema operativo divide el tiempo disponible de CPU entre los procesos conmutando entre ellos; esta tarea se denomina multitarea. Cada cambio de contexto entre un proceso y el siguiente supone una sobrecarga considerable de la CPU; incluso en los sistemas rápidos de hoy en día un cambio de contexto puede tardar cientos de microsegundos. Los problemas anteriores pueden evitarse teniendo un proceso con un solo servidor al que se conecten todos los servidores; este modelo se denomina modelo de servidor único, ilustrado en la Figura 25.1b. Los clientes remotos envían las solicitudes al proceso del servidor, que ejecuta entonces esas solicitudes. Este modelo también se usa en los entornos cliente–servidor, en los que los clientes envían solicitudes a un proceso de un solo servidor. El proceso servidor asume las tareas, como la autentificación de los usuarios, que normalmente asumiría el sistema operativo. Para evitar bloquear otros clientes al procesar una solicitud de larga duración de un cliente, el servidor usa multienhebramiento: el proceso servidor dispone una hebra de control para cada cliente y, en efecto, implementa su propia multitarea de baja sobrecarga. Ejecuta el código en nombre de un cliente durante un rato, luego guarda el contexto interno y conmuta al código de otro cliente. A diferencia de la sobrecarga de la multitarea, el coste de la conmutación entre hebras es reducido (generalmente sólo unos pocos microsegundos). Los sistemas basados en el modelo de servidor único, como la versión original del monitor TP CICS de IBM y los servidores de archivos como NetWare de Novell, proporcionaban con éxito tasas de transacciones elevadas con recursos limitados. No obstante, tenían problemas, especialmente cuando varias aplicaciones tenían acceso a la misma base de datos: • Dado que todas las aplicaciones se ejecutan como un único proceso, no hay protección entre ellas. Un fallo en una aplicación puede afectar también a todas las demás aplicaciones. Sería mejor ejecutar cada aplicación como un proceso separado.

www.detodoprogramacion.com


Monitores de procesamiento de transacciones

25.1

779

Figura 25.2

Componentes de los monitores TP.

• Estos sistemas no estån adecuados a las bases de datos paralelas o distribuidas, ya que un proceso servidor no puede ejecutarse simultåneamente en varios servidores (sin embargo, las hebras concurrentes de un proceso pueden soportarse en un sistema multiprocesador de memoria compartida). Se trata de un inconveniente serio para las organizaciones de gran tamaùo en las que el procesamiento paralelo resulta fundamental para el tratamiento de grandes cargas de trabajo, y los datos distribuidos son cada vez mås frecuentes. Una manera de resolver estos problemas es ejecutar varios procesos del servidor de aplicaciones que tengan acceso a una base de datos común y dejar que los clientes se comuniquen con la aplicación mediante un único proceso de comunicaciones que encamine las solicitudes. Este modelo se denomina modelo de varios servidores y un solo encaminador, ilustrado en la Figura 25.1c. Este modelo soporta procesos de servidor independientes para varias aplicaciones; ademås, cada aplicación puede tener un grupo de procesos de servidor, cualquiera de los cuales puede manejar una sesión cliente. La solicitud puede, por ejemplo, encaminarse al servidor con menor carga de un grupo. Como antes, cada proceso de servidor puede tener, a su vez, varias hebras, de modo que puede atender de manera concurrente varios clientes. Como generalización adicional, los servidores de aplicaciones pueden ejecutarse en sitios diferentes de una base de datos paralela o distribuida y el proceso de comunicaciones puede manejar las comunicaciones entre los procesos. La arquitectura anterior tambiÊn se usa mucho en los servidores Web. Un servidor Web tiene un proceso principal que recibe las solicitudes HTTP, y luego asigna la tarea de manejar cada solicitud a un proceso diferente (escogido de entre un grupo de procesos). Cada uno de los procesos tiene, a su vez, varias hebras, por lo que puede atender varias solicitudes. El uso de lenguajes de programación seguros, tales como Java, C#, o Visual Basic, permite que los servidores de aplicaciones Web protejan las hebras frente a errores en otras. En cambio, con un lenguaje como C o C++, los errores como los de asignación de memoria en una hebra pueden provocar el fallo de otras. Una arquitectura mås general tiene varios procesos, en lugar de uno solo, para comunicarse con los clientes. Los procesos de comunicación con los clientes interactúan con uno o varios procesos encaminadores, que encaminan las solicitudes hacia el servidor correspondiente. Los monitores TP de generaciones posteriores, por tanto, tienen una arquitectura diferente, denominada modelo de varios servidores y varios encaminadores, ilustrado en la Figura 25.1d. Un proceso controlador inicia los demås procesos y supervisa su funcionamiento. Pathway de Tandem es un ejemplo de un monitor TP que usa esta arquitectura. Los sistemas servidores Web de rendimiento muy elevado tambiÊn adoptan una arquitectura de este tipo. Los procesos del encaminador son generalmente encaminadores de red que dirigen el tråfico de la misma dirección Internet a distintas computadoras servidoras, dependiendo de dónde venga el tråfico. Lo que parece al mundo exterior un solo servidor con una sola dirección puede ser una colección de servidores.

www.detodoprogramacion.com


780

Capítulo 25

Procesamiento avanzado de transacciones

La estructura detallada de un monitor TP aparece en la Figura 25.2. Un monitor TP hace más cosas que pasar mensajes a los servidores de aplicaciones. Cuando llegan los mensajes, puede que haya que ubicarlos en una cola; por tanto, hay un gestor de colas para los mensajes entrantes. Puede que la cola sea una cola duradera, cuyas entradas sobreviven a los fallos del sistema. El uso de colas duraderas ayuda a asegurar que se acaben procesando los mensajes una vez recibidos y guardados en la cola, independientemente de los fallos del sistema. La gestión de las autorizaciones y de los servidores de aplicaciones (por ejemplo, el inicio de los servidores y el encaminamiento de los mensajes hacia los servidores) son otras funciones de los monitores TP. Los monitores TP suelen proporcionar recursos para la elaboración de registros históricos, recuperación y control de concurrencia, lo que permite a los servidores de aplicaciones implementar directamente, si fuera necesario, las propiedades ACID de las transacciones. Finalmente, los monitores TP también proporcionan soporte para la mensajería persistente. Hay que recordar que la mensajería persistente (Apartado 22.4.3) proporciona una garantía de que el mensaje se entregue si (y sólo si) la transacción se compromete. Además de estos servicios, muchos monitores TP también proporcionaban recursos para presentaciones para crear interfaces de menús o de formularios o para los clientes no inteligentes como los terminales; estos recursos ya no son importantes porque los clientes no inteligentes ya no se usan mucho.

25.1.2 Coordinación de las aplicaciones mediante los monitores TP

Hoy en día las aplicaciones suelen tener que interactuar con múltiples bases de datos. Puede que tengan que interactuar con sistemas heredados, como los sistemas de almacenamiento de finalidad especial construidos directamente con base en los sistemas de archivos. Finalmente, puede que tengan que comunicarse con usuarios o con otras aplicaciones en sitios remotos. Por tanto, también tienen que interactuar con subsistemas de comunicaciones. Es importante poder coordinar los accesos a los datos e implementar las propiedades ACID de las propiedades a través de esos sistemas. Los monitores TP modernos proporcionan soporte para la construcción y la gestión de aplicaciones de un tamaño tan grande, creadas a partir de varios subsistemas como las bases de datos, los sistemas heredados y los sistemas de comunicaciones. Los monitores TP tratan cada subsistema como un gestor de recursos que proporciona acceso transaccional a algún conjunto de recursos. La interfaz entre el monitor TP y el gestor de recursos se define mediante un conjunto de primitivas de las transacciones como begin_transaction (iniciar transacción), commit_transaction (comprometer transacción), abort_transaction (abortar transacción) y prepare_to_commit_transaction (preparar para comprometer transacción, para el compromiso de dos fases). Por supuesto, el gestor de recursos también debe proporcionar otros servicios, como proporcionar datos, a la aplicación. La interfaz del gestor de recursos está definida por el estándar de procesamiento de transacciones distribuidas X/Open (X/Open Distributed Transaction Processing). Muchos sistemas de bases de datos soportan los estándares X/Open, y pueden actuar como gestores de recursos. Los monitores TP —así como otros productos, como los sistemas SQL, que soportan los estándares X/Open—pueden conectarse con los gestores de recursos. Además, los servicios proporcionados por los monitores TP, como la mensajería persistente y las colas duraderas, actúan como gestores de recursos que soportan las transacciones. Los monitores TP pueden actuar como coordinadores de los compromisos de dos fases para las transacciones que tienen acceso a estos servicios y a los sistemas de bases de datos. Por ejemplo, cuando se ejecuta una transacción de actualización encolada, se entrega un mensaje y se elimina la transacción solicitada de la cola de solicitudes. El compromiso de dos fases entre la base de datos y los gestores de recursos para las colas duraderas y para la mensajería persistente ayuda a asegurar que, independientemente de los fallos, pueden producirse todas estas acciones o ninguna de ellas. También se pueden usar los monitores TP para administrar los sistemas complejos cliente–servidor que consisten en varios servidores y gran número de clientes. El monitor TP coordina las actividades como los puntos de control y los cierres del sistema. Proporciona la seguridad y la autentificación de los clientes. Administra los grupos de servidores añadiendo o eliminando servidores sin ninguna interrupción del sistema de bases de datos. Finalmente, controla el ámbito de los fallos. Si falla algún servidor, el monitor TP puede detectar ese fallo, abortar las transacciones en curso y reiniciarlas. Si falla algún nodo,

www.detodoprogramacion.com


25.2

Flujos de trabajo de transacciones

781

el monitor TP puede migrar las transacciones a servidores de otros nodos y, una vez más, cancelar las transacciones incompletas. Cuando los nodos que fallan se reinician, el monitor TP puede gobernar la recuperación de los gestores de recursos del nodo. Los monitores TP pueden usarse para ocultar fallos de las bases de datos en los sistemas replicados; los sistemas remotos de copia de seguridad (Apartado 17.9) son un ejemplo de sistemas replicados. Las solicitudes de transacciones se remiten al monitor TP, que transfiere los mensajes a una de las réplicas de la base de datos (al sitio principal, en el caso de sistemas remotos de copia de seguridad). Si falla algún sitio, el monitor TP puede encaminar los mensajes de manera transparente hacia un sitio de copia de seguridad, enmascarando el fallo del primer sitio. En los sistemas cliente – servidor los clientes suelen interactuar con los servidores mediante un mecanismo de llamada a procedimientos remotos (Remote Procedure Call, RPC), en el que el cliente realiza la llamada a un procedimiento, que se ejecuta realmente en el servidor, y los resultados se devuelven al cliente. En lo relativo al código cliente que invoca al RPC, la llamada tiene el mismo aspecto que la invocación a un procedimiento local. Los sistemas de monitores TP, como Encina, proporcionan una interfaz para RPC transaccionales con sus servicios. En esta interfaz el mecanismo RPC proporciona llamadas que pueden usarse para encerrar una serie de llamadas RPC dentro de una transacción. Por tanto, las actualizaciones llevadas a cabo por el RPC se ejecutan dentro del ámbito de la transacción y se pueden hacer retroceder si hay algún fallo. 25.2 Flujos de trabajo de transacciones

Un flujo de trabajo es una actividad en la que varias entidades de procesamiento ejecutan varias tareas de manera coordinada. Una tarea define un trabajo que hay que hacer y puede especificarse de varias maneras, incluidos una descripción textual en un archivo o en un mensaje de correo electrónico, un formulario, un mensaje o un programa de computadora. La entidad de procesamiento que lleva a cabo las tareas puede ser una persona o un sistema de software (por ejemplo, un sistema de envío de correo electrónico, un programa de aplicación o un sistema gestor de bases de datos). La Figura 25.3 muestra algunos ejemplos de flujos de trabajo. Un ejemplo de sencillo es el de un sistema de correo electrónico. La entrega de un solo mensaje de correo implica varios sistemas de envío de correo que reciben y transmiten el mensaje de correo, hasta que el mensaje alcance su destino, donde se almacena. Cada sistema de envío de correo lleva a cabo una tarea—transmitir el mensaje al siguiente sistema de envío de correo—y puede ser necesaria la tarea de varios sistemas de envío de correo para encaminar el mensaje desde su origen hasta su destino. Otros términos empleados en la literatura de bases de datos y similares para hacer referencia a los flujos de trabajo son flujo de tareas y aplicaciones multisistema. Las tareas del flujo de trabajo a veces se denominan pasos. En general, los flujos de trabajo pueden implicar a una o varias personas. Por ejemplo, considérese el procesamiento de un préstamo. El flujo de trabajo correspondiente aparece en la Figura 25.4. La persona que desea un préstamo rellena un formulario, que es revisado por el encargado de los préstamos. Un empleado que procesa las solicitudes de préstamos comprueba los datos del formulario, usando fuentes como las sucursals de referencia de préstamo. Cuando se ha reunido toda la información solicitada, el encargado de los préstamos puede que decida conceder el préstamo; puede que esa decisión tenga que ser aprobada por uno o más empleados de rango superior, después de lo cual se podrá conceder el prés-

Aplicación de flujo de trabajo encaminamiento de correo electrónico procesamiento de préstamos procesamiento de pedidos de compra

Tarea habitual mensaje de correo electrónico procesamiento de formularios procesamiento de formularios

Figura 25.3

Entidad típica de procesamiento sistemas de envío de correo electrónico personas, software de aplicaciones personas, software de aplicaciones, SGBD

Ejemplos de flujos de trabajo.

www.detodoprogramacion.com


782

Capítulo 25

Procesamiento avanzado de transacciones

solicitud de préstamo

cliente

encargado de préstamos

rechazo concesión del préstamo Figura 25.4

aceptación

comprobación empleado de rango superior

Flujo de trabajo en el procesamiento de préstamos.

tamo. Cada persona de este flujo de trabajo realiza una tarea; en un banco que no tenga automatizada la tarea de procesamiento de los préstamos, la coordinación de las tareas suele ejecutarse pasando la solicitud del préstamo con notas y otra información adjuntas de un empleado al siguiente. Otros ejemplos de flujos de trabajo son el procesamiento de notas de gastos, de pedidos de compra y de transacciones de tarjetas de préstamo. Hoy en día es más probable que toda la información relativa a un flujo de trabajo se almacene en forma digital en una o más computadoras y, con el auge de las redes, la información puede transferirse con facilidad de una computadora a otra. Por tanto, es viable que las organizaciones automaticen sus flujos de trabajo. Por ejemplo, para automatizar las tareas implicadas en el procesamiento de los préstamos, se puede almacenar la solicitud de préstamo y la información asociada en una base de datos. El propio flujo de trabajo implica, entonces, la transferencia de la responsabilidad de una persona a la siguiente y, posiblemente, incluso a programas que pueden capturar de manera automática la información necesaria. Las personas implicadas pueden coordinar sus actividades mediante el correo electrónico. Los flujos de trabajo están llegando a ser cada vez más importantes por muchas razones en y entre las organizaciones. Muchas organizaciones tienen actualmente múltiples sistemas de software que necesitan trabajar juntos. Por ejemplo, cuando un empleado entra a trabajar en una organización, su información puede tener que ser proporcionada al sistema de nóminas, al sistema de bibliotecas, a los sistemas de autentificación que permiten que el usuario inicie sesión en las computadoras, a las cuentas de un sistema que gestione las cuentas de la cafetería, etc. Las actualizaciones, como cuando el empleado cambia su estado o deja la organización, también tienen que ser propagadas a todos los sistemas. Las organizaciones están automatizando cada vez más sus servicios; por ejemplo, un proveedor puede proporcionar un sistema automatizado para que los clientes realicen sus pedidos. Cuando se realiza un pedido es posible que se deban llevar a cabo varias tareas, como reservar tiempo de producción para crear el producto pedido y tiempo del servicio de entrega para entregar el producto. Hay que abordar dos actividades, en general, para automatizar un flujo de trabajo. La primera es la especificación del flujo de trabajo: detallar las tareas que hay que ejecutar y definir los requisitos de la ejecución. El segundo problema es la ejecución del flujo de trabajo, que hay que llevar a cabo mientras se proporcionan las salvaguardas de los sistemas tradicionales de bases de datos relativas a corrección de los cálculos e integridad y durabilidad de los datos. Por ejemplo, no resulta aceptable que se pierda una solicitud de préstamo o una nota, ni que se procese más de una vez, debido a un fallo del sistema. La idea subyacente a los flujos de trabajo transaccionales es usar y ampliar los conceptos de las transacciones al contexto de los flujos de trabajo. Las dos actividades se complican por el hecho de que muchas organizaciones usan varios sistemas de procesamiento de la información administrados de manera independiente que, en la mayor parte de los casos, se desarrollaron por separado para automatizar funciones diferentes. Puede que las actividades del flujo de trabajo exijan interacciones entre varios de esos sistemas, cada uno de las cuales lleva a cabo una tarea, así como interacciones con las personas. En los últimos años se han desarrollado varios sistemas de flujo de trabajo. Aquí se estudiarán las propiedades de los sistemas de flujo de trabajo en un nivel relativamente abstracto, sin descender a los detalles de ningún sistema concreto.

www.detodoprogramacion.com


25.2

Flujos de trabajo de transacciones

783

25.2.1 Especi cación de los ujos de trabajo

No hace falta modelar los aspectos internos de cada tarea con vistas a la especificación y gestión de un flujo de trabajo. En una vista abstracta de las tareas, cada tarea puede usar los parámetros almacenados en sus variables de entrada, recuperar y actualizar los datos del sistema local, almacenar los resultados en sus variables de salida y se la puede consultar sobre su estado de ejecución. En cualquier momento de la ejecución el estado del flujo de trabajo consiste en el conjunto de estados de las tareas constituyentes del flujo de trabajo, y los estados (valores) de todas las variables de la especificación del flujo de trabajo. La coordinación de las tareas puede especificarse de manera estadística o dinámica. La especificación estática define las tareas— y las dependencias entre ellas—antes de que comience la ejecución del flujo de trabajo. Por ejemplo, las tareas del flujo de trabajo de las notas de gastos pueden consistir en la aprobación de las notas por una secretaria, un gestor y un contable, en ese orden, y, finalmente, en la entrega de un cheque. Las dependencias entre las tareas puede ser sencilla—hay que completar cada tarea antes de que comience la siguiente. Una generalización de esta estrategia es la imposición de una condición previa a la ejecución de cada tarea del flujo de trabajo, de modo que todas las tareas posibles del flujo de trabajo y sus dependencias se conozcan por anticipado, pero que sólo se ejecuten aquellas tareas cuyas condiciones previas se satisfagan. Las condiciones previas pueden definirse mediante dependencias como las siguientes: • El estado de ejecución de otras tareas—por ejemplo, “la tarea ti no puede comenzar hasta que la tarea tj haya finalizado”, o “la tarea ti debe abortarse si la tarea tj se ha comprometido”. • Los resultados de otras tareas—por ejemplo, “la tarea ti puede comenzar si la tarea tj devuelve un valor mayor que veinticinco”, o “la tarea de aprobación por el gestor puede comenzar si la tarea de aprobación por la secretaria devuelve el resultado ’Aceptar’”. • Las variables externas modificadas por los eventos externos—por ejemplo, “la tarea ti no puede iniciarse antes de las nueve de la mañana”, o “la tarea ti debe iniciarse antes de que transcurran veinticuatro horas desde la finalización de la tarea tj ”. Las dependencias pueden combinarse mediante los conectores lógicos (or, and, not) para formar condiciones previas complejas de planificación. Un ejemplo de la planificación dinámica de las tareas son los sistemas de encaminamiento del correo electrónico. La tarea que hay que programar a continuación para cada mensaje de correo depende de la dirección de destino de ese mensaje y de los encaminadores intermedios se hallan en funcionamiento. 25.2.2 Requisitos de atomicidad ante fallos de los ujos de trabajo

El diseñador del flujo de trabajo puede especificar sus requisitos de atomicidad ante fallos de acuerdo con su semántica. El concepto tradicional de atomicidad ante fallos exige que el fallo de cualquier tarea de lugar al fallo del flujo de trabajo. Sin embargo, un flujo de trabajo puede, en muchos casos, sobrevivir al fallo de una de sus tareas—por ejemplo, ejecutando una tarea funcionalmente equivalente en otro sitio. Por tanto, se debe permitir al diseñador que defina los requisitos de atomicidad ante fallos del flujo de trabajo. El sistema debe garantizar que cada ejecución de un flujo de trabajo termine en un estado que satisfaga los requisitos de atomicidad ante fallos definidos por el diseñador. Esos estados se denominan estados de terminación aceptables del flujo de trabajo. Todos los demás estados del flujo de trabajo constituyen un conjunto de estados de terminación no aceptables, en los que puede que se violen los requisitos de atomicidad de los fallos. Los estados aceptables de terminación pueden declararse comprometidos o abortados. Un estado aceptable de terminación comprometido es un estado de ejecución en el que los objetivos del flujo de trabajo se han conseguido. Por el contrario, un estado aceptable de terminación abortado es un estado válido de terminación en el que el flujo de trabajo no ha logrado alcanzar sus objetivos. Si se ha alcanzado un estado aceptable de terminación abortado hay que deshacer todos los efectos indeseables de la ejecución parcial del flujo de trabajo de acuerdo con los requisitos de atomicidad ante fallos del flujo de trabajo.

www.detodoprogramacion.com


784

Capítulo 25

Procesamiento avanzado de transacciones

El flujo de trabajo debe alcanzar un estado aceptable de terminación incluso en caso de fallo del sistema. Por tanto, si el flujo de trabajo se hallaba en un estado no aceptable de terminación en el momento del fallo, durante la recuperación del sistema hay que llevarlo a un estado aceptable de terminación (bien sea abortado, bien comprometido). Por ejemplo, en el flujo de trabajo del procesamiento de los préstamos, en el estado final, o bien se comunica al solicitante del préstamo que no se le puede conceder, o se le abona el importe solicitado. En caso de fallo como puede ser un fallo de larga duración del sistema de verificación, puede devolverse la solicitud de préstamo al solicitante con una explicación adecuada; este resultado constituiría una terminación abortada aceptable. Una terminación comprometida aceptable sería la aceptación o el rechazo de la solicitud. En general, las tareas pueden comprometer y liberar sus recursos antes de que el flujo de trabajo alcance un estado de terminación. Sin embargo, si la transacción multitarea aborta posteriormente, su atomicidad ante fallos puede que exija que se deshagan todos los efectos de las tareas ya completadas (por ejemplo, las subtransacciones comprometidas) ejecutando tareas compensadoras (como las subtransacciones). La semántica de la compensación exige que la transacción compensadora acabe completando su ejecución con éxito, quizás tras varios reenvíos. En el flujo de trabajo del procesamiento de las notas de gastos, por ejemplo, puede que se reduzca el importe del presupuesto del departamento debido a la aprobación inicial de una nota de gastos por el gestor. Si posteriormente se rechaza esa nota, debido a un fallo o por otro motivo, puede que haya que restaurar el presupuesto mediante una transacción compensadora.

25.2.3 Ejecución de los ujos de trabajo

La ejecución de las tareas puede controlarla un coordinador humano o un sistema de software denominado sistema gestor de flujos de trabajo. Los sistemas gestores de flujos de trabajo consisten en un planificador, los agentes para las tareas y un mecanismo para consultar el estado del sistema del flujo de trabajo. Cada agente de tarea controla la ejecución de una tarea por una entidad de procesamiento. El planificador es un programa que procesa los flujos de trabajo remitiendo diferentes tareas para su ejecución, controlando los diferentes eventos y evaluando las condiciones relativas a las dependencias entre las tareas. El planificador puede remitir una tarea para su ejecución (a un agente de tareas) o solicitar que se aborte una tarea previamente remitida. En el caso de las transacciones con múltiples bases de datos, las tareas son subtransacciones y las entidades de procesamiento son sistemas gestores de bases de datos locales. De acuerdo con las especificaciones del flujo de trabajo, el planificador hace que se cumplan las dependencias de planificación y es responsable de asegurar que las tareas alcancen estados aceptables de terminación. Hay tres alternativas de desarrollo en la arquitectura de los sistemas gestores de flujos de trabajo. La arquitectura centralizada tiene un solo planificador que programa las tareas de todos los flujos de trabajo que se ejecutan de manera concurrente. La arquitectura parcialmente distribuida tiene un planificador para cada flujo de trabajo. Cuando los problemas de la ejecución concurrente pueden separarse de la función de planificación, esta opción es una elección natural. La arquitectura completamente distribuida no tiene planificador, pero los agentes de tareas coordinan su ejecución comunicándose entre sí para satisfacer las dependencias entre las tareas y otros requisitos de ejecución del flujo de trabajo. Los sistemas de ejecución de flujos de trabajo siguen el enfoque totalmente distribuido que se acaba de describir y están basados en la mensajería. La mensajería puede implementarse mediante mecanismos de mensajería persistente. Algunas implementaciones usan el correo electrónico para la mensajería; estas implementaciones proporcionan muchas de las características de la mensajería persistente, pero generalmente no garantizan la atomicidad de la entrega de los mensajes y el compromiso de las transacciones. Cada sitio tiene un agente de tareas que ejecuta las tareas recibidas mediante los mensajes. Puede que la ejecución también implique la entrega de mensajes a personas, que tienen que llevar a cabo alguna acción. Cuando se completa una tarea en un sitio y hay que procesarla en otro sitio, el agente de tareas transmite un mensaje al sitio siguiente. El mensaje contiene toda la información relevante sobre la tarea que hay que realizar. Estos sistemas de flujos de trabajo basados en mensajes resultan especial-

www.detodoprogramacion.com


25.2

Flujos de trabajo de transacciones

785

mente útiles en las redes que se pueden desconectar durante parte del tiempo, como las redes de acceso telefónico. El enfoque centralizado se usa en sistemas de flujos de trabajo en que los datos se almacenan en una base de datos central. El planificador notifica a los diferentes agentes, como pueden ser las personas o los programas informáticos, que hay que llevar a cabo una tarea y realiza un seguimiento de su finalización. Resulta más sencillo realizar un seguimiento del estado del flujo de trabajo con el enfoque centralizado que con el enfoque completamente distribuido. El planificador debe garantizar que termine el flujo de trabajo en uno de los estados aceptables de terminación especificados. Idealmente, antes de intentar ejecutar un flujo de trabajo, el planificador debe examinarlo para comprobar si puede terminar en un estado no aceptable. Si el planificador no puede garantizar que el flujo de trabajo termine en un estado aceptable, debe rechazar esas especificaciones sin intentar ejecutar el flujo de trabajo. Por ejemplo, considérese un flujo de trabajo consistente en dos tareas representadas por las subtransacciones S1 y S2 , con los requisitos de atomicidad ante fallos que indican que se deben comprometer las dos subtransacciones o ninguna de ellas. Si S1 y S2 no proporcionan estados preparados para comprometerse (para un compromiso de dos fases) y, además, no tienen transacciones compensadoras, es posible alcanzar un estado en que se comprometa una subtransacción y se aborte la otra, y no haya manera de llevar a las dos al mismo estado. Por tanto, esa especificación del flujo de trabajo es insegura, y debe rechazarse. Los controles de seguridad como el que se acaba de describir pueden ser imposibles o poco prácticos de implementar en el planificador; pasa a ser, entonces, responsabilidad de la persona que diseña la especificación del flujo de trabajo asegurarse de que el flujo de trabajo sea seguro. 25.2.4 Recuperación en los ujos de trabajo

El objetivo de la recuperación en los flujos de trabajo es hacer que se cumpla la atomicidad ante fallos de los flujos de trabajo. Los procedimientos de recuperación deben asegurarse de que, si se produce un fallo en cualquiera de los componentes de procesamiento del flujo de trabajo (incluido el planificador), éste acabe alcanzando un estado aceptable de terminación (sea abortado o comprometido). Por ejemplo, el planificador puede continuar procesando tras el fallo y la recuperación, como si no hubiera pasado nada, lo que proporciona recuperabilidad hacia delante. En caso contrario, el planificador puede abortar todo el flujo de trabajo (es decir, alcanzar uno de los estados globales abortados). De cualquier forma, puede que haga falta comprometer algunas subtransacciones o incluso remitirlas para su ejecución (por ejemplo, las subtransacciones compensadoras). Se da por supuesto que las entidades de procesamiento implicadas en el flujo de trabajo tienen sus propios sistemas locales de recuperación y tratan sus fallos locales. Para recuperar el contexto del entorno de ejecución las rutinas de recuperación de los fallos deben restaurar la información de estado del planificador en el momento del fallo, incluida la información sobre el estado de ejecución de cada tarea. Por tanto, la información de estado correspondiente debe registrarse en almacenamiento estable. También hay que considerar el contenido de las colas de mensajes. Cuando un agente transfiere una tarea a otro, la transferencia debe ejecutarse exactamente una vez: si la transferencia tiene lugar dos veces, puede que se ejecute dos veces una tarea; si no se produce la transferencia, puede que se pierda la tarea. La mensajería persistente (Apartado 22.4.3) proporciona exactamente las características para asegurar una transferencia positiva y única. 25.2.5 Sistemas gestores de ujos de trabajo

Los flujos de trabajo suelen codificarse a mano como parte de los sistemas de aplicaciones. Por ejemplo, los sistemas de planificación de los recursos de las empresas (Enterprise Resource Planning, ERP), que ayudan a coordinar las actividades en toda la empresa, tienen incorporados numerosos flujos de trabajo. El objetivo de los sistemas gestores de flujos de trabajo es simplificar la construcción de flujos de trabajo y hacerlos más dignos de confianza, permitiéndoles que se especifiquen en un modo de nivel elevado y se ejecuten de acuerdo con la especificación. Hay gran número de sistemas comerciales de gestión de flujos de datos; algunos, como FlowMark de IBM, son sistemas gestores de flujos de trabajo de propósito general, mientras que otros son específicos de flujos de trabajo concretos, como los sistemas de procesamiento de comandos o los sistemas de comunicación de fallos.

www.detodoprogramacion.com


786

Capítulo 25

Procesamiento avanzado de transacciones

En el mundo actual de organizaciones interconectadas, no es suficiente gestionar los flujos de trabajo exclusivamente en el interior de una organización. Los flujos de trabajo que atraviesan las fronteras organizativas se están volviendo cada vez más frecuentes. Por ejemplo, considérese un pedido realizado por una organización y comunicado a otra organización que lo atiende. En cada organización puede que haya un flujo de trabajo asociado con el pedido, y es importante que los flujos de trabajo puedan operar entre sí con objeto de minimizar la intervención humana. La Coalición de gestión de flujos de trabajo (Workflow Management Coalition) ha desarrollado estándares para la interoperatividad entre sistemas de flujos de trabajo. Los esfuerzos actuales de normalización usan XML como lenguaje subyacente para comunicar la información sobre el flujo de trabajo. Véanse las notas bibliográficas para obtener más información. 25.3 Comercio electrónico

El término comercio electrónico hace referencia al proceso de llevar a cabo varias actividades relacionadas con el comercio por medios electrónicos, principalmente por Internet. Entre los tipos de actividades figuran: • Actividades previas a la venta, necesarias para informar al posible comprador del producto o servicio que se desea vender. • El proceso de venta, que incluye las negociaciones sobre el precio y la calidad del servicio, y otros asuntos contractuales. • El mercado: cuando hay varios vendedores y varios compradores para un mismo producto, un mercado, como la bolsa, ayuda a negociar el precio que se va a pagar por el producto. Las subastas se usan cuando hay un único vendedor y varios compradores, y las subastas inversas se usan cuando hay un solo comprador y varios vendedores. • El pago de la compra. • Las actividades relacionadas con la entrega del producto o servicio. Algunos productos y servicios pueden entregarse por Internet; para otros, Internet sólo se usa para facilitar información sobre el envío y para realizar un seguimiento de los envíos de los productos. • Atención al cliente y servicio postventa. Las bases de datos se usan ampliamente para soportar estas actividades. Para algunas de las actividades el uso de las bases de datos es directo, pero hay aspectos interesantes de desarrollo de aplicaciones para las demás actividades. 25.3.1 Catálogos electrónicos

Cualquier sitio de comercio electrónico proporciona a los usuarios un catálogo de los productos y servicios que ofrece. Los servicios facilitados por los catálogos electrónicos pueden variar considerablemente. Como mínimo, un catálogo electrónico debe proporcionar servicios de exploración y de búsqueda para ayudar a los clientes a hallar el producto que buscan. Para ayudar en la exploración conviene que los productos estén organizados en una jerarquía intuitiva, de modo que unas pocas pulsaciones en los hipervínculos puedan llevar a los clientes a los productos en los que estén interesados. Las palabras clave facilitadas por el cliente (por ejemplo, “cámara digital” o “computadora”) deben acelerar el proceso de búsqueda de los productos solicitados. Los catálogos electrónicos también deben proporcionar un medio para que los clientes comparen con facilidad las alternativas para elegir entre los diferentes productos. Los catálogos electrónicos pueden personalizarse para los clientes. Por ejemplo, puede que un vendedor al por menor tenga un acuerdo con una gran empresa para venderle algunos productos con descuento. Un empleado de la empresa, al examinar el catálogo para adquirir productos para la empresa, debería ver los precios con el descuento acordado, en vez de con los precios normales. Debido a las restricciones legales sobre las ventas de algunos tipos de artículos, no se les deberían mostrar a los clientes menores de edad, o de ciertos estados o países, los artículos que no se les pueden vender legalmente.

www.detodoprogramacion.com


25.3

Comercio electrónico

787

Los catálogos también pueden personalizarse para usuarios individuales, de acuerdo con su historial de compras. Por ejemplo, se pueden ofrecer a los clientes frecuentes descuentos especiales en algunos productos. El soporte de esa personalización necesita que la información de los clientes y la información sobre precios o descuentos especiales y sobre restricciones a las ventas se guarde en una base de datos. También hay desafíos en el soporte de tasas de transacciones muy elevadas, que suelen abordarse guardando en la caché los resultados de las consultas o las páginas Web generadas. 25.3.2 Mercados

Cuando hay varios vendedores o varios compradores (o ambas cosas) para un producto, los mercados ayudan a negociar el precio que debe pagarse por el producto. Hay varios tipos diferentes de mercados: • En los sistemas de subastas inversas los compradores manifiestan sus necesidades y los vendedores pujan por proporcionar el artículo. El proveedor que ofrece el precio más bajo gana la subasta. En los sistemas de puja cerrada las pujas no se hacen públicas, mientras que en los sistemas de puja abierta las pujas sí se hacen públicas. • En las subastas hay varios compradores y un solo vendedor. Por simplificar, supóngase que sólo se vende un ejemplar de cada artículo. Los compradores pujan por los artículos que se venden y el que puja más alto por un artículo consigue comprarlo por el precio de la puja. Cuando hay varios ejemplares de un artículo las cosas se vuelven más complicadas: supóngase que hay cuatro artículos y puede que un comprador desee tres ejemplares a 10 e cada uno, mientras que otro desea dos copias por 13 e cada una. No es posible satisfacer ambas pujas. Si los artículos carecen de valor si no se venden (por ejemplo, billetes de avión, que deben venderse antes de que despegue el avión), el vendedor simplemente selecciona un conjunto de pujas que maximice los ingresos. En caso contrario, la decisión es más complicada. • En las bolsas, como puede ser una bolsa de valores, hay varios vendedores y varios compradores. Los compradores pueden especificar el precio máximo que desean pagar, mientras que los vendedores especifican el precio mínimo que desean. Suele haber un creador de mercado que casa las ofertas de compra y de venta y decide el precio de cada intercambio (por ejemplo, al precio de la oferta de venta). Existen otros tipos de mercados más complejos. Entre los aspectos de las bases de datos relacionados con el manejo de los mercados figuran: • Hay que autentificar a los que realizan las pujas antes de permitirles pujar. • Las pujas (de compra o de venta) deben registrarse de modo seguro en una base de datos. Hay que comunicar rápidamente las pujas al resto de las personas implicadas en el mercado (como pueden ser todos los compradores o todos los vendedores), que puede que sean numerosas. • Los retrasos en la difusión de las pujas pueden llevar a pérdidas financieras para algunos participantes. • Los volúmenes de los intercambios pueden resultar tremendamente grandes en tiempos de volatilidad de las bolsas, o hacia el final de las subastas. Por tanto, se usan para estos sistemas bases de datos de muy alto rendimiento con elevados grados de paralelismo. 25.3.3 Liquidación de pedidos

Una vez seleccionados los artículos (quizás mediante un catálogo electrónico) y determinado el precio (acaso mediante un mercado electrónico), hay que liquidar el pedido. La liquidación implica el pago y la entrega de las mercancías. Una manera sencilla pero poco segura de pagar electrónicamente consiste en enviar el número de una tarjeta de crédito. Hay dos problemas principales. En primer lugar, es posible el fraude con las tarjetas de crédito. Cuando un comprador paga mercancías físicas las empresas pueden asegurarse de que la

www.detodoprogramacion.com


788

Capítulo 25

Procesamiento avanzado de transacciones

dirección de entrega coincide con la del titular de la tarjeta, de modo que nadie más reciba la mercancía, pero para las mercancías entregadas de manera electrónica no es posible realizar esa comprobación. En segundo lugar, hay que confiar en que el vendedor sólo facture el artículo acordado y en que no pase el número de la tarjeta de crédito a personas no autorizadas que lo puedan usar de manera no adecuada. Se dispone de varios protocolos para los pagos seguros que evitan los dos problemas mencionados. Además, proporcionan una mayor intimidad, ya que no hay que dar al vendedor datos innecesarios del comprador y no se le facilitan a la compañía de la tarjeta de crédito información innecesaria de los artículos comprados. Toda la información transmitida debe cifrarse de modo que nadie que intercepte los datos por la red pueda averiguar su contenido. El cifrado con claves pública y privada se usa mucho para esta tarea. Los protocolos también deben evitar los ataques de personas intermedias, en los que alguien puede suplantar al banco o a la compañía de la tarjeta de crédito, o incluso al vendedor o al comprador y sustraer información secreta. La suplantación puede realizarse pasando una clave falsa como si fuera la clave pública de otra persona (el banco, la compañía de la tarjeta de crédito, el comerciante o el comprador). La suplantación se evita mediante un sistema de certificados digitales, en el que las claves públicas vienen firmadas por una agencia de certificación cuya clave pública es bien conocida (o que, a su vez, tiene su clave pública certificada por otra agencia de certificación, y así hasta llegar a una clave que sea bien conocida). A partir de la clave pública bien conocida el sistema puede autentificar las otras claves comprobando los certificados en una secuencia inversa. Los certificados digitales se describieron anteriormente en el Apartado 8.8.3.3. El protocolo transacciones electrónicas seguras (Secure Electronic Transaction, SET) es uno de los protocolos de pago seguro. El protocolo necesita varias rondas de comunicación entre el comprador, el vendedor y el banco para garantizar la seguridad de la transacción. También hay sistemas que ofrecen más anonimato, parecido al proporcionado por el dinero físico en efectivo. El sistema de pagos DigiCash es uno de esos sistemas. Cuando se realiza un pago en estos sistemas no es posible identificar al comprador. Sin embargo, la identificación del comprador resulta muy sencilla con las tarjetas de crédito e, incluso en el caso de SET, es posible identificar al comprador con la colaboración de la compañía de la tarjeta de crédito o del banco.

25.4 Bases de datos en memoria principal

Para permitir una velocidad elevada de procesamiento de transacciones (centenares o millares de transacciones por segundo) hay que usar hardware de alto rendimiento y aprovechar el paralelismo. Estas técnicas, por sí solas, no obstante, resultan insuficientes para obtener tiempos de respuesta muy bajos, ya que las operaciones de E/S de disco siguen constituyendo un cuello de botella—se necesitan alrededor de diez milisegundos para cada operación de E/S y esta cifra no se ha reducido a una velocidad comparable con el aumento en la velocidad de los procesadores. Las operaciones de E/S suele ser el cuello de botella de las operaciones de lectura y de los compromisos de las transacciones. La elevada latencia de los discos (alrededor de diez milisegundos de promedio) no sólo aumenta el tiempo necesario para tener acceso a un elemento de datos, sino que también limita el número de accesos por segundo. Se puede hacer un sistema de bases de datos menos ligado a los discos aumentando el tamaño de la memoria intermedia de la base de datos. Los avances en la tecnología de la memoria principal permiten construir memorias principales de gran tamaño con un coste relativamente bajo. Hoy en día los sistemas comerciales de sesenta y cuatro bits pueden soportar memorias principales de decenas de gigabytes. Para algunas aplicaciones, como el control en tiempo real, es necesario almacenar los datos en la memoria principal para cumplir los requisitos de rendimiento. El tamaño de memoria exigido para la mayoría de estos sistemas no resulta excepcionalmente grande, aunque hay unas cuantas aplicaciones que exigen que sean residentes en la memoria varios gigabytes de datos. Dado que el tamaño de la memoria ha estado creciendo con una velocidad muy elevada, se puede suponer que los datos de cada vez más aplicaciones puedan caber en la memoria principal. Las memorias principales de gran tamaño permiten el procesamiento más rápido de las transacciones, ya que los datos están residentes en la memoria. No obstante, sigue habiendo limitaciones relacionadas con los discos:

www.detodoprogramacion.com


25.4

Bases de datos en memoria principal

789

• Hay que guardar en almacenamiento estable los registros del registro histórico antes de comprometer una transacción. El rendimiento mejorado que hace posible la memoria principal de gran tamaño puede hacer que el proceso de registro se convierta en un cuello de botella. Se puede reducir el tiempo de compromiso creando un búfer de registro estable en la memoria principal, usando RAM no volátil (implementada, por ejemplo, mediante memoria sustentada por baterías). La sobrecarga impuesta por el registro también puede reducirse mediante la técnica de compromiso en grupo estudiada más adelante en este apartado. La productividad (el número de transacciones por segundo) sigue estando limitada por la velocidad de transferencia de datos del disco de registro. • Sigue habiendo que escribir los bloques de la memoria intermedia marcados como modificados por las transacciones comprometidas para que se reduzca la cantidad de registro histórico que hay que volver a ejecutar en el momento de la recuperación. Si la velocidad de actualización es extremadamente elevada, la velocidad de transferencia de los datos al disco puede convertirse en un cuello de botella. • Si el sistema falla, se pierde toda la memoria principal. En la recuperación el sistema tiene la memoria intermedia de la base de datos vacía y hay que introducir desde el disco los elementos de datos cuando se tenga acceso a ellos. Por tanto, incluso una vez que esté completa la recuperación hace falta algo de tiempo antes de que se cargue completamente la base de datos en memoria principal y se pueda reanudar el procesamiento de transacciones de alta velocidad. Por otro lado, las bases de datos en memoria principal ofrecen oportunidades para la optimización: • Como la memoria resulta más costosa que el espacio de disco, hay que diseñar las estructuras internas de los datos de la memoria principal para reducir los requisitos de espacio. No obstante, las estructuras de datos pueden tener punteros que atraviesen varias páginas a diferencia de los de las bases de datos en disco, en las que el coste de que la operación de E/S atraviese varias páginas resultaría excesivamente elevado. Por ejemplo, las estructuras arbóreas de las bases de datos en memoria principal pueden ser relativamente profundas, a diferencia de los árboles B+ , pero deben minimizar los requisitos de espacio. • No hace falta clavar en la memoria las páginas de la memoria intermedia antes de que se tenga acceso a los datos, ya que las páginas de la memoria intermedia no se sustituyen nunca. • Las técnicas de procesamiento de consultas deben diseñarse para minimizar la sobrecarga de espacio, de modo que no se superen los límites de la memoria mientras se evalúa una consulta; esa situación daría lugar a que se paginara el área de intercambio y ralentizaría el procesamiento de la consulta. • Una vez eliminado el cuello de botella de las operaciones de E/S del disco, pueden convertirse en cuellos de botella operaciones como los bloqueos y los pestillos. Hay que eliminar estos cuellos de botella mediante mejoras en la implementación de estas operaciones. • Los algoritmos de recuperación pueden optimizarse, ya que rara vez hace falta borrar las páginas para hacer sitio a otras páginas. TimesTen y DataBlitz son dos productos de bases de datos en memoria principal que aprovechan varias de estas optimizaciones, mientras que la base de datos de Oracle ha añadido características especiales para soportar memorias principales de tamaño muy grande. Se da información adicional sobre las bases de datos en memoria principal en las referencias de las notas bibliográficas. El proceso de comprometer una transacción T exige que estos registros se escriban en almacenamiento estable: • Todos los registros del registro histórico asociados con T que no se hayan remitidos al almacenamiento estable • El registro <comprometer T> del registro histórico

www.detodoprogramacion.com


790

Capítulo 25

Procesamiento avanzado de transacciones

Estas operaciones de salida suelen exigir la salida de bloques que sólo se hallan parcialmente llenos. Para asegurarse de que se saquen bloques casi llenos se usa la técnica de compromiso en grupo. En lugar de intentar comprometer T cuando se complete T, el sistema espera hasta que se hayan completado varias transacciones, o hasta que haya pasado un determinado periodo de tiempo desde que se completó la ejecución de una transacción. Luego compromete el grupo de transacciones que están esperando, todas juntas. Los bloques escritos en el registro histórico en almacenamiento estable contienen registros de varias transacciones. Mediante una cuidadosa selección del tamaño del grupo y del tiempo máximo de espera, el sistema puede asegurarse de que los bloques estén llenos cuando se escriben en el almacenamiento estable sin hacer que las transacciones esperen demasiado. Esta técnica da como resultado, en promedio, menos operaciones de salida por cada transacción comprometida. Aunque el compromiso en grupo reduce la sobrecarga impuesta por el registro histórico, da lugar a un ligero retraso en el compromiso de las transacciones que llevan a cabo actualizaciones. El retraso puede hacerse bastante pequeño (del orden de diez milisegundos), lo que resulta aceptable para muchas aplicaciones. Estos retrasos pueden eliminarse si los discos o los controladores de disco soportan los búferes de RAM no volátil para las operaciones de escritura. Las transacciones pueden comprometerse en cuanto la operación de escritura se lleva a cabo en la memoria intermedia de RAM no volátil. En este caso, no hay necesidad de compromiso en grupo. Obsérvese que el compromiso en grupo resulta útil incluso en bases de datos con datos residentes en disco.

25.5 Sistemas de transacciones de tiempo real

Las restricciones de integridad que se han considerado hasta ahora corresponden a los valores almacenados en la base de datos. En determinadas aplicaciones las restricciones incluyen tiempos límite en los que se tiene que haber completado una tarea. Entre estas aplicaciones están la gestión de factorías, el control del tráfico y la planificación. Cuando se incluyen tiempos límite, la corrección de la ejecución ya no es exclusivamente un problema de consistencia de la base de datos. Por el contrario, hay que preocuparse por el número de tiempos límite sobrepasados y por el tiempo que hace que se sobrepasaron. Los tiempos límite se caracterizan de la manera siguiente: • Tiempo límite estricto. Pueden producirse problemas graves, como fallos del sistema, si no se completa una tarea antes de su tiempo límite. • Tiempo límite firme. La tarea no tiene ningún valor si se completa después del tiempo límite. • Tiempo límite flexible. La tarea tiene un valor decreciente si se completa tras el tiempo límite, y el valor se aproxima a cero a medida que aumenta el retraso. Los sistemas con tiempos límite se denominan sistemas de tiempo real. La gestión de transacciones en los sistemas de tiempo real debe tener en cuenta los tiempos límite. Si el protocolo de control de concurrencia determina que la transacción Ti debe esperar, puede hacer que Ti supere el tiempo límite. En esos casos, puede que resulte preferible adelantar la transacción que mantiene el bloqueo y permitir que Ti siga adelante. El adelantamiento debe usarse con cuidado, no obstante, ya que el tiempo perdido por la transacción adelantada (debido al retroceso y al renicio) puede hacer que la transacción supere su tiempo límite. Por desgracia, es difícil determinar si es preferible retroceder o esperar en una situación dada. Una de las principales dificultades para soportar las restricciones de tiempo real surge de la variabilidad en el tiempo de ejecución de las transacciones. En el caso más favorable, todos los accesos a los datos hacen referencia a datos de la memoria intermedia de la base de datos. En el peor de los casos, cada acceso hace que se escriba una página de la memoria intermedia en el disco (precedida de los registros del registro histórico necesario), seguido de la lectura desde el disco de la página que contiene los datos a los que hay que tener acceso. Como los dos o más accesos al disco necesarios en el peor de los casos tardan varios órdenes de magnitud más que las referencias a la memoria principal necesarias en el caso más favorable, el tiempo de ejecución de las transacciones puede estimarse con muy poca precisión si

www.detodoprogramacion.com


25.6

Transacciones de larga duración

791

los datos están residentes en el disco. Por tanto, se suelen usar las bases de datos en memoria principal si hay que cumplir restricciones de tiempo real. Sin embargo, aunque los datos estén residentes en la memoria principal, la variabilidad del tiempo de ejecución surge de las esperas de los bloqueos, de los abortos de las transacciones, etc. Los investigadores han dedicado esfuerzos considerables al control de concurrencia para las bases de datos de tiempo real. Han ampliado los protocolos de bloqueo para conceder una prioridad más elevada a las transacciones con tiempos límite más próximos. Han determinado que los protocolos de concurrencia optimistas tienen un buen comportamiento en las bases de datos de tiempo real; es decir, estos protocolos dan lugar a menos tiempos límite sobrepasados incluso que los protocolos de bloqueo ampliados. Las notas bibliográficas proporcionan referencias para la investigación en el área de las bases de datos de tiempo real. En los sistemas de tiempo real, los tiempos límite, y no la velocidad absoluta, son el aspecto más importante. El diseño de sistemas de tiempo real implica asegurarse de que hay suficiente capacidad de procesamiento como para respetar las tiempos límite sin necesitar excesivos recursos de hardware. La consecución de este objetivo, pese a la variabilidad de los tiempos de ejecución resultante de la gestión de las transacciones, sigue constituyendo un problema sin resolver. 25.6 Transacciones de larga duración

El concepto de transacción se desarrolló inicialmente en el contexto de las aplicaciones de procesamiento de datos, en el que la mayor parte de las transacciones son de corta duración y no interactivas. Aunque las técnicas presentadas aquí y, anteriormente, en los Capítulos 15, 16 y 17 funcionan bien en esas aplicaciones, surgen problemas graves cuando se aplica este concepto a sistemas de bases de datos que implican la interacción con personas. Esas transacciones tienen las siguientes propiedades principales: • Larga duración. Una vez que una persona interactúa con una transacción activa esa transacción se transforma en una transacción de larga duración desde la perspectiva de la computadora, ya que el tiempo de respuesta de las personas es lento en comparación con la velocidad de las computadoras. Además, en las aplicaciones de diseño, la actividad humana puede suponer horas, días o periodos incluso más prolongados. Por tanto, las transacciones pueden ser de larga duración en términos humanos, además de serlo en términos de la máquina. • Exposición de datos no comprometidos. Los datos generados y mostrados a los usuarios por las transacciones de larga duración no están comprometidos, ya que la transacción puede abortarse. Por tanto, los usuarios—y, en consecuencia, las demás transacciones—pueden verse forzados a leer datos no comprometidos. Si varios usuarios están colaborando en un proyecto puede que las transacciones de los usuarios necesiten intercambiar datos antes de comprometer las transacciones. • Subtareas. Cada transacción interactiva puede consistir en un conjunto de subtareas iniciadas por el usuario. Puede que el usuario desee abortar una subtarea sin hacer necesariamente que aborte toda la transacción. • Recuperabilidad. Resulta inaceptable abortar una transacción interactiva de larga duración debido a un fallo del sistema. La transacción activa debe recuperarse hasta un estado que existiera poco antes del fallo para que se pierda una cantidad de trabajo humano relativamente pequeña. • Rendimiento. El buen rendimiento de los sistemas interactivos de transacciones se define como tiempo de respuesta rápido. Esta definición difiere de la de los sistemas no interactivos, en los que el objetivo es una productividad (número de transacciones por segundo) elevada. Los sistemas con productividad elevada hacen un uso eficiente de los recursos del sistema. Sin embargo, en el caso de las transacciones interactivas, el recurso más costoso es el usuario. Si hay que optimizar la eficiencia y la satisfacción del usuario, el tiempo de respuesta debe ser rápido (desde el punto de vista humano). En los casos en los que una tarea tarde mucho tiempo, el tiempo de respuesta debe ser predecible (es decir, la variabilidad de los tiempos de respuesta debe ser baja), de modo que los usuarios puedan administrar bien su tiempo.

www.detodoprogramacion.com


792

Capítulo 25

Procesamiento avanzado de transacciones

En los Apartados 25.6.1 a 25.6.5 se verá el motivo de que estas cinco propiedades sean incompatibles con las técnicas presentadas hasta ahora, y se estudiará el modo en que se pueden modificar dichas técnicas para acomodar las transacciones interactivas de larga duración.

25.6.1 Ejecuciones no secuenciables

Las propiedades que se han estudiado hacen poco práctico obligar a que se cumpla el requisito empleado en los capítulos anteriores de que sólo se permitan las planificaciones secuenciables. Cada uno de los protocolos de control de concurrencia del Capítulo 16 tiene efectos negativos sobre las transacciones de larga duración: • Bloqueo de dos fases. Cuando no se puede conceder un bloqueo, la transacción que lo ha solicitado se ve obligada a esperar a que se desbloquee el elemento de datos en cuestión. La duración de la espera es proporcional a la duración de la transacción que sostiene el bloqueo. Si el elemento de datos está bloqueado por una transacción de corta duración, se espera que el tiempo de espera sea breve (excepto en el caso de interbloqueos o de carga extraordinaria del sistema). Sin embargo, si el elemento de datos está bloqueado por una transacción de larga duración, la espera será prolongada. Los tiempos de espera elevados provocan tiempos de respuesta mayores y una mayor posibilidad de interbloqueos. • Protocolos basados en grafos. Los protocolos basados en grafos permiten que se liberen los bloqueos antes que con los protocolos de bloqueo de dos fases, y evitan los interbloqueos. Sin embargo, imponen una ordenación de los elementos de datos. Las transacciones deben bloquear los elementos de datos de manera consistente con esta ordenación. En consecuencia, puede que una transacción tenga que bloquear más datos de los que necesita. Además, la transacción debe mantener el bloqueo hasta que no haya posibilidades de que se vuelva a necesitar. Por tanto, es probable que se produzcan esperas por bloqueos de larga duración. • Protocolos basados en marcas temporales. Los protocolos de marcas temporales nunca necesitan que las transacciones esperen. Sin embargo, exigen que las transacciones se aborten bajo ciertas circunstancias. Si se aborta una transacción de larga duración, se pierde una cantidad sustancial de trabajo. Para las transacciones no interactivas este trabajo perdido supone un problema de rendimiento. Para las transacciones interactivas el problema también es de satisfacción de los usuarios. Resulta muy poco deseable que el usuario descubra que se han deshecho varias horas de trabajo. • Protocolos de validación. Al igual que los protocolos basados en las marcas temporales, los protocolos de validación hacen que se cumpla la secuencialidad mediante el aborto de transacciones. Por tanto, parece que el cumplimiento de la secuencialidad provoca esperas de larga duración, el aborto de transacciones de larga duración o ambas cosas. Hay resultados teóricos, citados en las notas bibliográficas, que sustentan esta conclusión. Cuando se consideran los problemas de las recuperaciones surgen dificultades adicionales con el cumplimiento de la secuencialidad. Ya se ha estudiado el problema de los retrocesos en cascada, en los que el aborto de una transacción puede conducir al aborto de otras transacciones. Este fenómeno no es deseable, especialmente para las transacciones de larga duración. Si se usa el bloqueo, se deben mantener bloqueos exclusivos hasta el final de la transacción, si hay que evitar el retroceso en cascada. Este mantenimiento de bloqueos exclusivos, no obstante, aumenta la duración del tiempo de espera de las transacciones. Por tanto, parece que el cumplimiento de la atomicidad de las transacciones debe llevar a una mayor probabilidad de las esperas de larga duración o a crear la posibilidad de retrocesos en cascada. Estas consideraciones son la base de los conceptos alternativos de corrección de las ejecuciones concurrentes y de la recuperación de transacciones que se considerarán en el resto de este apartado.

www.detodoprogramacion.com


25.6

Transacciones de larga duración

793

25.6.2 Control de concurrencia

El objetivo fundamental del control de concurrencia de las bases de datos es asegurarse de que la ejecución concurrente de las transacciones no da lugar a una pérdida de la consistencia de la base de datos. El concepto de secuencialidad puede usarse para conseguir este objetivo, ya que todas las planificaciones secuenciables conservan la consistencia de las bases de datos. No obstante, no todas las planificaciones que conservan la consistencia de las bases de datos son secuenciables. Por ejemplo, considérese nuevamente una base de datos bancaria que consista en dos cuentas, A y B, con el requisito de consistencia de que se conserve la suma A + B. Aunque la planificación de la Figura 25.5 no es secuenciable para conflictos, pese a todo, conserva la suma de A + B. También ilustra dos aspectos importantes del concepto de corrección sin secuencialidad. • La corrección depende de las restricciones de consistencia concretas de la base de datos. • La corrección depende de las propiedades de las operaciones llevadas a cabo por cada transacción. En general, no es posible llevar a cabo un análisis automático de las operaciones de bajo nivel de las transacciones y comprobar su efecto en las restricciones de consistencia de la base de datos. Sin embargo, hay técnicas más sencillas. Una de ellas es el uso de las restricciones de consistencia de la base de datos como base de una división de la base de datos en subbases de datos en las que se puede administrar por separado la concurrencia. Otra es el intento de tratar algunas operaciones aparte de leer y de escribir como operaciones fundamentales de bajo nivel y ampliar el control de concurrencia para trabajar con ellas. Las notas bibliográficas hacen referencia a otras técnicas para asegurar la consistencia sin exigir secuencialidad. Muchas de estas técnicas aprovechan variedades del control de concurrencia multiversión (véase el Apartado 17.5). A las aplicaciones de procesamiento de datos más antiguas que sólo necesitan una versión los protocolos multiversión les imponen una elevada sobrecarga de espacio para almacenar las versiones adicionales. Dado que muchas de las nuevas aplicaciones de bases de datos exigen el mantenimiento de las versiones de los datos, las técnicas de control de concurrencia que aprovechan varias versiones resultan prácticas. 25.6.3 Transacciones anidadas y multinivel

Las transacciones de larga duración pueden considerarse como conjuntos de subtareas relacionadas o subtransacciones. Al estructurar cada transacción como un conjunto de subtransacciones, se puede mejorar el paralelismo, ya que puede que sea posible ejecutar en paralelo varias subtransacciones. Además, es posible trabajar con los fallos de las subtransacciones (debidos a abortos, fallos del sistema, etc.) sin tener que hacer retroceder toda la transacción de larga duración.

T1 leer(A) A := A - 50 escribir(A)

T2

leer(B) B := B - 10 escribir(B) leer(B) B := B + 50 escribir(B) leer(A) A := A + 10 escribir(A) Figura 25.5

Planificación no secuenciable en cuanto a conflictos.

www.detodoprogramacion.com


794

Capítulo 25

Procesamiento avanzado de transacciones

Una transacción anidada o multinivel T consiste en un conjunto T = {t1 , t2 , . . . , tn } de subtransacciones y en un orden parcial P sobre T. Cada subtransacción ti de T puede abortar sin obligar a que T aborte. En lugar de eso, puede que T reinicie ti o simplemente escoja no ejecutar ti . Si se compromete ti , esa acción no hace que ti sea permanente (a diferencia de la situación del Capítulo 17). En vez de eso, ti se compromete con T, y puede que todavía aborte (o exija compensación—véase el Apartado 25.6.4) si T aborta. La ejecución de T no debe violar el orden parcial P. Es decir, si un trazo ti → tj aparece en el grafo de precedencia, ti → tj no debe estar en el cierre transitivo de P. El anidamiento puede tener varios niveles de profundidad, representando la subdivisión de una transacción en subtareas, subsubtareas, etc. En el nivel inferior de anidamiento se tienen las operaciones estándar de bases de datos leer y escribir que se han usado anteriormente. Si se permite a una subtransacción de T liberar los bloqueos al completarse, T se denomina transacción multinivel. Cuando una transacción multinivel representa una actividad de larga duración, a veces se denomina saga. De manera alternativa, si los bloqueos mantenidos por la subtransacción ti de T se asignan de manera automática a T al concluir ti , T se denomina transacción anidada. Aunque el principal valor práctico de las transacciones multinivel surja en las transacciones complejas de larga duración, se usará el sencillo ejemplo de la Figura 25.5 para mostrar el modo en que el anidamiento puede crear operaciones de nivel superior que pueden mejorar la concurrencia. Se reescribe la transacción T1 mediante las subtransacciones T1,1 y T1,2 , que llevan a cabo operaciones de suma o de resta: • T1 consiste en ¤ T1,1 , que resta 50 de A ¤ T1,2 , que suma 50 a B De manera parecida, se reescribe la transacción T2 mediante las subtransacciones T2,1 y T2,2 , que también llevan a cabo operaciones de suma o de resta: • T2 consiste en ¤ T2,1 , que resta 10 de B ¤ T2,2 , que suma 10 a A No se especifica ninguna ordenación para T1,1 , T1,2 , T2,1 ni T2,2 . Cualquier ejecución de estas subtransacciones generará un resultado correcto. La planificación de la Figura 25.5 corresponde a la planificación < T1,1 , T2,1 , T1,2 , T2,2 >. 25.6.4 Transacciones compensadoras

Para reducir la frecuencia de las esperas de larga duración se dispone que las actualizaciones no comprometidas se muestren otras transacciones que se ejecuten de manera concurrente. En realidad, las transacciones multinivel pueden permitir esta exposición. No obstante, la exposición de datos no comprometidos crea la posibilidad de retrocesos en cascada. El concepto de transacciones compensadoras ayuda a tratar este problema. Divídase la transacción T en varias subtransacciones t1 , t2 , . . . , tn . Una vez comprometida la subtransacción ti , libera sus bloqueos. Ahora, si hay que abortar la transacción del nivel externo T , hay que deshacer el efecto de sus subtransacciones. Supóngase que las subtransacciones t1 , . . . , tk se han comprometido y que tk+1 se estaba ejecutando cuando se tomó la decisión de abortar. Se pueden deshacer los efectos de tk+1 abortando esa subtransacción. Sin embargo, no es posible abortar las subtransacciones t1 , . . . , tk , puesto que ya se han comprometido. En lugar de eso, se ejecuta una nueva subtransacción tci , denominada transacción compensadora, para deshacer el efecto de cada subtransacción ti . Es necesario que cada subtransacción ti tenga su transacción compensadora tci . Las transacciones compensadoras deben ejecutarse en el orden inverso tck , . . . , tc1 . A continuación se ofrecen varios ejemplos de compensaciones: • Considérese la planificación de la Figura 25.5, que se ha demostrado que es correcta, aunque no secuenciable en cuanto a conflictos. Cada subtransacción libera sus bloqueos una vez se completa. Supóngase que T2 falla justo antes de su terminación, una vez que T2,2 ha liberado sus

www.detodoprogramacion.com


25.6

Transacciones de larga duración

795

bloqueos. Se ejecuta una transacción compensadora para T2,2 que resta 10 de A y una transacción compensadora para T2,1 que suma 10 a B. • Considérese una inserción en la base de datos por la transacción Ti que, como efecto lateral, provoca que se actualice el índice del árbol B+ . La operación de inserción puede haber modificado varios nodos del índice del árbol B+ . Otras transacciones pueden haber leído estos nodos al tener acceso a datos diferentes del registro insertado por Ti . Como en el Apartado 17.8, se puede deshacer la inserción eliminando el registro insertado por Ti . El resultado es un árbol B+ correcto y consistente, pero no necesariamente uno con exactamente la misma estructura que la que se tenía antes de que se iniciara Ti . Por tanto, la eliminación es una acción compensadora para la inserción. • Considérese una transacción de larga duración Ti que represente una reserva de viaje. La transacción T tiene tres subtransacciones: Ti,1 , que hace las reservas de billetes de avión; Ti,2 , que reserva los coches de alquiler; y Ti,3 , que reserva las habitaciones de hotel. Supóngase que el hotel cancela la reserva. En lugar de deshacer todas las Ti , se compensa el fallo de Ti,3 eliminando la reserva de hotel antigua y realizando una nueva. Si el sistema falla en medio de la ejecución de una transacción del nivel externo hay que hacer retroceder sus subtransacciones cuando se recupere. Las técnicas descritas en el Apartado 17.8 pueden usarse con este fin. La compensación del fallo de una transacción exige que se utilice la semántica de la transacción que ha fallado. Para determinadas operaciones, como el incremento o la inserción en un árbol B+ , la compensación correspondiente se define con facilidad. Para transacciones más complejas puede que los planificadores de la aplicación tengan que definir la forma correcta de compensación en el momento en que se codifique la transacción. Para las transacciones interactivas complejas puede que sea necesario que el sistema interactúe con el usuario para determinar la forma adecuada de compensación. 25.6.5 Problemas de implementación

Los conceptos sobre las transacciones estudiados en este apartado crean serias dificultades para su implementación. Aquí se presentan unos cuantos y se estudia el modo de abordar esos problemas. Las transacciones de larga duración deben sobrevivir a los fallos del sistema. Se puede asegurar que lo harán llevando a cabo una operación rehacer con las subtransacciones comprometidas, y llevando a cabo una operación deshacer o una compensación para cualquier subtransacción de corta duración que estuviera activa en el momento del fallo. Sin embargo, estas acciones sólo resuelven parte del problema. En los sistemas típicos de bases de datos los datos internos del sistema como las tablas de bloqueos y las marcas temporales de las transacciones se conservan en almacenamiento volátil. Para que se pueda reanudar una transacción de larga duración tras un fallo hay que restaurar esos datos. Por tanto, es necesario registrar no sólo las modificaciones de la base de datos, sino también las modificaciones de los datos internos del sistema correspondientes a las transacciones de larga duración. El registro histórico de las actualizaciones se hace más complicado cuando hay en la base de datos ciertos tipos de elementos de datos. Un elemento de datos puede ser un diseño CAD, el texto de un documento u otra forma de diseño compuesto. Estos elementos de datos son de gran tamaño físico. Por tanto, guardar los valores antiguos y nuevos del elemento de datos en un registro del registro histórico no resulta deseable. Hay dos enfoques para reducir la sobrecarga de asegurar la recuperabilidad de elementos de datos de gran tamaño: • Registro histórico de operaciones. Sólo se guardan en el registro histórico la operación llevada a cabo en el elemento de datos y el nombre del elemento de datos. El registro histórico de operaciones también se denomina registro histórico lógico. Para cada operación debe haber una operación inversa. Se lleva a cabo la operación deshacer usando la operación inversa y la operación rehacer usando la misma operación. La recuperación mediante el registro histórico de operaciones resulta más difícil, ya que rehacer y deshacer no son idempotentes. Además, el uso del registro lógico para una operación que actualice varias páginas resulta muy complicado debi-

www.detodoprogramacion.com


796

Capítulo 25

Procesamiento avanzado de transacciones

do al hecho de que algunas, pero no todas, las páginas actualizadas pueden haberse escrito en el disco, por lo que resulta difícil aplicar tanto rehacer como deshacer a la operación en la imagen del disco durante la recuperación. El uso del registro histórico físico de rehacer y registro histórico lógico de deshacer tal y como se describe en el Apartado 17.8 proporciona las ventajas de concurrencia del registro histórico lógico y evita los inconvenientes mencionados. • Registro histórico y paginación en la sombra. El registro se usa para las modificaciones de elementos de datos de pequeño tamaño, pero los elementos de datos de gran tamaño a menudo se hacen recuperables mediante una técnica de paginación en la sombra (véase el Apartado 15.3). Cuando se usa esta técnica es posible reducir la sobrecarga manteniendo sólo las páginas que realmente se modifiquen. Independientemente de la técnica usada, las complejidades introducidas por las transacciones de larga duración y los elementos de datos de gran tamaño complican el proceso de recuperación. Por tanto, es deseable permitir que algunos datos no esenciales queden exentos del registro, y confiar en las copias de seguridad fuera de línea y en la intervención de las personas. 25.7 Gestión de transacciones en varias bases de datos

Hay que recordar del Apartado 22.8 que un sistema con múltiples bases de datos crea la ilusión de una integración lógica de las bases de datos, en un sistema de bases de datos heterogéneo en el que los sistemas locales de bases de datos pueden usar diferentes modelos lógicos de datos y lenguajes de definición y de manipulación diferentes, y pueden diferenciarse en sus mecanismo de control de concurrencia y de gestión de las transacciones. Los sistemas con múltiples bases de datos soportan dos tipos de transacciones: 1. Transacciones locales. Estas transacciones las ejecuta cada sistema local de base de datos fuera del control del sistema con múltiples bases de datos. 2. Transacciones globales. Estas transacciones se ejecutan bajo el control del sistema con múltiples bases de datos. El sistema con múltiples bases de datos es consciente del hecho de que pueden ejecutarse transacciones locales en los sitios locales, pero no de las transacciones concretas que se ejecutan, ni de los datos a los que tienen acceso. Asegurar la autonomía local de cada sistema de bases de datos exige que no se realice ningún cambio en su software. Por tanto, el sistema de bases de datos de un sitio no puede comunicarse directamente con los de otros sitios para sincronizar la ejecución de transacciones globales activas en varios sitios. Dado que el sistema con múltiples bases de datos no tiene ningún control sobre la ejecución de las transacciones globales, cada sistema local debe usar un esquema de control de concurrencia (por ejemplo, el compromiso de dos fases o las marcas temporales) para asegurarse de que su planificación sea secuenciable. Además, en caso de bloqueo, cada sistema local debe poder protegerse contra la posibilidad de interbloqueos locales. La garantía de la secuencialidad local no es suficiente para asegurar la secuencialidad global. Como ejemplo, considérense dos transacciones globales T1 y T2 , cada una de las cuales tiene acceso y actualiza a dos elementos de datos, A y B, ubicados en los sitios S1 y S2 , respectivamente. Supóngase que las planificaciones locales son secuenciables. Sigue siendo posible que haya una situación en la que, en el sitio S1 , T2 siga a T1 , mientras que, en S2 , T1 siga a T2 , dando como resultado una planificación global no secuenciable. En realidad, aunque no haya concurrencia entre las transacciones globales (es decir, cada transacción global sólo se remite una vez que la anterior se compromete o aborta), la secuencialidad local no resulta suficiente para asegurar la secuencialidad global (véase el Ejercicio práctico 25.7). En función de la implementación de los sistemas locales de bases de datos puede que una transacción global no pueda controlar el comportamiento exacto de los bloqueos de sus subtransacciones. Por tanto, incluso si todos los sistemas locales de bases de datos siguen el bloqueo de dos fases, puede que sólo sea posible asegurar que cada transacción local siga las reglas del protocolo. Por ejemplo, puede que

www.detodoprogramacion.com


25.7

Gestión de transacciones en varias bases de datos

797

un sistema local de bases de datos comprometa su subtransacción y libere sus bloqueos mientras que la subtransacción de otro sistema local se sigue ejecutando. Si los sistemas locales permiten el control del comportamiento de los bloqueos y todos los sistemas siguen el bloqueo de dos fases, el sistema con múltiples bases de datos puede asegurar que las transacciones globales se bloqueen en la modalidad de dos fases y que los puntos de bloqueo de las transacciones en conflicto definan su orden global de secuencia. Aunque diferentes sistemas locales siguen diferentes mecanismos de control de concurrencia, sin embargo, esta forma directa de control global no funciona. Hay muchos protocolos para asegurar la consistencia pese a la ejecución concurrente de las transacciones globales y locales en los sistemas con múltiples bases de datos. Algunos se basan en imponer las condiciones suficientes para asegurar la secuencialidad global. Otros sólo aseguran una forma de consistencia más débil que la secuencialidad, pero la consiguen por medios menos restrictivos. Se considerará uno de estos últimos esquemas: la secuencialidad de dos niveles. El Apartado 25.6 describe más enfoques de la consistencia sin secuencialidad; se citan otros enfoques en las notas bibliográficas. Un problema relacionado en los sistemas de bases de datos es el del compromiso atómico global. Si todos los sistemas locales siguen el protocolo de compromiso de dos fases, puede usarse este protocolo para conseguir la atomicidad global. No obstante, puede que los sistemas locales no diseñados para ser parte de un sistema distribuido no puedan participar en este protocolo. Aunque un sistema local pueda soportar el compromiso de dos fases, la organización propietaria del sistema puede que no desee permitir las esperas en los casos en los que se producen bloqueos. En esos casos, pueden alcanzarse compromisos que permitan la falta de atomicidad en determinadas modalidades de fallo. En la bibliografía proporcionada hay un tratamiento más extenso de estos asuntos (véanse las notas bibliográficas). 25.7.1 Secuencialidad de dos niveles

La secuencialidad de dos niveles (S2N) asegura la secuencialidad en dos niveles del sistema: • Cada sistema local de bases de datos asegura la secuencialidad local entre sus transacciones locales, incluidas las que forman parte de las transacciones globales. • El sistema con múltiples bases de datos asegura sólo la secuencialidad entre las transacciones globales – ignorando las ordenaciones inducidas por las transacciones locales. Resulta sencillo hacer que se cumpla cada uno de estos niveles de secuencialidad. Los sistemas locales ya ofrecen garantías de secuencialidad; por tanto, el primer requisito es sencillo de lograr. El segundo requisito sólo se aplica a una proyección de la planificación global en la que las transacciones locales no aparecen. Por tanto, el sistema con múltiples bases de datos puede asegurar el segundo requisito usando técnicas estándar de control de concurrencia (no importa la elección concreta de la técnica). Los dos requisitos de S2N no resultan suficientes para asegurar la secuencialidad global. Sin embargo, con el enfoque S2N, se adopta un requisito más débil que la secuencialidad, denominado corrección fuerte: 1. La conservación de la consistencia tal y como especifica un conjunto de restricciones de consistencia. 2. La garantía de que el conjunto de elementos de datos leído por cada transacción sea consistente. Puede probarse que determinadas restricciones al comportamiento de las transacciones, combinadas con S2N, son suficientes para asegurar la corrección fuerte (aunque no necesariamente para asegurar la secuencialidad). Se citarán varias de estas restricciones. En cada uno de los protocolos se distingue entre los datos locales y los datos globales. Los elementos locales de datos pertenecen a un sitio concreto y se hallan bajo el control exclusivo de ese sitio. Obsérvese que no puede haber restricciones de consistencia entre los elementos locales de datos de sitios distintos. Los elementos globales de datos pertenecen al sistema con múltiples bases de datos y, aunque puede que se almacenen en un sitio local, se hallan bajo el control del sistema con múltiples bases de datos.

www.detodoprogramacion.com


798

Capítulo 25

Procesamiento avanzado de transacciones

El protocolo globales – lectura permite que las transacciones globales lean, pero no actualicen, los elementos locales de datos, mientras que impide el acceso a los datos globales por parte de las transacciones locales. El protocolo globales–lectura asegura la corrección fuerte si se cumplen las reglas siguientes: 1. Las transacciones locales sólo tienen acceso a los elementos locales de datos. 2. Las transacciones globales pueden tener acceso a los elementos globales de datos, y pueden leer los elementos locales de datos (aunque no deben escribirlos). 3. No hay restricciones de consistencia entre los elementos de datos locales y los globales. El protocolo locales – lectura concede a las transacciones locales acceso de lectura a los datos globales, pero impide el acceso a los datos locales por las transacciones globales. En este protocolo hay que introducir el concepto de dependencia del valor. Cada transacción tiene una dependencia del valor si el valor que escribe en el elemento de datos de un sitio depende del valor que ha leído para el elemento de datos de otro sitio. El protocolo locales – lectura asegura la corrección fuerte si se cumplen las condiciones siguientes: 1. Las transacciones locales pueden tener acceso a los elementos locales de datos y pueden leer los elementos globales de datos almacenados en ese sitio (aunque no deban escribir elementos globales de datos). 2. Las transacciones globales sólo tienen acceso a los elementos globales de datos. 3. Ninguna transacción puede tener dependencia de ningún valor. El protocolo globales – lectura–escritura/locales–lectura es el más generoso en términos de acceso a los datos de los protocolos que se han considerado. Permite que las transacciones globales lean y escriban los datos locales y que las transacciones locales lean los datos globales. Sin embargo, impone tanto la condición de dependencia del valor del protocolo locales–lectura como la condición del protocolo globales– lectura de que no haya restricciones de consistencia entre los datos locales y los globales. El protocolo globales – lectura–escritura/locales–lectura asegura la corrección fuerte si se cumplen las condiciones siguientes: 1. Las transacciones locales pueden tener acceso a los elementos locales de datos y pueden leer los elementos globales de datos almacenados en ese sitio (aunque no deben escribir los elementos globales de datos). 2. Las transacciones globales pueden tener acceso a los elementos globales de datos y a los elementos locales de datos (es decir, pueden leer y escribir todos los datos). 3. No hay restricciones de consistencia entre los elementos locales de datos y los globales. 4. Ninguna transacción puede tener dependencia de ningún valor. 25.7.2 Aseguramiento de la secuencialidad global

Los primeros sistemas con múltiples bases de datos restringían las transacciones globales a ser sólo de lectura. Así evitaban la posibilidad de que las transacciones globales introdujeran inconsistencia en los datos, pero no eran lo bastante restrictivas como para asegurar la secuencialidad global. Resulta posible realmente obtener planificaciones globales de este tipo y desarrollar un esquema para asegurar la secuencialidad global, y se pide al lector que haga las dos cosas en el Ejercicio práctico 25.8. Hay varios esquemas generales para asegurar la secuencialidad global en entornos en los que se pueden ejecutar actualizaciones y transacciones sólo de lectura. Varios de estos esquemas se basan en la idea del billete. Se crea un elemento de datos especial denominado billete en cada sistema local de bases de datos. Cada transacción global que tenga acceso a los datos de un sitio debe escribir en el billete de ese sitio. Este requisito asegura que las transacciones globales entren en conflicto directamente en cada sitio que visiten. Además, el gestor de las transacciones globales puede controlar el orden en el que se

www.detodoprogramacion.com


25.8

Resumen

799

secuencian las transacciones globales controlando el orden en el que tienen acceso a los billetes. Las referencias a estos esquemas aparecen en las notas bibliográficas. Si se desea asegurar la secuencialidad global en entornos en los que no se generan en cada sitio conflictos locales directos, hay que realizar algunas suposiciones sobre las planificaciones autorizadas por el sistema local de bases de datos. Por ejemplo, si las planificaciones locales son tales que el orden de compromiso y el de secuenciación son siempre idénticos, se puede asegurar la secuencialidad controlando únicamente el orden en que se comprometen las transacciones. El problema de los esquemas que aseguran la secuencialidad global es que pueden restringir la concurrencia de manera inadecuada. Resultan especialmente propensos a hacerlo porque la mayor parte de las transacciones remiten al sistema de bases de datos subyacente las sentencias SQL, en lugar de remitir cada uno de los pasos de lectura, escritura, compromiso y aborto. Aunque sigue siendo posible asegurar la secuencialidad global con esta suposición, el nivel de concurrencia puede ser tal que otros esquemas, como la técnica de secuencialidad de dos niveles estudiada en el Apartado 25.7.1, resulten alternativas atractivas.

25.8 Resumen

• Los flujos de trabajo son actividades que implican la ejecución coordinada de varias tareas llevadas a cabo por diferentes entidades de proceso. No sólo existen en las aplicaciones informáticas, sino también en casi todas las actividades de una organización. Con el auge de las redes y la existencia de numerosos sistemas autónomos de bases de datos, los flujos de trabajo ofrecen una manera adecuada de llevar a cabo las tareas que implican a varios sistemas. • Aunque los requisitos transaccionales ACID habituales resultan demasiado estrictos o no pueden implementarse para estas aplicaciones de flujo de trabajo, los flujos de trabajo deben satisfacer un conjunto limitado de propiedades transaccionales que garantiza que no se dejen los procesos en estados inconsistentes. • Los monitores de procesamiento de transacciones se desarrollaron inicialmente como servidores con varias hebras que podían atender a un gran número de terminales desde un único proceso. Desde entonces han evolucionado y hoy en día ofrecen la infraestructura para la creación y gestión de sistemas complejos de procesamiento de transacciones que tienen gran número de clientes y varios servidores. Proporcionan servicios como colas duraderas de las solicitudes de los clientes y de las respuestas de los servidores, el encaminamiento de los mensajes de los clientes a los servidores, la mensajería persistente, el equilibrio de carga y la coordinación del compromiso de dos fases cuando las transacciones tienen acceso a varios servidores. • Los sistemas de comercio electrónico se han convertido en una parte principal del comercio. Hay varios aspectos de las bases de datos en los sistemas de comercio electrónico. La administración de los catálogos, especialmente su personalización, se realiza con bases de datos. Los mercados electrónicos ayudan a fijar el precio de los productos mediante subastas, subastas inversas o bolsas. Se necesitan sistemas de bases de datos de alto rendimiento para manejar este intercambio. Los pedidos se liquidan mediante sistemas de pago electrónico, que también necesitan sistemas de bases de datos de alto rendimiento para manejar tasas de transacciones muy elevadas. • Las memorias principales de gran tamaño se aprovechan en determinados sistemas para conseguir una gran productividad del sistema. En esos sistemas el registro histórico constituye un cuello de botella. Bajo el concepto de compromiso en grupo se puede reducir el número de salidas hacia el almacenamiento estable, lo que libera este cuello de botella. • La gestión eficiente de las transacciones interactivas de larga duración resulta más compleja debido a las esperas de larga duración y a la posibilidad de los abortos. Dado que las técnicas de control de concurrencia usadas en el Capítulo 16 emplean las esperas, los abortos o las dos cosas, hay que considerar técnicas alternativas. Estas técnicas deben asegurar la corrección sin exigir la secuencialidad.

www.detodoprogramacion.com


800

Capítulo 25

Procesamiento avanzado de transacciones

• Las transacciones de larga duración se representan como transacciones atómicas con operaciones atómicas de la base de datos anidadas en el nivel inferior. Si una transacción falla, sólo se abortan las transacciones activas de corta duración. Las transacciones activas de larga duración se reanudan una vez que se han recuperado todas las transacciones de corta duración. Se necesita una transacción compensadora para deshacer las actualizaciones de las transacciones anidadas que se hayan comprometido, si falla la transacción del nivel exterior. • En los sistemas con restricciones de tiempo real la corrección de la ejecución no sólo implica la consistencia de la base de datos, sino también el cumplimiento de los tiempos límite. La amplia variabilidad de los tiempos de ejecución de las operaciones de lectura y de escritura complica el problema de la gestión de las transacciones en sistemas con restricciones temporales. • Los sistemas con múltiples bases de datos proporcionan un entorno en el que las nuevas aplicaciones de bases de datos pueden tener acceso a los datos desde gran variedad de bases de datos existentes previamente ubicadas en varios entornos heterogéneos de hardware y de software. Los sistemas locales de bases de datos pueden usar diferentes modelos lógicos y lenguajes diferentes de definición y de manipulación de datos, y puede que se diferencien en sus mecanismos de control de concurrencia y de gestión de las transacciones. Los sistemas con múltiples bases de datos crean la ilusión de la integración lógica de las bases de datos sin exigir su integración física. Términos de repaso

• Monitor TP.

¤ Abortado.

• Arquitecturas de los monitores TP. ¤ ¤ ¤ ¤

Proceso por cliente. Servidor único. Varios servidores, un encaminador. Varios servidores, varios encaminadores.

• Recuperación en los flujos de trabajo. • Sistema gestor de flujos de trabajo. • Arquitecturas de los sistemas gestores del flujo de trabajo: ¤ Centralizadas. ¤ Parcialmente distribuidas. ¤ Completamente distribuidas.

• Multitarea. • Cambio de contexto.

• Comercio electrónico.

• Servidor con varias hebras.

• Catálogos electrónicos.

• Gestor de la cola.

• Mercados. ¤ Subastas. ¤ Subastas inversas. ¤ Bolsas.

• Coordinación de aplicaciones. ¤ Gestor de recursos. ¤ Llamada a procedimiento remoto (Remote Procedure Call, RPC). • Flujos de trabajo transaccionales. ¤ ¤ ¤ ¤

Tarea. Entidad de procesamiento. Especificación del flujo de trabajo. Ejecución del flujo de trabajo.

• Estado del flujo de trabajo. ¤ Estados de ejecución. ¤ Valores de salida. ¤ Variables externas. • Atomicidad ante fallos del flujo de trabajo. • Estados de terminación del flujo de trabajo: ¤ Aceptable. ¤ No aceptable. ¤ Comprometido.

• Liquidación de pedidos. • Certificados digitales. • Bases de datos en memoria principal. • Compromiso en grupo. • Sistemas de tiempo real. • Tiempo límite: ¤ Estricto. ¤ Firme. ¤ Flexible. • Bases de datos de tiempo real. • Transacciones de larga duración. • Exposición de datos no comprometidos. • Ejecuciones no secuenciables. • Transacciones anidadas.

www.detodoprogramacion.com


Ejercicios prácticos

• • • • • • • • • •

Transacciones multinivel. Saga. Transacciones compensadoras. Registro histórico lógico. Sistemas con múltiples bases de datos. Autonomía. Transacciones locales. Transacciones globales. Secuencialidad de dos niveles (S2N). Corrección fuerte.

801

• Datos locales. • Datos globales. • Protocolos: ¤ ¤ ¤ ¤

Globales–lectura. Locales–lectura. De dependencia del valor. Globales–lectura–escritura/locales– lectura.

• Aseguramiento de la secuencialidad global. • Billete.

Ejercicios prácticos

25.1 Al igual que los sistemas de bases de datos, los sistemas de flujo de trabajo también necesitan la gestión de la concurrencia y de la recuperación. Indíquense tres motivos por los que no se puede aplicar simplemente un sistema relacional de bases de datos usando bloqueo de dos fases, registro histórico de operaciones físicas de deshacer y compromiso de dos fases. 25.2 Considérese un sistema de bases de datos en memoria principal que se recupera de un fallo del sistema. Explíquense las ventajas relativas de: a. Volver a cargar toda la base de datos en memoria principal antes de reanudar el procesamiento de las transacciones. b. Cargar los datos a medida que los soliciten las transacciones. 25.3 Indíquese si un sistema de transacciones de alto rendimiento es necesariamente un sistema de tiempo real. Explíquese el motivo. 25.4 Explíquese el motivo por el que puede que no resulte práctico exigir la secuencialidad para las transacciones de larga duración. 25.5 Considérese un proceso con varias hebras que entrega mensajes desde una cola duradera de mensajes persistentes. Pueden ejecutarse de manera concurrente diferentes hebras, que intentan entregar mensajes diferentes. En caso de fallo en la entrega el mensaje debe restaurarse en la cola. Modélense las acciones que lleva a cabo cada hebra como una transacción multinivel, de manera que no haga falta mantener los bloqueos en la cola hasta que se entregue cada mensaje. 25.6 Descríbanse las modificaciones que hay que hacer en cada uno de los esquemas de recuperación tratados en el Capítulo 17 si se permiten las transacciones anidadas. Explíquense también las diferencias que se producen si se permiten las transacciones multinivel. 25.7 Considérese un sistema con múltiples bases de datos en el que se garantice que, como máximo, está activa una transacción global en un momento dado y que cada sistema local asegura la secuencialidad local. a. Sugiéranse maneras de que el sistema con múltiples bases de datos pueda asegurar que haya como máximo una transacción global activa en cualquier momento dado. b. Demuéstrese mediante un ejemplo que resulta posible que se produzca una planificación global no secuenciable pese a estas suposiciones. 25.8 Considérese un sistema con múltiples bases de datos en el que cada sitio local asegura la secuencialidad local y todas las transacciones globales son sólo de lectura. a. Demuéstrese mediante un ejemplo que pueden producirse ejecuciones no secuenciables en este sistema. b. Muéstrese la manera en que se podría usar un esquema de billete para asegurar la secuencialidad global.

www.detodoprogramacion.com


802

Capítulo 25

Procesamiento avanzado de transacciones

Ejercicios

25.9 Explíquese el modo en que los monitores TP administran los recursos de la memoria y del procesador de manera más efectiva que los sistemas operativos habituales. 25.10 Compárense las características de los monitores TP con las proporcionadas por los servidores Web que soportan servlets (estos servidores se han denominado TP-lite— TP ligeros). 25.11 Considérese el proceso de admisión de nuevos alumnos en la universidad (o de nuevos empleados en la organización). a. Dese una imagen de alto nivel del flujo de trabajo comenzando por el procedimiento de matrícula de los estudiantes. b. Indíquense los estados de terminación aceptables y los pasos que implican intervención de personas. c. Indíquense los posibles errores (incluido el vencimiento del tiempo límite) y el modo en que se tratan. d. Estúdiese la cantidad de flujo de trabajo que se ha automatizado en la universidad. 25.12 Contéstense las preguntas siguientes con respecto a sistemas electrónicos de pago. a. Explíquese por qué las transacciones electrónicas realizadas usando números de la tarjeta de crédito son inseguras. b. Un alternativa es tener una pasarela para el pago electrónico mantenida por la compañía de la tarjeta de crédito, y que el sitio que reciba el pago redirija a los clientes a la pasarela para hacer el pago. I . Explíquense las ventajas que ofrece este sistema si la entrada no autentica al usuario. II . Explíquense las ventajas si la pasarela tiene un mecanismo para autenticar al usuario. c. Algunas compañías de tarjetas de crédito ofrecen un número de la tarjeta de crédito de un solo uso como método más seguro de pago electrónico. Los clientes se conectan con el sitio Web de las compañías de tarjetas de crédito para conseguir un número de un solo uso. Explíquese la ventaja que ofrece este sistema con respecto a usar números de tarjeta de crédito normales. Explíquense también sus ventajas e inconvenientes con respecto a las pasarelas de pago con autentificación. d. ¿Alguno de estos sistemas garantiza la misma privacidad disponible cuando los pagos se hacen en efectivo? Explíquese la respuesta. 25.13 Si toda la base de datos cabe en la memoria principal, indíquese si sigue haciendo falta un sistema de bases de datos para administrar los datos. Explíquese la respuesta. 25.14 En la técnica de compromiso en grupo indicar el número de transacciones que deben formar parte de un grupo. Explíquese la respuesta. 25.15 En un sistema de bases de datos que utilice el registro histórico de escritura adelantada indíquese el número de accesos a disco necesarios para leer un elemento de datos de una página de disco especificada en el peor caso posible. Explíquese el motivo por el que esto supone un problema para los diseñadores de sistemas de bases de datos de tiempo real. 25.16 Indíquese la finalidad de las transacciones compensadoras. Preséntense dos ejemplos de su uso. 25.17 Explíquense las semejanzas entre un flujo de trabajo y una transacción de larga duración. Notas bibliográ cas

Gray y Edwards [1995] proporcionan una introducción a las arquitecturas de los monitores TP; en el libro Gray y Reuter [1993] se ofrece una descripción detallada (y excelente) de los sistemas de procesamiento de transacciones, incluidos capítulos sobre los monitores TP. X/Open [1991] define la interfaz X/Open XA. El procesamiento de las transacciones en Tuxedo se describe en Wipfler [1987] es uno de los textos sobre el desarrollo de aplicaciones mediante CICS.

www.detodoprogramacion.com


Notas bibliográficas

803

Fischer [2001] es un manual sobre los sistemas de flujos de trabajo. Un modelo de referencia para los flujos de trabajo, propuesto por la Coalición para la gestión de flujos de trabajo (Workflow Management Coalition), se presenta en Hollingsworth [1994] En Hollingsworth [2004], se presenta una revisión del modelo, incluyendo sus conexiones con el modelo de procesos de negocios, como parte del manual sobre flujos de trabajo (Fischer [2004]). El sitio Web de la coalición es www.wfmc.org. La descripción de flujos de trabajo que se ha dado sigue el modelo de Rusinkiewicz y Sheth [1995]. Loeb [1998] proporciona una descripción detallada de las transacciones electrónicas seguras. Garcia-Molina y Salem [1992] ofrecen una introducción a las bases de datos en memoria principal. Jagadish et al. [1993] describen un algoritmo de recuperación diseñado para las bases de datos en memoria principal. En Jagadish et al. [1994] se describe un gestor de almacenamiento para las bases de datos en memoria principal. Las bases de datos de tiempo real se estudian en Lam y Kuo [2001]. Entre las aplicaciones de procesamiento de datos en tiempo real se encuentra TelegraphCQ (Chandrasekaran et al. [2003]). El control de concurrencia y las planificaciones en las bases de datos de tiempo real se estudian en Haritsa et al. [1990], Hong et al. [1993] y en Pang et al. [1995]. Ozsoyoglu y Snodgrass [1995] es una reseña de la investigación en las bases de datos de tiempo real y en las bases de datos temporales. Las transacciones anidadas y las transacciones multinivel se presentan en Lynch [1983], Moss [1985], Lynch y Merritt [1986], Fekete et al. [1990], Weikum [1991], Korth y Speegle [1994] y en Pu et al. [1988]. Los aspectos teóricos de las transacciones multinivel se presentan en Lynch et al. [1988] y en Weihl y Liskov [1990]. Se han definido varios modelos de transacciones ampliadas, incluidos Sagas (Garcia-Molina y Salem [1987]), el modelo ConTract (Wachter y Reuter [1992]) y ARIES (Mohan et al. [1992] y Rothermel y Mohan [1989]). La división de las transacciones para conseguir un rendimiento mayor se aborda en Shasha et al. [1995]. La recuperación en los sistemas de transacciones anidadas se estudia en Moss [1987], Haerder y Rothermel [1987] y Rothermel y Mohan [1989]. El procesamiento de las transacciones de larga duración se considera en Weikum y Schek [1984], Haerder y Rothermel [1987], Weikum et al. [1990] y en Korth et al. [1990]. Salem et al. [1994] presentan una extensión del bloqueo de dos fases para las transacciones de larga duración al permitir la liberación precoz de los bloqueos en ciertas circunstancias. El procesamiento de las transacciones en los sistemas con múltiples bases de datos se estudia en Mehrotra et al. [2001]. El esquema del billete se presenta en Georgakopoulos et al. [1994]. S2N se introduce en Mehrotra et al. [1991].

www.detodoprogramacion.com


www.detodoprogramacion.com


P

A

R

T

E

9

Estudio de casos

Esta parte describe la forma en que los distintos sistemas de bases de datos integran los conceptos descritos anteriormente en el libro. Comienza en el Capítulo 26 con el estudio de un sistema de bases de datos de código abierto ampliamente usado: PostgreSQL. En los Capítulos 27, 28 y 29 se estudian tres sistemas comerciales de bases de datos muy usados: DB2 de IBM, Oracle y SQL Server de Microsoft. Representan tres de los sistemas comerciales de bases de datos más usados. Cada uno de estos capítulos muestra características únicas de cada sistema de bases de datos: herramientas, variaciones y extensiones de SQL, y la arquitectura del sistema, incluyendo organización del almacenamiento, procesamiento de consultas, control de concurrencia, recuperación y réplicas. Los capítulos tratan solamente los aspectos clave de los productos de bases de datos que describen y por tanto no se deberían usar como una descripción completa. Además, puesto que los productos se mejoran periódicamente, sus detalles pueden cambiar. Cuando se usa una versión particular del producto hay que asegurarse de consultar en los manuales de usuario los detalles específicos. Se debe tener presente que en los capítulos de esta parte se usa a menudo terminología industrial en lugar de académica. Por ejemplo, se usa tabla en lugar de relación, fila en lugar de tupla y columna en lugar de atributo.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

26

PostgreSQL Anastassia Ailamaki, Sailesh Krishnamurthy, Spiros Papadimitriou, Bianca Schroeder CMU

PostgreSQL es un sistema gestor de bases de datos relacionales de objetos de código abierto. Es un des-

cendiente de uno de los primeros sistemas de este tipo, el sistema Postgres desarrollado bajo la dirección del profesor Michael Stonebraker en la Universidad de California en Berkeley. El nombre “Postgres” proviene del nombre de un sistema pionero de bases de datos relacionales, Ingres, también desarrollado bajo la dirección de Stonebraker en Berkeley. Actualmente, PostgreSQL soporta SQL92 y SQL:1999 y ofrece características como las consultas complejas, las claves externas, los disparadores, las vistas, la integridad transaccional y el control de concurrencia de varias versiones. Además, los usuarios pueden ampliar PostgreSQL con tipos de datos, funciones, operadores y métodos de indexación nuevos. PostgreSQL trabaja con gran variedad de lenguajes de programación (incluidos C, C++, Java, Perl, TcI y Python). Quizás, el punto fuerte de PostgreSQL sea que, junto con MySQL, son los dos sistemas de bases de datos relacionales de código abierto más utilizados. La licencia de PostgreSQL es la licencia BSD, que concede libre de cargo permiso para el uso, modificación y distribución del código y de la documentación de PostgreSQL con cualquier propósito. 26.1 Introducción

A lo largo de más de una década, PostgreSQL ha tenido varias versiones importantes. El primer sistema prototipo, con el nombre de Postgres, se presentó en la conferencia SIGMOD de la ACM en 1988. La versión 1 se distribuyó a los usuarios en 1989. Después de que las versiones posteriores añadieran un nuevo sistema de reglas, soporte para varios gestores de almacenamiento y un ejecutor de consultas mejorado, los desarrolladores del sistema se centraron en la portabilidad y en el rendimiento hasta 1994, cuando se añadió un intérprete del lenguaje SQL. Con un nuevo nombre, Postgres95, el sistema se distribuyó por Web y, posteriormente, fue comercializado por Illustra Information Technologies (que posteriormente se fusionó con Informix, que ahora es propiedad de IBM). Hacia 1996 el nombre Postgres95 fue sustituido por PostgreSQL, para reflejar la relación entre el Postgres original y las versiones más recientes con capacidades de SQL. PostgreSQL se puede ejecutar bajo prácticamente todos los sistemas operativos tipo Unix, incluidos Linux y OS X para Apple de Macintosh. PostgreSQL también puede ejecutarse bajo Microsoft Windows en el entorno Cygwin, el cual proporciona emulación de Linux bajo Windows. La versión más reciente, la 8.0, publicada en enero de 2005, ofrece soporte nativo de Microsoft Windows. Hoy en día PostgreSQL se utiliza para implementar varias aplicaciones de investigación y de producción diferentes (como el proyecto informático científico Sequoia 2000) y como herramienta educativa en 807

www.detodoprogramacion.com


808

Capítulo 26

PostgreSQL

Figura 26.1

pgAdmin III: una interfaz gráfica de usuario de código abierto para la administración de bases de datos.

varias universidades. El sistema sigue evolucionando gracias a las contribuciones de una comunidad de alrededor de 1.000 desarrolladores. En este capítulo se explicará el funcionamiento de PostgreSQL, comenzando por las interfaces y los lenguajes de usuario y siguiendo por el corazón del sistema (las estructuras de datos y los mecanismos de control de concurrencia). 26.2 Interfaces de usuario

La distribución estándar de PostgreSQL incluye herramientas de línea de comandos para la administración de las bases de datos. Sin embargo, existe un gran número de herramientas de administración y de diseño comerciales y de código abierto que soportan PostgreSQL. PostgreSQL ofrece un amplio conjunto de interfaces de usuario. 26.2.1 Interfaces de terminal interactivas

Como la mayor parte de los sistemas de bases de datos, PostgreSQL ofrece herramientas de línea de comandos para la administración de bases de datos. El principal cliente de terminal interactiva es psql, que se modeló a partir del intérprete de comandos de Unix y permite la ejecución de comandos de SQL en el servidor, así como otras operaciones (como la copia en el lado del cliente). Algunas de sus características son: • Variables. psql ofrece características de sustitución de variables, parecidas a los intérpretes de comandos Unix habituales. • Interpolación SQL. El usuario puede sustituir (“interpolar”) las variables de psql en instrucciones SQL regulares colocando un punto y coma delante del nombre de la variable. • Edición de la línea de comandos. psql utiliza la biblioteca Readline de GNU para hacer más cómoda la edición de líneas, que permite autocompletar las entradas mediante tabuladores. PostgreSQL también ofrece pgtkshy pgtclsh, que son versiones de los intérpretes de comandos tipo Tk y Tcl (wish) los cuales incluyen adicionalmente enlaces con PostgreSQL. Tcl/Tk es un lenguaje de guiones

flexible, empleado generalmente para la creación rápida de prototipos.

www.detodoprogramacion.com


26.3

Figura 26.2

Variaciones y extensiones de SQL

809

Data Architect: una interfaz gráfica de usuario multiplataforma para el diseño de bases de datos.

26.2.2 Interfaces grá cas

La distribución estándar de PostgreSQL no contiene ninguna herramienta gráfica. No obstante, existen varias herramientas con interfaz gráfica de usuario, de forma que se pueden escoger entre las posibilidades comerciales y las de código abierto. Muchas de ellas experimentan ciclos de publicación rápidos; la lista siguiente refleja la situación en el momento de escribir este libro. Se encuentran disponibles herramientas gráficas para la administración, incluidas pgAccess y pgAdmin, la última de las cuales puede verse en la Figura 26.1. Entre las herramientas para el diseño de bases de datos están TORA y Data Architect, la última de las cuales puede verse en la Figura 26.2. PostgreSQL trabaja con varias herramientas comerciales para el diseño de formularios y la generación de informes. Entre las posibilidades de código abierto se encuentran Rekall (que puede verse en las Figuras 26.3 y 26.4), GNU Report Generator y un conjunto de herramientas más general, GNU Enterprise. 26.2.3 Interfaces para lenguajes de programación

PostgreSQL ofrece interfaces nativas para ODBC y para JDBC, así como enlaces con la mayor parte de los lenguajes de programación, incluidos C, C++, PHP, Perl, Tcl/Tk, ECPG, Python y Ruby. La interfaz de programación para aplicaciones en C de PostgreSQL es libpq, que también es el motor subyacente de la mayor parte de los enlaces de lenguajes de programación (por tanto, todas sus características también están disponibles en los demás lenguajes soportados). La biblioteca libpq soporta tanto la ejecución síncrona de los comandos de SQL y de las instrucciones preparadas como la asíncrona. Es reentrante y aporta seguridad a las hebras (threads). Utiliza variables de entorno para ciertos parámetros y un archivo de contraseñas opcional para las conexiones que exigen autentificación.

26.3 Variaciones y extensiones de SQL PostgreSQL cumple la norma SQL de ANSI. Soporta casi todas las características del nivel básico de SQL92

(que es lo que la mayor parte de los fabricantes de sistemas de bases de datos relacionales entienden por conformidad con SQL92) y muchas de las de los niveles intermedio y completo. Finalmente, soporta

www.detodoprogramacion.com


810

Capítulo 26

PostgreSQL

Figura 26.3

Figura 26.4

Rekall: interfaz gráfica de usuario para diseño de formularios.

Rekall: interfaz gráfica de usuario para diseño de informes.

www.detodoprogramacion.com


26.3

Variaciones y extensiones de SQL

811

varias de las características de SQL:1999 (incluida la mayor parte de las características relacionales de objetos que se describen en el Capítulo 9); de hecho, algunas de ellas fueron introducidas por PostgreSQL o por sus antecesores. Carece de características OLAP (principalmente, cube y rollup), pero los datos de PostgreSQL pueden cargarse con facilidad en servidores OLAP externos de código abierto (como Mondrian), así como en productos comerciales. 26.3.1 Tipos de PostgreSQL

PostgreSQL incluye soporte para varios tipos no normalizados, que resultan útiles para dominios de

aplicaciones concretas. Además, los usuarios pueden definir nuevos tipos con el comando create type. Esto incluye nuevos tipos básicos de bajo nivel, generalmente escritos en C (véase el Apartado 26.3.3.1) 26.3.1.1 El sistema de tipos de PostgreSQL

Los tipos de PostgreSQL pueden clasificarse en las categorías siguientes: • Tipos básicos. Los tipos básicos también se conocen como tipos abstractos de datos; es decir, módulos que encapsulan al mismo tiempo un estado y un conjunto de operaciones. Se implementan por debajo del nivel SQL, generalmente en un lenguaje como C (véase el Apartado 26.3.3.1). Entre los ejemplos se encuentran int4 (que ya está incluido en PostgreSQL) y complex (que se incluye como tipo de extensión opcional). Cada tipo básico de PostgreSQL va acompañado automáticamente por un tipo de array que pueda almacenar arrays de longitud variable de ese tipo básico concreto. • Tipos compuestos. Se corresponden con las filas de las tablas; es decir, son una lista de nombres de campos y de sus tipos básicos respectivos. Siempre que se crea una tabla se crea implícitamente un tipo compuesto, aunque los usuarios también pueden crearlos de manera explícita. • Dominios. Son muy parecidos a los tipos básicos (y a menudo ambos tipos son intercambiables), sin embargo pueden tener restricciones respecto de los valores que les están permitidos. • Pseudotipos. Actualmente, PostgreSQL soporta los pseudotipos siguientes: any, anyarray, anyelement, cstring, internal, language handler, record, trigger y void. No pueden utilizarse en los tipos compuestos (y, por tanto, no pueden utilizarse para las columnas de las tablas), pero pueden emplearse como argumentos y tipos de retorno de funciones definidas por los usuarios. • Tipos polimórficos. Los dos pseudotipos anyelement y anyarray se conocen como polimórficos. Las funciones con argumentos de estos tipos (denominadas, a su vez, funciones polimórficas) pueden operar sobre cualquier tipo. PostgreSQL tiene un esquema sencillo de resolución de tipos que exige que: (1) en cada invocación de una función polimórfica todas las ocurrencias de los tipos polimórficos estén vinculadas al mismo tipo (es decir, una función definida como f (fanyelement, fanyelement) sólo puede operar sobre parejas del mismo tipo) y (2) si el tipo devuelto es polimórfico, al menos uno de los argumentos debe ser del mismo tipo polimórfico. 26.3.1.2 Tipos no estándar

Los tipos descritos en este apartado se incluyen en la distribución estándar. Además, gracias a la naturaleza abierta de PostgreSQL, se han aportado varios tipos adicionales, como los números complejos y el ISBN/ISSN (véase el Apartado 26.3.3). Los tipos de datos geométricos (point, line, lseg, box, polygon, path, circle) se utilizan en los sistemas de información geográfica para representar objetos espaciales bidimensionales como los puntos, los segmentos de línea, los polígonos, los caminos y los círculos. En PostgreSQL se dispone de numerosas funciones y operadores para llevar a cabo diferentes operaciones geométricas como el cambio de escala, las traslaciones, las rotaciones y la determinación de las intersecciones. Además, PostgreSQL soporta el indexado de estos tipos mediante árboles R (Apartados 24.3.5.3 y 26.5.2.1). PostgreSQL ofrece tipos de datos para el almacenamiento de direcciones de red. Estos tipos de datos permiten que las aplicaciones de administración de redes utilicen bases de datos de PostgreSQL como al-

www.detodoprogramacion.com


812

Capítulo 26

PostgreSQL

macenes de datos. Para aquéllos familiarizados con las redes de computadoras, se ofrece a continuación un breve resumen de esta característica. Hay tipos diferentes para direcciones IPv4, direcciones IPv6 direcciones de Control de Acceso a Medios (Media Access Control, MAC) (cidr, inet y macaddr, respectivamente). Tanto el tipo inet como el tipo cidr pueden almacenar direcciones IPv4 y direcciones IPv6, con máscaras de subred opcionales. Su principal diferencia estriba en el formato de entrada y de salida, así como en la restricción de que las direcciones de enrutamiento de dominios de Internet sin clase (Classless Internet Domain Routing, CIDR) no aceptan valores con bits diferentes de cero a la derecha de la máscara de subred. El tipo macaddr se utiliza para almacenar direcciones MAC (generalmente, direcciones de hardware de tarjetas Ethernet). PostgreSQL soporta el indexado y la ordenación de estos tipos, así como un conjunto de operaciones (incluidas la comprobación de subredes y la asignación de direcciones MAC a nombres de fabricantes de hardware). Además, estos tipos ofrecen comprobación de errores de entrada. Por tanto, son preferibles a los campos de texto sencillo. El tipo bit de PostgreSQL puede almacenar cadenas de unos y ceros tanto de longitud fija como de longitud variable. PostgreSQL soporta los operadores lógicos de bits y las funciones de manipulación de cadenas de caracteres. 26.3.2 Las reglas y otras características de las bases de datos activas

PostgreSQL soporta las restricciones y los disparadores de SQL (y los procedimientos almacenados; véa-

se el Apartado 26.3.3). Además, ofrece reglas de reescritura de consultas que pueden declararse en el servidor. PostgreSQL permite comprobar las restricciones, las restricciones de existencia y las restricciones de clave principal y de clave externa (con borrados restrictivos y en cascada). Al igual que otros muchos sistemas de bases de datos relacionales, PostgreSQL soporta los disparadores, que resultan útiles para las restricciones no triviales y para comprobar o hacer cumplir la consistencia. Las funciones disparadoras pueden escribirse en lenguajes procedimentales como PL/pgSQL(véase el Apartado 26.3.3.4) o en C, pero no en mero SQL. Los disparadores pueden ejecutarse antes o después de las operaciones insert, update o delete y tanto una sola vez por fila modificada como una sola vez por instrucción SQL. El sistema de reglas de PostgreSQL permite que los usuarios definan las reglas de reescritura de consultas en el servidor de bases de datos. A diferencia de los procedimientos almacenados y de los disparadores, el sistema de reglas interviene entre el analizador de consultas y el planificador, y modifica las consultas de acuerdo con el conjunto de reglas. Una vez transformado el árbol de la consulta original en uno o más árboles, éstos se pasan al planificador de consultas. Por tanto, el planificador tiene toda la información necesaria (las tablas que hay que explorar, las relaciones entre ellas, las calificaciones, la información conjunta, etc.) y puede presentar un plan de ejecución eficiente, aunque estén implicadas reglas complejas. La sintaxis general para la declaración de las reglas es: create rule nombre_regla as on { select | insert | update | delete } to tabla [ where calificación_regla ] do [ instead ] { nothing | comando | ( comando ; comando ... ) } El resto de este apartado ofrece ejemplos que ilustran las posibilidades del sistema de reglas. En la documentación de PostgreSQL se pueden encontrar más detalles sobre el modo en que las reglas se adaptan a los árboles de consultas y la manera en que estos últimos se transforman posteriormente (véanse las notas bibliográficas). El sistema de reglas se implementa en la fase de reescritura del procesamiento de las consultas y se explica en el Apartado 26.6.1. En primer lugar, PostgreSQL utiliza las reglas para implementar las vistas. La definición de una vista como: create view mivista as select * from mitabla; se transforma en la siguiente definición de regla:

www.detodoprogramacion.com


26.3

Variaciones y extensiones de SQL

813

create table mivista (la misma lista de columnas que en mitabla); create rule return as on select to mivista do instead select * from mitabla; Las consultas a mivista se transforman antes de su ejecución en consultas a la tabla subyacente mitabla. La sintaxis create view se considera una forma de programación mejor en este caso, ya que es más concisa y también evita la creación de vistas que hagan referencia unas a otras (lo que es posible si las reglas se declaran de manera poco cuidadosa, y puede dar lugar a errores de tiempo de ejecución que lleven a la confusión). No obstante, se pueden utilizar reglas para definir de manera explícita las acciones de actualización de las vistas (las instrucciones create view no permiten hacer esto). Como ejemplo adicional, considérese el caso de que el usuario desee examinar las actualizaciones de las tablas. Algo así podría lograrse mediante una regla como: create rule control_sueldos as on update to empleado where new.sueldo <> old.sueldo do insert into control_sueldos values (current_timestamp, current_user, new.nombre_emp, old.sueldo, new.sueldo); Finalmente, se ofrece una regla de inserción y actualización ligeramente más complicada. Supóngase que se almacenan los aumentos salariales pendientes en la tabla aumentos_salariales(nombre_emp, aumento). Se puede declarar la tabla adicional aumentos_aprobados con los mismos campos y definir después la regla siguiente: create rule aumentos_aprobados_insertar as on insert to aumentos_aprobados do instead update empleado set sueldo = sueldo + new.aumento where nombre_emp = new.nombre_emp; Entonces la consulta siguiente: insert into aumentos_aprobados select * from aumentos_salariales; actualizará a la vez todos los sueldos de la tabla empleado. El sistema de reglas de PostgreSQL puede utilizarse para implementar la mayor parte de los disparadores. Algunos tipos de restricciones (especialmente las claves externas) no se pueden implementar mediante reglas. Además, si la violación de una restricción genera un mensaje de error (en vez de descartar silenciosamente los valores no válidos, mediante la declaración de una regla “. . . do instead nothing”), entonces hay que utilizar disparadores. Los disparadores no pueden usarse para las acciones update ni delete sobre vistas. Dado que no hay ningún dato real en las relaciones de vistas, nunca se llamaría al disparador. Finalmente, los disparadores se activan una vez por cada fila afectada. Las reglas, por su parte, manipulan el árbol de consultas antes de planificar la consulta. Por tanto, si una instrucción afecta a muchas filas, las reglas son más eficientes que los disparadores. La implementación de los disparadores y de las restricciones en PostgreSQL se esboza brevemente en el Apartado 26.6.4. 26.3.3 Extensibilidad

Al igual que la mayor parte de los sistemas de bases de datos relacionales, PostgreSQL almacena la información sobre las bases de datos, las tablas, las columnas, etc., en lo que suele denominarse como catálogos del sistema, que se presentan ante el usuario como tablas normales. Otros sistemas de bases de datos relacionales se suelen ampliar modificando procedimientos incluidos en el código fuente o mediante la carga de módulos especiales de extensión escritos por el fabricante.

www.detodoprogramacion.com


814

Capítulo 26

PostgreSQL

Sin embargo, a diferencia de la mayor parte de los sistemas de bases de datos relacionales, PostgreSQL va un paso más allá y almacena mucha más información en los catálogos: no sólo la información sobre las tablas y las columnas, sino también la información sobre los tipos de datos, las funciones, los métodos de acceso, etc. Por tanto, resulta sencillo para los usuarios ampliar PostgreSQL y esto facilita la creación rápida de prototipos de nuevas aplicaciones y de estructuras de almacenamiento. PostgreSQL también puede incorporar en el servidor código escrito por los usuarios, mediante la carga dinámica de los objetos compartidos. Esto ofrece un enfoque alternativo a la escritura de extensiones que puede utilizarse cuando las extensiones basadas en los catálogos no resultan suficientes. Además, el módulo contrib de la distribución de PostgreSQL incluye numerosas funciones de usuario (por ejemplo, iteradores de arrays, comparación difusa de cadenas de caracteres, funciones criptográficas), tipos básicos por ejemplo, contraseñas cifradas, ISBN/ISSN, cubos n —dimensionales) y extensiones de los índices (por ejemplo, árboles RD, indexado de texto completo). Gracias a la naturaleza abierta de PostgreSQL hay una gran comunidad de profesionales y entusiastas de PostgreSQL que también amplían PostgreSQL prácticamente a diario. Los tipos de las extensiones son idénticos en funcionalidad a los tipos predefinidos (véase también el Apartado 26.3.1.2); los últimos simplemente se hallan ya enlazados en el servidor y están registrados previamente en el catálogo del sistema. De manera parecida, ésta es la única diferencia entre las funciones intrínsecas y las ampliadas. 26.3.3.1 Tipos

PostgreSQL permite que los usuarios definan tipos compuestos, así como que amplíen los tipos básicos

disponibles. Las definiciones de los tipos compuestos son parecidas a las definiciones de las tablas (de hecho, la última lleva a cabo la primera de manera implícita). Los tipos compuestos independientes suelen resultar útiles para los argumentos de las funciones. Por ejemplo, la definición create type t_ciudad as (nombre varchar(80), provincia char(2)) permite que las funciones acepten y devuelvan las tuplas t_ciudad, aunque no haya ninguna tabla que contenga de manera explícita filas de este tipo. La adición de tipos básicos a PostgreSQL es directa; se puede encontrar un ejemplo en complex.sql y complex.c en los tutoriales de la distribución de PostgreSQL. Los tipos básicos pueden declararse en C, por ejemplo: typedef struct Complejo { double x; double y; } Complejo; A continuación el usuario tiene que definir las funciones para leer y escribir los valores del nuevo tipo en formato de texto (véase el Apartado 26.3.3.2). Posteriormente, el nuevo tipo puede registrarse empleando la instrucción: create type complejo { internallength = 16, input = complejo_entrada, output = complejo_salida, alignment = double }; suponiendo que las funciones de E/S de texto se hayan registrado como complejo_entrada y complejo _salida. El usuario también tiene la posibilidad de definir funciones de E/S binarias (para un volcado de datos más eficiente). Los tipos ampliados pueden utilizarse como los tipos básicos de PostgreSQL ya existentes. De hecho, la única diferencia es que los tipos ampliados se cargan y enlazan dinámicamente

www.detodoprogramacion.com


26.3

Variaciones y extensiones de SQL

815

en el servidor. Además, los índices pueden ampliarse fácilmente para que manejen los nuevos tipos básicos; véase el Apartado 26.3.3.3.

26.3.3.2 Funciones

PostgreSQL permite que los usuarios definan funciones que se almacenen y ejecuten en el servidor.

También soporta la sobrecarga de funciones (es decir, se pueden declarar funciones que utilicen el mismo nombre pero con argumentos de tipos diferentes). Las funciones pueden escribirse como instrucciones de mero SQL. Además, se soportan varios lenguajes procedimentales (se tratan en el Apartado 26.3.3.4). Finalmente, PostgreSQL tiene una interfaz para programación de aplicaciones para añadir funciones escritas en C (que se explica en este apartado). Las funciones definidas por los usuarios pueden escribirse en C (o en un lenguaje con convenios de llamada compatibles, como C++). Los convenios de codificación reales son básicamente los mismos para las funciones definidas por los usuarios que se cargan de manera dinámica y para las funciones internas (que se enlazan en el servidor de manera estática). Por tanto, la biblioteca de funciones interna estándar es un fuente abundante de ejemplos de codificación para las funciones de C definidas por los usuarios. Una vez que se haya creado la biblioteca compartida que contiene la función, una declaración como la siguiente la registra en el servidor: create function complejo_salida(complejo) returns cstring as ’nombre_archivo_objeto_compartido’ language C immutable strict; Se da por supuesto que el punto de entrada al archivo del objeto compartido es el nombre de la función de SQL (aquí, complejo_salida), a menos que se especifique lo contrario. El ejemplo siguiente continúa el del Apartado 26.3.3.1. La interfaz de programación de aplicaciones oculta la mayor parte de los detalles internos de PostgreSQL. Por tanto, el código C para la función de salida de texto anterior de valores complejo es bastante sencillo: pg_function_info_v1(complejo_salida); Datum complejo_salida(pg_function_args) { Complejo *complejo = (Complejo *) pg_getarg_pointer(0); char *resultado; resultado = (char *) palloc(100); snprintf(resultado, 100, "( %g, %g)", complejo−>x, complejo−>y); pg_return_cstring(resultado); } Las funciones agregadas de PostgreSQL operan actualizando los valores de estado mediante funciones de transición de estado que se llaman para cada valor de la tupla del grupo de agregación. Por ejemplo, el estado del operador avg consta de la suma y recuento de los valores. A medida que llega cada tupla, la función de transición simplemente debe añadir su valor a la suma y aumentar en uno el recuento. De manera opcional, se puede llamar a una función final para que calcule el valor de retorno de acuerdo con la información de estado. Por ejemplo, la función final para avg simplemente dividiría la suma ejecutada entre el recuento y devolvería el resultado. Por tanto, la definición de un operador nuevo es tan sencilla como la definición de esas dos funciones. Para el ejemplo del tipo complejo, si complejo_suma es una función definida por los usuarios que toma dos argumentos complejos y devuelve su suma, entonces el operador de agregación sum puede ampliarse a los números complejos mediante la declaración siguiente:

www.detodoprogramacion.com


816

Capítulo 26

PostgreSQL

create aggregate sum ( sfunc = suma_complejo, basetype = complejo, stype = complejo, initcond = ’(0,0)’ ); Obsérvese el empleo de la sobrecarga de funciones: PostgreSQL llamará a la función de agregación sum adecuada en función del tipo real del argumento que se invoque. Basetype es el tipo de argumento y stype es el tipo del valor de estado. En este caso, no hace falta ninguna función final, ya que el valor devuelto es el propio valor de estado (es decir, la suma total en ambos casos). Las funciones definidas por los usuarios también pueden invocarse mediante la sintaxis de los operadores. Más allá del mero “azúcar sintáctico” para la invocación de funciones, las declaraciones de los operadores también pueden ofrecer sugerencias al optimizador de consultas para que optimice el rendimiento. Estas sugerencias pueden incluir información sobre la conmutatividad, la restricción y la estimación de la selectividad de las uniones, así como otras propiedades relacionadas con los algoritmos de unión. 26.3.3.3 Extensiones de los índices

PostgreSQL soporta los índices habituales de árbol B y asociativos, así como los índices de árbol R (para los objetos espaciales bidimensionales) y los índices GiST genéricos (que son exclusivos de PostgreSQL y

se explican en el Apartado 26.5.2.1). Todos ellos pueden extenderse fácilmente para incluir nuevos tipos básicos. La adición de extensiones de los índices para un tipo dado exige la definición de una clase de operador que encapsule lo siguiente: • Estrategias para métodos de indexado. Se trata de un conjunto de operadores que pueden utilizarse como calificadores en las cláusulas where. El conjunto concreto depende del tipo de índice. Por ejemplo, los índices de árbol B pueden recuperar rangos de objetos, por lo que el conjunto consiste en cinco operadores (<, <=, =, >= y >), todos los cuales pueden aparecer en las cláusulas where que afecten a índices de árbol B. Los índices asociativos sólo permiten comprobar las igualdades y los índices de árbol R permiten varias relaciones espaciales (por ejemplo, contenido, a la izquierda, etc.). • Rutinas de soporte de los métodos de indexado. El conjunto de operadores anterior no suele ser suficiente para la operación del índice. Por ejemplo, los índices asociativos necesitan una función que calcule el valor asociativo de cada objeto. Los índices de árbol R necesitan poder calcular las intersecciones y las uniones, y estimar el tamaño de los objetos indexados. Por ejemplo, si se definen las funciones y operadores siguientes para comparar la magnitud de los números complejo (véase el Apartado 26.3.3.1), entonces se puede hacer que esos objetos sean indexables mediante la declaración siguiente: create operator class ops_abs_complejo default for type complejo using btree as operator 1 <(complejo, complejo), operator 2 <= (complejo, complejo), operator 3 = (complejo, complejo), operator 4 >= (complejo, complejo), operator 5 > (complejo, complejo), function 1 cmp_abs_complejo(complejo, complejo); Las instrucciones operator definen los métodos estratégicos y las instrucciones function definen los de soporte.

www.detodoprogramacion.com


26.4

Gestión de transacciones en PostgreSQL

817

26.3.3.4 Lenguajes procedimentales

Las funciones y los procedimientos almacenados pueden escribirse en varios lenguajes procedimentales. Además, PostgreSQL define una interfaz para programación de aplicaciones con objeto de aprovechar cualquier lenguaje de programación con esta finalidad. Los lenguajes de programación pueden registrarse a petición de los usuarios y pueden ser dignos de confianza (trusted) o no dignos de confianza (untrusted). Estos últimos permiten un acceso ilimitado al SGBD y al sistema de archivos, y escribir en ellos las funciones almacenadas exige privilegios de superusuario. • PL/pqSQL. Se trata de un lenguaje digno de confianza que añade a SQL posibilidades de programación procedimental (por ejemplo, variables y control de flujo). Es muy parecido a PL/pqSQL de Oracle. Aunque no se puede transferir el código tal cual entre uno y otro, la portabilidad suele resultar sencilla. • PL/Tcl, PL/Perl y PL/Python. Estos lenguajes aprovechan la potencia de TcI, Perl y Python para escribir en el servidor funciones y procedimientos almacenados. Los dos primeros están disponibles tanto en versión digna de confianza como en versión no digna de confianza (PL/Tcl, PL/Perl y PL/TclU, PL/PerlU, respectivamente), mientras que PL/Python no es digno de confianza en el momento de escribir este libro. Cada uno de ellos tiene enlaces que permiten el acceso al sistema de bases de datos mediante una interfaz específica de ese lenguaje. 26.3.3.5 Interfaz de programación para servidores

La interfaz de programación para servidores (Server Programming Interface, SPI) es una interfaz para programadores de aplicaciones que permite que las funciones de C definidas por los usuarios (véase el Apartado 26.3.3.2) ejecuten comandos SQL arbitrarios dentro de las funciones. Esto ofrece a los escritores de funciones definidas por los usuarios la posibilidad de implementar en C sólo las partes fundamentales y de aprovechar con facilidad toda la potencia del motor de bases de datos relacionales para hacer la mayor parte del trabajo. 26.4 Gestión de transacciones en PostgreSQL

El control de concurrencia de PostgreSQL implementa tanto el control de concurrencia de varias versiones (Multiversion Concurrency Control, MVCC) como el bloqueo de dos fases. El protocolo empleado depende del tipo de instrucción en ejecución. Para las instrucciones LMD1 se emplean esquemas MVCC parecidos al que se presenta en el Apartado 16.5.1. El control de concurrencia para las instrucciones LDD, por su parte, se basa en el bloqueo de dos fases estándar. 26.4.1 Control de concurrencia en PostgreSQL

Dado que los detalles del protocolo MVCC de PostgreSQL dependen del nivel de aislamiento solicitado por la aplicación, se comenzará con una visión general de los niveles de aislamiento que ofrece PostgreSQL. Luego se describirán las ideas principales subyacentes al esquema MVCC de PostgreSQL, a lo que seguirá la discusión de su implementación en el MVCC de PostgreSQL y algunas implicaciones en relación con la gestión del almacenamiento por PostgreSQL, el diseño de las aplicaciones de usuario para PostgreSQL y el rendimiento de las bases de datos de PostgreSQL. Este apartado concluirá con una visión general de los bloqueos para las instrucciones LDD y una discusión del control de concurrencia para los índices. 26.4.1.1 Niveles de aislamiento en PostgreSQL

La norma de SQL define tres niveles de consistencia débiles, además del nivel de consistencia secuenciable, en el que se basa la mayor parte del estudio en este libro. La finalidad de ofrecer los niveles de consistencia débil es permitir un mayor grado de concurrencia para las aplicaciones que no necesiten 1. Las instrucciones LMD son instrucciones que actualizan o leen los datos de una tabla, es decir, select, insert, update, fetch y copy. Las instrucciones LDD afectan a toda la tabla, pueden eliminarla o cambiar su esquema, por ejemplo. Las instrucciones DDL y algunas otras instrucciones exclusivas de PostgreSQL se estudiarán más adelante en este apartado.

www.detodoprogramacion.com


818

Capítulo 26

PostgreSQL

Nivel de aislamiento Lectura no comprometida Lectura comprometida Lectura repetida Secuenciable Figura 26.5

Lectura sucia Posible Posible Posible No

Lectura irrepetible Posible Posible Posible No

Fantasma Posible Posible Posible No

Definición de los cuatro niveles de aislamiento estándar de SQL.

las sólidas garantías que ofrece la secuencialidad. Entre los ejemplos de estas aplicaciones están las transacciones duraderas que recopilan estadísticas de la base de datos y cuyos resultados no tienen por qué ser muy precisos. La norma SQL define los diferentes niveles de aislamiento en términos de tres fenómenos que violan la secuencialidad. Esos tres fenómenos se denominan lectura irrepetible, lectura sucia y lectura fantasma, y se definen de la manera siguiente: • Lectura irrepetible. Una transacción lee dos veces el mismo objeto durante la ejecución y encuentra un valor diferente en la segunda lectura, aunque la transacción no haya cambiado ese valor mientras tanto. • Lectura sucia. La transacción lee valores escritos por otra transacción que todavía no se ha comprometido. • Lectura fantasma. Una transacción vuelve a ejecutar una consulta que devuelve un conjunto de filas que satisfacen una condición de búsqueda y descubre que el conjunto de filas que satisfacen la condición ha cambiado como consecuencia de otra transacción comprometida recientemente (se puede hallar una explicación más detallada de este fenómeno en el Apartado 16.7.3). Debería resultar evidente que cada uno de los fenómenos anteriores viola el aislamiento de las transacciones y, por tanto, violan la secuencialidad. La Figura 26.5 muestra la definición de los cuatro niveles de aislamiento de SQL especificados en la norma SQL: lectura no comprometida, lectura comprometida, lectura repetible y lectura secuenciable—en relación con estos fenómenos. PostgreSQL soporta dos de los cuatro niveles de aislamiento, la lectura comprometida y la lectura secuenciable. 26.4.1.2 Control de concurrencia para los comandos LMD

La idea principal que subyace a MVCC es conservar diferentes versiones de cada fila, que corresponden a diferentes instancias de esa fila en diferentes momentos. El protocolo MVCC se asegura de que cada transacción sólo vea las versiones de los datos que sean consistentes con la vista de la base de datos que tiene la transacción. Cada transacción ve una instantánea de los datos, que consta únicamente de los datos que se comprometieron en el momento en que se inició la transacción2 . Esta instantánea no es necesariamente igual al estado actual de los datos. La razón de emplear MVCC es que los lectores nunca bloquean a los escritores, y viceversa. Los lectores tienen acceso a la versión más reciente de las filas que forman parte de la instantánea de la transacción. Los escritores crean su propia copia independiente de la fila que se va a actualizar. El Apartado 26.4.1.3 muestra que el único conflicto que hace que se bloquee una transacción surge si dos escritores intentan actualizar la misma fila. Por el contrario, con el enfoque estándar de bloqueo de dos fases, puede que se bloqueen tanto los lectores como los escritores, ya que sólo hay una versión de cada objeto de datos y tanto las operaciones de lectura como las de escritura deben obtener un bloqueo antes de tener acceso a los datos. MVCC de PostgreSQL es muy parecido en espíritu al esquema de ordenación de marcas temporales multiversión que se describe en el Apartado 16.5.1. PostgreSQL no emplea nunca bloqueos para los comandos LMD de manera explícita y, por tanto, no es necesaria ninguna interacción con el administrador de bloqueos. Esto se diferencia del esquema del MVCC empleado por Oracle, el único sistema 2. Además, las transacciones con varias consultas también ven los datos de consultas anteriores de la misma transacción.

www.detodoprogramacion.com


26.4

Gestión de transacciones en PostgreSQL

819

comercial de bases de datos que utiliza MVCC en lugar del bloqueo de dos fases. El esquema del MVCC de Oracle es, básicamente, el protocolo de bloqueo de dos fases multiversión que se describe en el Apartado 16.5.2.

26.4.1.3 Implementación de MVCC en PostgreSQL

En el corazón de MVCC de PostgreSQL se halla el concepto de visibilidad de tuplas. Las tuplas de PostgreSQL hacen referencia a versiones de las filas. La visibilidad de tuplas define la versión válida de las potencialmente numerosas versiones de cada fila de una tabla en el contexto de una instrucción o transacción dada. Una tupla es visible para una transacción TA si se cumplen las dos condiciones siguientes: 1. La tupla fue creada por una transacción TB que comenzó a ejecutarse y se comprometió antes de que la transacción TA comenzara a ejecutarse. 2. Las actualizaciones de la tupla (si es que se ha llevado a cabo alguna) las ejecutó una transacción TC que • se abortó o • comenzó a ejecutarse después de la transacción TA o • estaba en proceso al comienzo de TA . El objetivo de las condiciones anteriores es asegurarse de que cada transacción sólo tenga acceso a los datos que se comprometieron en el momento en que la transacción comenzó a ejecutarse. PostgreSQL mantiene las siguientes estructuras de datos para comprobar eficientemente estas condiciones: • Se asigna un identificador de transacción, que sirve simultáneamente como marca de tiempo, en el momento del comienzo de la transacción. PostgreSQL utiliza un contador lógico (como se describe en el Apartado 16.2.1) para la asignación de los identificadores de transacciones. • Un archivo de registro denominado pg_clog contiene el estado actual de cada transacción. El estado puede ser en progreso, comprometida o abortada. • Cada tupla de una tabla tiene una cabecera con tres campos: xmin, que contiene el identificador de la transacción que ha creado la tupla y que, por tanto, se denomina también identificador de transacción creadora; xmax, que contiene el identificador de transacción de la transacción de sustitución o eliminación (o null, si no se elimina o sustituye) y que también se conoce como identificador de transacción expiradora; y un enlace adelantado a nuevas versiones de la misma fila lógica, si es que hay alguna. • Se crea una estructura de datos SnapshotData bien en el momento inicial de la transacción, bien en el momento inicial de la consulta, según el nivel de aislamiento (que se describe con más detalle más adelante). La estructura de datos SnapshotData contiene, entre otras cosas, una lista de todas las transacciones activas en el momento en que se toma la instantánea. La Figura 26.6 ilustra estas estructuras de datos mediante un ejemplo sencillo que implica a una base de datos con una sola tabla, la tabla sucursal de la Figura 2.3. La tabla sucursal contiene tres atributos, el nombre de la sucursal, la ciudad en la que está ubicada y los activos de la sucursal. La Figura 26.6 muestra un fragmento de la tabla sucursal que sólo contiene (las versiones de) la fila de la sucursal de “Galapagar”. Las cabeceras de las tuplas indican que la fila la creó originalmente la transacción 100, y que posteriormente la actualizaron las transacciones 102 y 106. La Figura 26.6 muestra también un fragmento del archivo de registro pg_log. Según el archivo pg_log, las transacciones 100 y 102 quedan comprometidas, mientras que las transacciones 104 y 106 se hallan procesándose. Dadas las estructuras de datos anteriores, las dos condiciones que hay que satisfacer para que una tupla resulte visible pueden reescribirse de la manera siguiente:

www.detodoprogramacion.com


820

Capítulo 26

PostgreSQL

Tabla de la base de datos sentido cronológico xmin xmax datos (nombre_sucursal, ciudad_sucursal, activos)

... ...

... ... 100 102 ... ...

...... Galapagar Arganzuela 71.000.000 ......

...

102 106 ... ...

Galapagar Arganzuela 64.000.000 ...... Galapagar Arganzuela 68.000.000

106

x

archivo pg_ log XID Indicadores de estado ... 100 ... 102 ... 104 ... 106 ...

... 10 ... 10 ... 00 ... 00 ...

Transacción 104 select activos from sucursal where nombre_sucursal = "Galapagar" Figura 26.6

01 Abortada 10 Comprometida

Las estructuras de datos de PostgreSQL empleadas para MVCC

1. El identificador de transacción creadora de la cabecera de la tupla • es una transacción comprometida de acuerdo con el archivo pg_log y • es menor que el contador de transacciones almacenado al comienzo de la consulta en SnapshotData y • no estaba procesándose al comienzo de la consulta según SnapshotData. 2. El identificador de transacción expiradora • está en blanco o abortado o • es mayor que el contador de transacciones almacenado al comienzo de la consulta en SnapshotData o • estaba procesándose al comienzo de la consulta según SnapshotData. Por ejemplo, la única versión de la fila correspondiente a la sucursal de “Galapagar” que es visible para la transacción 104 de la Figura 26.6 es la segunda versión de la tabla, creada por la transacción 102. La primera versión, creada por la transacción 100 no es visible, dado que viola la condición 2: el identificador de transacción expiradora de esta tupla es 102, que corresponde a una transacción que no está abortada y que tiene un identificador de transacción menor que la transacción 104. La tercera versión de la sucursal “Galapagar” no es visible, dado que la creó la transacción 106, que tiene un identificador de transacción mayor que la transacción 104, lo que implica que esta versión no se había comprometido en el momento en que la transacción 104 comenzó a ejecutarse. Además, la transacción 106 sigue procesándose, lo que viola otra de las condiciones. La segunda versión de la fila cumple todas las condiciones de visibilidad de las tuplas. Los detalles del modo en que el MVCC de PostgreSQL interactúa con la ejecución de las instrucciones de SQL dependen de si la instrucción es insert, select, update o delete. El caso más sencillo es el de la instrucción insert. A diferencia del caso de los bloqueos de dos fases, para las instrucciones insert no hay esencialmente ninguna interacción con el protocolo de control de concurrencia durante la ejecución de la instrucción: las instrucciones insert se limitan a crear una nueva tupla basada en los datos de la instrucción, inicializar la cabecera de la tupla (el identificador de creación) e insertar la nueva tupla en la tabla. Cuando el sistema ejecuta una instrucción select, update o delete, la interacción con el protocolo MVCC depende del nivel de aislamiento especificado por la aplicación. Si el nivel de aislamiento es

www.detodoprogramacion.com


26.4

Gestión de transacciones en PostgreSQL

821

lectura comprometida, el procesamiento de una nueva instrucción comienza por la creación de una nueva estructura de datos SnapshotData (independientemente de si la instrucción comienza una nueva transacción o forma parte de otra ya existente). A continuación, el sistema identifica las tuplas objetivo; es decir, las tuplas que son visibles con respecto a SnapshotData y cumplen los criterios de búsqueda de la instrucción. En el caso de las instrucciones select, el conjunto de tuplas objetivo constituye el resultado de la consulta. En el caso de las instrucciones update o delete, se necesita un paso adicional tras identificar las tuplas objetivo, antes de que pueda tener lugar la verdadera operación de actualización o de eliminación. El motivo es que la visibilidad de las tuplas sólo garantiza que la tupla haya sido creada por una transacción comprometida antes del inicio de la instrucción update / delete. No obstante, es posible que, desde el inicio de la consulta, la tupla haya sido actualizada o eliminada por otra transacción que se esté ejecutando de manera concurrente. Esto puede detectarse examinando el identificador de transacción expiradora de la tupla. Si el identificador de transacción expiradora corresponde a una transacción que todavía esté ejecutándose, es necesario esperar a que se complete esa transacción. Si la transacción se aborta, la instrucción update o delete puede seguir adelante y llevar a cabo la verdadera operación de actualización o de eliminación. Si la transacción se compromete, el criterio de búsqueda de la instrucción update / delete debe volver a evaluarse y, sólo si la tupla sigue cumpliendo los criterios, puede llevarse a cabo la actualización o la eliminación. La realización de la operación de actualización o de eliminación incluye la creación de una nueva tupla (con su correspondiente cabecera que contendrá el identificador de creación) y también la actualización de la información del cabecera de la tupla vieja (es decir, el identificador de transacción expiradora). Volviendo al ejemplo de la Figura 26.6, la transacción 104, que consiste sólo en una instrucción select, identifica la segunda versión de la fila Galapagar como tupla objetivo y la devuelve de manera inmediata. Si, en vez de eso, la transacción 104 fuera una instrucción de actualización, por ejemplo, que intentara incrementar los activos de la sucursal de Galapagar en algún importe, tendría que esperar a que la transacción 106 se completara. Luego volvería a evaluar la condición de búsqueda y, sólo si siguiera cumpliéndose, seguiría adelante con la actualización. Emplear el protocolo descrito anteriormente para las instrucciones update y delete sólo proporciona el nivel de aislamiento de lectura comprometida. La secuencialidad puede violarse de varias maneras. En primer lugar, son posibles lecturas no repetibles. Dado que cada consulta de una transacción comienza con una nueva instantánea, una consulta de la transacción podría ver el efecto de las transacciones completadas entretanto que no fueran visibles a consultas anteriores de la misma transacción. Siguiendo la misma línea de pensamiento, son posibles las lecturas fantasmas. Además, una consulta update puede ver los efectos de las actualizaciones concurrentes llevadas a cabo por otras consultas en la misma fila, pero no ve el efecto de esas consultas concurrentes en otras filas de la base de datos. Con objeto de proporcionar el nivel de aislamiento secuenciable de PostgreSQL, MVCC de PostgreSQL elimina las violaciones de la secuencialidad de dos maneras: en primer lugar, cuando determina la visibilidad de las tuplas, todas las consultas de una misma transacción utilizan una instantánea del comienzo de la transacción, en lugar de usarla del comienzo de cada consulta. Así, las sucesivas consultas de una misma transacción siempre ven los mismos datos. En segundo lugar, el modo en que se procesan las actualizaciones y las eliminaciones es diferente en el modo secuenciable y en el modo de lectura comprometida. Al igual que en el modo de lectura comprometida, las transacciones esperan tras identificar una fila objetivo visible que cumple la condición de búsqueda y está siendo actualizada o eliminada por otra transacción concurrente. Si la transacción concurrente que está ejecutando la actualización o la eliminación se aborta, la transacción que se halla en espera puede seguir adelante con su propia actualización. No obstante, si la transacción concurrente se compromete, no hay manera de que PostgreSQL garantice la secuencialidad de la transacción en espera. Por tanto, la transacción en espera retrocede y devuelve el mensaje de error “Can’t serialize access due to concurrent update” (No se puede secuenciar el acceso debido a una actualización concurrente). Depende de cada aplicación el manejo correcto de los mensajes de error como el anterior, abortando la transacción correspondiente y reiniciando toda la transacción desde el principio. Obsérvese que los retrocesos debidos a problemas de secuencialidad sólo son posibles para las instrucciones de actualización. Sigue cumpliéndose que las transacciones sólo de lectura no entran nunca en conflicto con otras transacciones.

www.detodoprogramacion.com


822

Capítulo 26

PostgreSQL

26.4.1.4 Repercusiones del empleo de MVCC

El empleo del esquema MVCC de PostgreSQL tiene repercusiones en tres áreas diferentes: (1) Se le asigna carga extra al gestor de almacenamiento, ya que necesita mantener diferentes versiones de las tuplas; (2) hace falta extremar el cuidado al desarrollar aplicaciones concurrentes, ya que el MVCC de PostgreSQL puede generar sutiles, pero importantes, diferencias en el modo en que se comportan las transacciones concurrentes respecto a los sistemas en que se utiliza el bloqueo de dos fases estándar; (3) el rendimiento de PostgreSQL depende de las características de la carga de trabajo que se ejecute en él. Las repercusiones del MVCC de PostgreSQL se describen a continuación con más detalle. La creación y almacenamiento de varias versiones de cada fila puede llevar a un consumo excesivo de almacenamiento. Para aliviar este problema, PostgreSQL libera periódicamente espacio mediante la identificación y la eliminaciones de versiones de las filas que ya no resultan necesarias. Esta funcionalidad se implementa mediante el comando vacuum. El comando vacuum se ejecuta en segundo plano como si fuera un demonio, pero también pueden invocarlo directamente los usuarios. El comando vacuum ofrece diferentes modos de operación: el comando vacuum sencillo simplemente reclama el espacio ocupado por las filas que ya no se utilizan y deja ese espacio libre para reutilizarlo. Esta forma del comando puede operar en paralelo con la lectura y la escritura normales de las tablas. El comando vacuum full lleva a cabo un procesamiento más amplio, que incluye el traslado de tuplas de unos bloques a otros para intentar compactar las tablas en un número mínimo de bloques de disco. Esta modalidad es mucho más lenta y exige el bloqueo exclusivo de cada tabla mientras se procesa. Cuando se invoca con el parámetro opcional analyze, vacuum reúne estadísticas del contenido de las tablas que está vaciando. El resultado se utiliza luego para actualizar la tabla de sistema pg_statistic, lo que permite que el planificador de consultas de PostgreSQL realice mejores elecciones al planificar las consultas. Debido al empleo del control de concurrencia multiversión en PostgreSQL, el traslado de aplicaciones desde otros entornos a PostgreSQL puede exigir algunas precauciones adicionales para garantizar la consistencia de los datos. Por ejemplo, considérese una transacción TA que ejecuta una instrucción select. Dado que los lectores de PostgreSQL no bloquean los datos, los datos leídos y seleccionados por TA pueden ser sobrescritos por otra transacción concurrente, TB , mientras que TA todavía se está ejecutando. En consecuencia, puede que parte de los datos que TA devuelve ya no estén actualizados en el momento de completarse TA . Puede que TA devuelva filas que otras transacciones hayan modificado o eliminado mientras tanto. Para garantizar la validez de las filas en cada momento y protegerla de las transacciones concurrentes, las aplicaciones deben utilizar select for update o adquirir de manera explícita un bloqueo con el comando lock table correspondiente. El enfoque que PostgreSQL da al control de concurrencia proporciona un rendimiento óptimo para las cargas de trabajo que contienen muchas más lecturas que actualizaciones ya que, en ese caso, las posibilidades de que dos actualizaciones entren en conflicto y den lugar al retroceso de una transacción son muy bajas.

26.4.1.5 Control de la concurrencia LDD

Los mecanismos de MVCC descritos en el apartado anterior no protegen a las transacciones de las operaciones que afectan a tablas completas como, por ejemplo, las transacciones que descartan una tabla o modifican su esquema. Para ello, PostgreSQL ofrece bloqueos explícitos que los comandos LDD se ven obligados a adquirir antes de comenzar su ejecución. Estos bloqueos siempre se basan en las tablas (en vez de basarse en las filas) y se adquieren y se liberan de acuerdo con el estricto protocolo de bloqueo de dos fases. La Figura 26.7 muestra una lista de todos los tipos de bloqueos ofrecidos por PostgreSQL, los comandos que los utilizan y la compatibilidad con otros modos de bloqueo. Los nombres de los tipos de bloqueo suelen tener un origen histórico y no reflejan necesariamente el uso que se les da. Por ejemplo, todos los bloqueos son bloqueos del nivel de tabla, aunque algunos tengan en el nombre la palabra “fila”. Los comandos LMD sólo adquieren bloqueos de los tipos 1, 2 y 3. Estos tres tipos de bloqueo son compatibles entre sí, ya que MVCC se preocupa de proteger esas operaciones unas de otras. Los comandos LDD sólo adquieren esos bloqueos para protegerse de comandos LDD.

www.detodoprogramacion.com


26.4

Gestión de transacciones en PostgreSQL

Nombre del bloqueo De acceso compartido De fila compartido De fila exclusivo

Entra en conflicto con De acceso exclusivo Exclusivo De actualización compartida exclusivo

De actualización compartida exclusivo

De actualización compartida exclusivo De fila compartida exclusivo Exclusivo De acceso exclusivo De fila exclusivo De actualización compartida exclusivo De fila compartida exclusivo De acceso exclusivo De fila exclusivo De actualización compartida exclusivo Compartido De fila compartida exclusivo De acceso exclusivo De fila compartido De fila exclusivo De actualización compartida exclusivo Compartido De fila compartida exclusivo De acceso exclusivo Entra en conflicto con los bloqueos de todos los modos

Compartido

De fila compartida exclusivo

Exclusivo

De acceso exclusivo

Figura 26.7

823

Adquirido por consulta select consulta select for update consultas update delete insert vacuum

create index

drop table alter table vacuum full

Modos de bloqueo en el nivel de tabla.

Aunque el principal objetivo es proporcionar control interno de la concurrencia a PostgreSQL para los comandos LDD, las aplicaciones de PostgreSQL también pueden adquirir de manera explícita todos los bloqueos de la Figura 26.7 mediante el comando lock table. Los bloqueos se registran en una tabla de bloqueos que se implementa como una tabla asociativa en memoria compartida que utiliza como claves el tipo y el identificador del objeto que se bloquea. Si una transacción desea adquirir un bloqueo sobre un objeto que otra transacción retiene en un modo no compatible, tiene que esperar hasta que se libere el bloqueo. Las esperas de bloqueo se implementan mediante semáforos. Cada transacción tiene asociado un semáforo. Cuando espera debido a un bloqueo, realmente es debido al semáforo asociado con la transacción que tiene el bloqueo. Una vez el titular del bloqueo lo libera, se lo comunica a la transacción que está esperando mediante el semáforo. Al implementar las esperas por bloqueo titular de bloqueo, en vez de hacerlo por objeto bloqueado, PostgreSQL necesita al menos un semáforo por cada transacción concurrente, en lugar de uno por cada objeto bloqueable. La detección de interbloqueos en PostgreSQL se basa en tiempos límites. De manera predeterminada, la detección de interbloqueos se activa si una transacción ha estado esperando debido a un bloqueo más de un segundo. El algoritmo de detección de interbloqueos crea un gráfico de esperas en términos de la información de la tabla de bloqueos y busca en ese gráfico dependencias circulares. Si encuentra alguna, lo que significa que se ha detectado un interbloqueo, la transacción que desencadenó el interbloqueo se aborta y devuelve un error al usuario. Si no se detecta ningún ciclo, la transacción sigue esperando debido al bloqueo. A diferencia de algunos sistemas comerciales, PostgreSQL no ajusta el parámetro de tiempo límite de bloqueo, pero permite que el administrador lo ajuste manualmente. Lo ideal sería escoger este parámetro del orden del tiempo de vida de las transacciones, con objeto de optimizar el equilibrio entre el tiempo que se tarda en detectar un interbloqueo y el trabajo perdido al ejecutar el algoritmo de detección de interbloqueos cuando no se ha producido ninguno.

www.detodoprogramacion.com


824

Capítulo 26

PostgreSQL

26.4.1.6 Bloqueos e índices

Los bloqueos realizados para el acceso a índices dependen del tipo de índice. Para GiST y para los árboles R se utilizan bloqueos sencillos del nivel de índices que se mantienen durante todo la duración del comando. Los accesos a índices asociados permiten más concurrencia mediante el empleo de bloqueos del nivel de páginas que se liberan una vez procesada la página. No obstante, los bloqueos del nivel de páginas para los índices asociados no están libres de interbloqueos. El tipo de índice recomendado para las aplicaciones con un grado elevado de concurrencia son los índices B, ya que ofrecen bloqueos de grano fino sin condiciones de interbloqueo: el acceso a los índices B se protege mediante bloqueos compartidos o exclusivos de corta duración del nivel de páginas. Los bloqueos se liberan en cuanto se captura o inserta cada tupla del índice. 26.4.2 Recuperación

Históricamente, PostgreSQL no usaba un registro histórico de escritura anticipada (Write–Ahead Logging, WAL) para la recuperación y, por tanto, no podía garantizar la consistencia en caso de caída. Las caídas pueden acabar dando lugar a estructuras de índice inconsistentes o, peor aún, a tablas con sus contenidos completamente corruptos, debido a las páginas de datos escritas parcialmente. En consecuencia, a partir de la versión 7.1, PostgreSQL emplea la recuperación estándar basada en registro histórico de escritura anticipada con una fase rehacer (redo) y una fase deshacer (undo) parecidas a las de ARIES. El Apartado 17.6.1 ofrece una introducción a estas fases y al concepto de registro histórico de escritura anticipada y el Apartado 17.8.6 ofrece una visión general de ARIES. La principal diferencia en la implementación de la recuperación en PostgreSQL es que el MVCC de PostgreSQL permite algunas simplificaciones en comparación con la recuperación estándar basada en el registro histórico. En primer lugar, en PostgreSQL la recuperación no necesita deshacer los efectos de las transacciones abortadas. Las transacciones en proceso de aborto realizan una entrada en el archivo pg_clog que registra el hecho de que está en proceso de aborto. En consecuencia, todas las versiones de las filas que deja atrás no serán nunca visibles para las demás transacciones. El único caso en que este enfoque puede acabar dando lugar a problemas se produce cuando una transacción aborta debido a una caída del proceso PostgreSQL correspondiente y ese proceso no tiene la posibilidad de crear la entrada pg_clog antes de la caída. PostgreSQL maneja esto de la manera siguiente: siempre que una transacción comprueba el estado de otra en el archivo pg_clog y descubre que el estado es “en proceso”, comprueba si la transacción se está ejecutando realmente en alguno de los procesos de PostgreSQL. Si ningún proceso de PostgreSQL está ejecutando la transacción, se deduce que el proceso correspondiente se ha caído y la entrada de pg _clog de la transacción se actualiza a “abortada”. En segundo lugar, la recuperación basada en registro histórico de escritura anticipada se simplifica debido a que MVCC de PostgreSQL ya realiza un seguimiento de parte de la información necesaria para el registro WAL. Más concretamente, no hace falta registrar el inicio, el compromiso y el aborto de las transacciones, ya que MVCC registra el estado de cada transacción en pg_clog. 26.5 Almacenamiento e índices

Al igual que con el resto de PostgreSQL, la filosofía de diseño de la disposición y el almacenamiento de los datos tiene dos objetivos gemelos de (1) una implementación sencilla y limpia y (2) la facilidad de administración. Las bases de datos gestionadas por los servidores de PostgreSQL las divide el administrador en agrupaciones de bases de datos, donde todos los datos y los metadatos asociados con cada agrupación se almacenan en el mismo directorio del sistema de archivos. A diferencia de los sistemas comerciales, PostgreSQL no soporta “espacios de tablas”3 que permitirían que el administrador de la base de datos tuviera un control preciso de la ubicación de almacenamiento de cada objeto físico concreto. Además, PostgreSQL sólo soporta “sistemas de archivos cocinados”, lo que excluye el empleo de particiones de disco sin formato. Al igual que con el resto de PostgreSQL, la filosofía de diseño de la disposición y el almacenamiento de los datos tiene dos objetivos gemelos de (1) una implementación sencilla y limpia y (2) la facilidad 3. El desarrollo de los espacios de tablas se está llevando a cabo activamente y formará parte de versiones futuras.

www.detodoprogramacion.com


26.5

datos de cabecera de página

...

plin1

plin2

Almacenamiento e índices

plin3

825

plin4

plinn dp_inferior

dp_superior

...

tuplan tupla2

Figura 26.8

tupla1

tupla3 “espacio especial”

Formato de página con ranuras para las tablas de PostgreSQL.

de administración. Las bases de datos gestionadas por los servidores de PostgreSQL las divide el administrador en agrupaciones de bases de datos, donde todos los datos y los metadatos asociados con cada agrupación se almacenan en el mismo directorio del sistema de archivos. A diferencia de los sistemas comerciales, PostgreSQL no soporta “espacios de tablas”4 que permitirían que el administrador de la base de datos tuviera un control preciso de la ubicación de almacenamiento de cada objeto físico concreto. Además, PostgreSQL sólo soporta “sistemas de archivos cocinados”, lo que excluye el empleo de particiones de disco sin formato. La simplicidad del diseño del sistema de almacenamiento de PostgreSQL puede crear algunas limitaciones en el rendimiento. La falta de soporte para los espacios de tablas limita las posibilidades de utilizar con eficiencia los recursos de almacenamiento disponibles, en especial varios discos que operen en paralelo. Además, el tamaño de bloque de todos los objetos de la base de datos está predeterminado (el valor predeterminado es de 8 KB y puede modificarse recompilando el código), lo que puede dar lugar a rendimientos por debajo de lo normal al tratar con medios de almacenamiento que manejen bloques de datos de mayor tamaño. El empleo de sistemas de archivos cocinados da lugar al empleo de memorias intermedias dobles, en las que cada bloque se captura primero del disco a la memoria intermedia del sistema de archivos (en el espacio del núcleo) antes de copiarlo al grupo de memorias intermedias de PostgreSQL. Por otro lado, las empresas modernas utilizan cada vez más sistemas de almacenamiento como los medios de almacenamiento conectados en red y las redes de áreas de almacenamiento, en lugar de los discos conectados a los servidores. La filosofía, en este caso, es que el almacenamiento es un servicio que se administra y se ajusta con facilidad de manera independiente. El empleo de RAID para conseguir tanto paralelismo como almacenamiento redundante se explica en el Apartado 11.3. Por tanto, la sensación de muchos desarrolladores de PostgreSQL es que, para una amplia mayoría de aplicaciones, y, en realidad, para el público de PostgreSQL, las limitaciones de rendimiento son mínimas y están justificadas por su facilidad de administración y de gestión, así como por la simplicidad de su implementación. 26.5.1 Tablas

La unidad principal de almacenamiento de PostgreSQL es la tabla. En PostgreSQL las tablas se almacenan en “archivos en montículo”. Estos archivos utilizan una forma del formato estándar de “página con ranuras” que se describe en el Apartado 11.6.2.1. El formato PostgreSQL se muestra en la Figura 26.8. En cada página, a la cabecera le sigue un array de “punteros de línea”. Cada puntero de línea guarda la posición (en relación con el comienzo de la página) y la longitud de una tupla concreta de la página. Las tuplas reales se almacenan en orden inverso de los punteros de línea desde el final de la página. Cada registro de un archivo en montículo queda identificado por un identificador de tupla (tuple ID, TID). El TID consiste en un identificador de bloque de 4 bytes que especifica la página del archivo 4. El desarrollo de los espacios de tablas se está llevando a cabo activamente y formará parte de versiones futuras.

www.detodoprogramacion.com


826

Capítulo 26

PostgreSQL

que contiene la tupla y un identificador de ranura de 2 bytes. El identificador de ranura es un índice del array de punteros de línea que, a su vez, se utiliza para tener acceso a la tupla. Aunque esta infraestructura permite que las tuplas de una página se eliminen o se actualicen, en el enfoque de MVCC de PostgreSQL ninguna de esas operaciones se lleva a cabo realmente de modo físico durante el procesamiento normal. Cuando se vacía una página, sin embargo, las tuplas caducadas se eliminan físicamente, lo que hace que se formen agujeros en la página. El método indirecto de acceso a las tuplas mediante el array de punteros de línea permite la reutilización de dichos agujeros. La longitud de cada tupla viene limitada normalmente por la de las páginas de datos. Esto hace difícil almacenar tuplas muy largas. Cuando PostgreSQL encuentra una tupla tan grande, intenta comprimir (toast) las columnas de gran tamaño. Los datos de las columnas comprimidas son sustituidos por un puntero que localiza una versión comprimida de los datos que se almacenan fuera de la página. 26.5.2 Índices

PostgreSQL soporta los diferentes tipos de índices, incluyendo los basados en métodos de acceso exten-

sible del usuario. Aunque los métodos de acceso pueden usar un formato de página diferente, todos los índices disponibles en PostgreSQL usan el mismo formato de página con ranuras descrito en el Apartado 26.5.1. 26.5.2.1 Tipos de índices

PostgreSQL soporta los siguientes tipos de índices:

• De árbol B. El tipo de índice predeterminado es un método de árbol B que es una implementación de los árboles de alta concurrencia de Lehman–Yao (esto se explica con detalle en el Apartado 16.9). Estos índices resultan útiles para las consultas de igualdad y para las de rango sobre datos ordenables, y también para algunas operaciones de coincidencia de patrones como la expresión like. • De asociación. Los índices asociativos de PostgreSQL son una implementación de la asociación lineal (para más información sobre los índices de asociación, véase el Apartado 12.6.3). Este tipo de índices resulta útil para las operaciones de igualdad sencillas. Se puede crear un índice asociativo con la siguiente instrucción LDD: create index nombreind on nombretab using hash (nombrecol) Se ha demostrado que los índices asociativos de PostgreSQL tienen un rendimiento de búsqueda no mejor que el de los árboles B, pero tienen un tamaño y unos costes de mantenimiento considerablemente mayores. Por tanto, casi siempre es preferible utilizar índices de árbol B a índices de asociación. • De árbol R. Para operaciones como el superposición con los tipos de datos espaciales predefinidos (caja, círculo, punto, etc.), PostgreSQL ofrece índices de árbol R. Estos índices implementan el algoritmo de división cuadrática (Apartado 24.3.5.3). Los índices de árbol R pueden crearse con la siguiente instrucción LDD: create index nombreind on nombretab using rtree (nombrecol) La gestión de los datos espaciales se estudió en el Apartado 24.3, con información sobre los árboles R y otras técnicas de indexación. • GiST. Finalmente, PostgreSQL soporta un cuarto tipo de índices basado en árboles extensibles denominado GiST, o árboles de búsqueda generalizados (Generalized Search Trees). GiST es un método de acceso equilibrado estructurado en árboles que puede utilizarse para implementar una familia completa de índices diferentes; por ejemplo, los índices de árbol B predeterminados y los índices de árbol R pueden implementarse mediante GiST. Los índices GiST facilitan a los

www.detodoprogramacion.com


26.6

Procesamiento y optimización de consultas

827

expertos en dominios que estén versados en un tipo de datos concreto (como los datos de imágenes) el desarrollo de índices que mejoren el rendimiento sin tener que tratar con los detalles internos del sistema de bases de datos. Entre los ejemplos de índices creados empleando GiST están la indexación de cubos multidimensionales y la indexación de texto completo para las consultas de recuperación de información. Véanse las notas bibliográficas para obtener referencias de más información sobre los índices GiST. 26.5.2.2 Otras variaciones de los índices

Para algunos de los tipos de índices que se han descrito PostgreSQL soporta más variaciones complejas como: • Índices de varias columnas. Resultan útiles para conjuntos de predicados que abarcan varias columnas de una tabla. Los índices multicolumna sólo se soportan para índices de árbol B y para índices GiST. • Índices únicos. Las restricciones de clave única y de clave principal pueden aplicarse mediante el empleo de índices únicos en PostgreSQL. Sólo se pueden definir como únicos los índices de árbol B. • Índices sobre expresiones. En PostgreSQL es posible crear índices sobre expresiones escalares arbitrarias de las columnas de las tablas, y no sólo sobre columnas concretas. Esto resulta especialmente útiles cuando las expresiones en cuestión son “caras”; es decir, suponen un cálculo complicado definido por los usuarios. Un ejemplo es el soporte de comparaciones que no distinguen entre mayúsculas y minúsculas mediante la definición de un índice sobre la expresión lower(columna) y el empleo del predicado lower(columna) = ’valor’ en las consultas. Un inconveniente es que los costes de mantenimiento de los índices sobre expresiones es elevado. • Clases de operadores. Las funciones de comparación concretas empleadas para crear, mantener y utilizar los índices sobre columnas están ligadas al tipo de datos de cada columna. Cada tipo de datos tiene asociado una “clase de operador” predeterminada (que se describe en el Apartado 26.3.3.3) que identifica los operadores reales que se utilizarían normalmente. Aunque este operador predeterminado suele resultar suficiente para la mayor parte de los usos, puede que algunos tipos de datos posean varias clases “significativas”. Por ejemplo, al tratar con los números complejos, puede que resulte preferible indexar el componente real o el imaginario. PostgreSQL ofrece algunas clases de operador para operaciones de comparación de patrones (como like) sobre datos de texto que no utilicen las reglas de comparación locales concretas. • Índices parciales. Se trata de índices creados sobre un subconjunto de una tabla definido por un predicado. El índice sólo contiene entradas para tuplas que satisfagan el predicado. Los índices parciales resultan adecuados para casos en que una columna pueda contener gran número de apariciones de un número muy pequeño de valores. En esos casos, sin un índice parcial, las consultas del tipo “aguja en el pajar” que buscan un valor infrecuente acabarían examinando todo el índice. Los índices parciales que excluyen los valores frecuentes son pequeños y suponen menos operaciones E/S. Los índices parciales resultan menos costosos de mantener, ya que una fracción importante de las inserciones no participa en ellos. 26.6 Procesamiento y optimización de consultas

Cuando PostgreSQL recibe una consulta, ésta se divide primero en una representación interna que sufre una serie de transformaciones que dan lugar a un plan de consulta que el ejecutor utiliza para procesar la consulta. 26.6.1 Reescritura de consultas

La primera etapa de la transformación de una consulta es la reescritura (rewrite) y, es esta etapa la responsable del sistema de reglas (rules) del sistema de PostgreSQL. Como se explicó en el Aparta-

www.detodoprogramacion.com


828

Capítulo 26

PostgreSQL

do 26.3.2, en PostgreSQL los usuarios pueden crear reglas que se activan ante diferentes eventos, como instrucciones update, delete, insert y select. El sistema implementa una vista mediante la conversión de la definición de una vista en una regla select. Cuando se recibe una consulta que implica una instrucción select sobre la vista, se desencadena la regla select para la vista y se reescribe la consulta utilizando la definición de la vista. Las reglas se registran en el sistema utilizando el comando create rule, momento en el cual la información sobre la regla se almacena en el catálogo. Este catálogo se utiliza luego durante la reescritura de la consulta para descubrir todas las reglas candidatas para una consulta dada. La fase de reescritura trabaja primero con todas las instrucciones update, delete e insert desencadenando todas las reglas adecuadas. Obsérvese que puede que tales instrucciones sean complejas y contengan cláusulas select. En consecuencia, se desencadenan todas las demás reglas que sólo contienen instrucciones select. Dado que el desencadenamiento de una regla puede hacer que la consulta se reescriba de una manera que exija que se desencadene otra regla, las reglas se comprueban repetidamente en cada forma de la consulta reescrita hasta que se alcanza un punto fijo y no hace falta desencadenar más reglas. En PostgreSQL no hay reglas predeterminadas, sólo las definidas de manera explícita por los usuarios y de forma implícita por las definiciones de las vistas.

26.6.2 Plani cación y optimización de consultas

Una vez reescrita la consulta, se somete a la fase de planificación y optimización. En esta fase cada bloque de la consulta se trata de manera aislada y se genera un plan específico para él. Esta planificación comienza de abajo arriba desde la subconsulta más interna de la consulta reescrita, hasta su bloque de consulta más externo. El optimizador de PostgreSQL está, en su mayor parte, basado en costes. Lo ideal es generar un plan de acceso cuyo coste estimado sea mínimo. El modelo de costes incluye como parámetros tanto el coste de E/S de la captura no secuencial de páginas como los costes de CPU del procesamiento de tuplas de montículo, tuplas de índices y predicados sencillos. El proceso real de optimización se basa en una de las dos formas siguientes: • Planificador estándar. Se trata de un enfoque de optimización tradicional que se utilizaba en System R, un sistema relacional pionero desarrollado por los centros de investigación de IBM en los años 70. Es un algoritmo de programación dinámica en el que, para cada bloque, se enumeran y planifican todas las posibilidades de reunión de dos sentidos y se estima su coste de acceso. Luego se enumeran y estiman todas las posibilidades de reunión de tres sentidos, utilizando las mejores estimaciones de reunión de dos sentidos. Este proceso continúa hasta que se genera un “buen” plan para el bloque de consulta. En el Capítulo 14 se ofrecen más detalles sobre este enfoque. • Optimizador genético de consultas. Cuando el número de tablas en un bloque de consulta es muy grande, el algoritmo de programación dinámica del Sistema R se vuelve muy costoso. A diferencia de otros sistemas comerciales que pasan de manera predeterminada a técnicas avaras o basadas en reglas, PostgreSQL utiliza un enfoque más radical: un algoritmo genético que inicialmente se desarrolló para resolver problemas de rutas de viajantes. Hay pruebas anecdóticas del empleo con éxito de la optimización genética de consultas en sistemas de producción para consultas con alrededor de 45 tablas. Dado que el planificador opera de abajo arriba, puede llevar a cabo ciertas transformaciones en el plan de la consulta a medida que éste se genera. Un ejemplo es la frecuente transformación de subconsulta a reunión que aparece en muchos sistemas comerciales (generalmente implementada en la fase de reescritura). Cuando PostgreSQL encuentra una subconsulta no correlacionada (como puede ser la causada por una consulta sobre una vista), suele ser posible “elevar” la subconsulta planificada y mezclarla en el bloque de consulta del nivel superior. No obstante, las transformaciones que empujan las eliminaciones de duplicados hacia bloques de consulta de nivel inferior no suelen ser posibles en PostgreSQL.

www.detodoprogramacion.com


26.6

Procesamiento y optimización de consultas

829

La fase de optimización de consultas da lugar a un plan de consultas que es un árbol de operadores relacionales. Cada operador representa una operación concreta sobre uno o varios conjuntos de tuplas. Los operadores pueden ser unarios (por ejemplo, la reunión de bucle anidado) o n-arios (por ejemplo, la unión de conjuntos). Resulta crucial para el modelo de costes una estimación precisa del número total de tuplas que se procesarán en cada operador del plan. Esto lo deduce el optimizador en función de las estadísticas que se tienen de cada relación del sistema. Estas estadísticas indican el número total de tuplas para cada relación e información específica sobre cada columna de una relación, como puede ser la cardinalidad de esa columna, una lista de los valores más frecuentes de la tabla y su número de apariciones, y un histograma que divida los valores de la columna en grupos de igual población. Además, PostgreSQL tiene también una correlación estadística entre las ordenaciones física y lógica en las filas de los valores de las columnas; esto indica el coste de las exploraciones de índices para recuperar tuplas que pasen predicados a la columna. El ABD debe garantizar que estas estadísticas estén al día mediante la ejecución periódica del comando analyze.

26.6.3 Ejecutor de consultas

El módulo ejecutor es responsable del procesamiento de los planes de consultas producidos por el optimizador. El ejecutor sigue el modelo iterador (iterator) con un conjunto de cuatro funciones implementadas para cada operador (open, next, rescan y close). Los iteradores también se estudian como parte de los cauces bajo demanda en el Apartado 13.7.2.1. Los iteradores de PostgreSQL tienen una función adicional, rescan, que se utiliza para reiniciar subplanes (por ejemplo, para el bucle interno de una reunión) con parámetros como pueden ser los rangos de las claves del índice. Algunos de los operadores importantes del ejecutor pueden catalogarse de la siguiente manera: 1. Métodos de acceso. Los métodos de acceso reales que se utilizan en PostgreSQL para recuperar datos de objetos que se hallan en el disco son las exploraciones secuenciales desde el montículo y las exploraciones de índices. • Exploraciones secuenciales. Las tuplas de cada relación se exploran secuencialmente desde el primer bloque del archivo hasta el último. Cada tupla se devuelve al invocador sólo si es “visible” de acuerdo con las reglas de aislamiento de transacciones del Apartado 26.4.1.3. • Exploraciones de índices. Dado un rango de índices (o una clave concreta, en el caso de un índice de montículo), este método de acceso devuelve un conjunto de tuplas coincidentes del archivo de montículo asociado. No hay nada previsto para separar el acceso a los identificadores de las tuplas desde el índice y la captura de las tuplas reales. Esto evita la ordenación de los TIDs y garantiza que se tenga acceso al archivo de montículo de manera secuencial, lo que minimiza el número de operaciones de captura de páginas. 2. Métodos de reunión. PostgreSQL soporta tres métodos de reunión: reuniones por mezcla ordenadas, reuniones de bucle anidado (incluidas las variantes de índice de bucle anidado para el interior) y una reunión híbrida asociativa. 3. Ordenación. La ordenación externa se implementa en PostgreSQL mediante algoritmos que se explican en el Apartado 13.4. Los datos de entrada se dividen en secuencias ordenadas que se mezclan en una mezcla polifásica. Aunque las secuencias iniciales se formen mediante selección por sustitución, se utiliza un árbol de prioridades en lugar de una estructura de datos para fijar el número de registros que se guardan en la memoria. Esto se debe a que PostgreSQL puede trabajar con tuplas que varían considerablemente en tamaño e intenta garantizar la utilización completa del espacio de memoria configurado para la ordenación. 4. Agregación. La agregación agrupada en PostgreSQL puede basarse en la ordenación o en la asociación. Cuando el número estimado de grupos diferentes es muy grande, se utiliza la primera y, en caso contrario, se prefiere el enfoque basado en la asociación.

www.detodoprogramacion.com


830

Capítulo 26

PostgreSQL

procesos clientes

procesos servidores

aplicación cliente

proceso demonio postmaster

memoria compartida sistema unix

comunicación mediante biblioteca API

biblioteca de interfaz del cliente

solicitud inicial de conexión y de autentificación

consultas y resultados SQL

Figura 26.9

memorias intermedias de disco

creación

servidor postgreSQL (subyacente)

tablas compartidas

memorias intermedias del núcleo

disco

lectura/ escritura

La arquitectura del sistema PostgreSQL.

26.6.4 Disparadores y restricciones

En PostgreSQL (a diferencia de algunos sistemas comerciales) las características de las bases de datos activas como los disparadores y las restricciones no se implementan en la fase de reescritura. Por el contrario, se implementan como parte del ejecutor de consultas. Cuando el usuario registra los disparadores y las restricciones, los detalles se asocian con la información del catálogo para cada relación e índice adecuados. El ejecutor procesa las instrucciones update, delete e insert generando repetidamente modificaciones en las tuplas para la relación. Por cada una de esas modificaciones (una operación de actualización, eliminación o inserción) el ejecutor comprueba de manera explícita los disparadores y las restricciones candidatos, y los desencadena o aplica, antes o después de la modificación, según se requiera. 26.7 Arquitectura del sistema

La arquitectura del sistema PostgreSQL sigue el modelo de proceso por transacción. Los sitios PostgreSQL en funcionamiento son gestionados por un proceso coordinador central, denominado postmaster. El proceso postmaster es responsable de inicializar y cerrar el servidor y también de manejar las solicitudes de conexión de nuevos clientes . El postmaster asigna cada nuevo cliente que se conecta a un proceso servidor en segundo plano que es responsable de ejecutar las consultas en nombre del cliente y de devolver los resultados al cliente. Esta arquitectura se describe en la Figura 26.9. Las aplicaciones clientes pueden conectarse con el servidor de PostgreSQL y remitir consultas mediante alguna de las muchas interfaces de programación de aplicaciones de la base de datos soportadas por PostgreSQL (libpq, JDBC, ODBC, Perl DBD) que se proporcionan como bibliotecas para la parte cliente. Un ejemplo de aplicación cliente es el programa de línea de comandos psql, que se incluye en la distribución PostgreSQL estándar. El postmaster es responsable de manejar las conexiones iniciales de los clientes. Para ello, escucha constantemente si hay nuevas conexiones en un puerto conocido. Tras llevar a cabo los pasos de inicialización, como la autenticación del usuario, el postmaster genera un nuevo proceso de servidor en segundo plano para manejar el nuevo cliente. Tras esta conexión inicial, el cliente sólo interactúa con el proceso servidor en segundo plano, remitiendo consultas y recibiendo resultados de consultas. Ésta es la esencia del modelo de proceso por conexión adoptado por PostgreSQL. El proceso servidor en segundo plano es responsable de ejecutar las consultas remitidas por el cliente mediante la realización de los pasos de ejecución de consultas necesarios, incluidos el análisis, la optimización y la ejecución. Cada proceso de servidor en segundo plano sólo puede manejar una única consulta a la vez. Para ejecutar más de una consulta en paralelo la aplicación debe establecer varias conexiones con el servidor. En cualquier momento puede haber varios clientes conectados al sistema y, por tanto, varios procesos de servidor en segundo plano pueden estar ejecutándose de manera concurrente. Los procesos de servidor en segundo plano tienen acceso a los datos de la base de datos mediante el grupo de memorias intermedias de la memoria principal, que se ubica en la memoria compartida, por lo que todos los pro-

www.detodoprogramacion.com


Notas bibliográficas

831

cesos tienen la misma vista de los datos. La memoria compartida también se utiliza para implementar otras formas de sincronización entre los procesos de servidor como, por ejemplo, el bloqueo de elementos de datos. El empleo de la memoria compartida como medio de comunicación exige que el servidor de PostgreSQL se ejecute en una sola máquina; los sitios con un solo servidor no pueden extenderse por varias máquinas. Notas bibliográ cas

Se puede encontrar una extensa documentación en línea de PostgreSQL en www.postgresql.org. Este sitio Web es la fuente autorizada de información sobre las nuevas versiones de PostgreSQL, que tienen lugar con frecuencia. Hasta PostgreSQL versión 8, la única manera de ejecutar PostgreSQL bajo Microsoft Windows era utilizar Cygwin. Cygwin es un entorno similar a Linux que permite la reconstrucción de aplicaciones Linux a partir de su código para ejecutarlas bajo Windows. Más detalles en www.cygwin.com. Entre los libros sobre PostgreSQL están Douglas y Douglas [2003], y Stinson [2002]. Las reglas, tal y como se utilizan en PostgreSQL, se presentaron en Stonebraker et al. [1990]. La estructura GiST se describe en Hellerstein et al. [1995]. Las herramientas de administración de PostgreSQL, pgAccess y pgAdmin se describen en el sitio Web www.pgaccess.org y www.pgadmin.org, respectivamente. Las herramientas de diseño de bases de datos de PostgreSQL, TORA y Data Architect, se describen en www.globecom.se/tora y www.thekompany.com/products/dataarchitect, respectivamente. Las herramientas de generación de informes GNU Report Generator y GNU Enterprise se describen en www.gnu.org/software/grg y www.gnuenterprise.org, respectivamente. El servidor OLAP de Mondrian se describe mondrian.sourceforge.net. Es de código abierto, como PostgreSQL. Una alternativa de código abierto a PostgreSQL es MySQL, que está disponible para usos no comerciales bajo la Licencia Pública General GNU, pero que exige el pago para usos comerciales. Las comparaciones entre las versiones más recientes de los dos sistemas se pueden conseguir fácilmente en Web.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

27

Oracle Hakan Jakobsson Oracle Corporation

Cuando Oracle se fundó en 1977 como Software Development Laboratories por Larry Ellison, Bob Miner y Ed Oates no había productos de bases de datos relacionales comerciales. La compañía, cuyo nombre cambió posteriormente a Oracle, se estableció para construir un sistema de gestión de bases de datos como producto comercial y fue la primera en lanzarlo al mercado. Desde entonces Oracle ha mantenido una posición líder en el mercado de bases de datos relacionales, pero con el paso de los años su producto y servicios ofrecidos han crecido más allá del servicio de bases de datos relacionales. Además de las herramientas directamente relacionadas con el desarrollo y gestión de bases de datos Oracle ofrece herramientas de inteligencia de negocio, incluyendo herramientas de consulta y análisis, productos de minería de datos y un servidor de aplicaciones con una gran integración con el servidor de bases de datos. Además de los servidores y herramientas relacionados con las bases de datos, la compañía ofrece software para la planificación empresarial de recursos y gestión de relaciones con el cliente, incluyendo áreas como finanzas, recursos humanos, manufactura, marketing, ventas y gestión de cadenas de proveedores. La unidad On Demand de Oracle ofrece servicios en estas áreas como un proveedor de servicios de aplicación. Este capítulo cubre un subconjunto de características, opciones y funcionalidad de los productos Oracle. Continuamente se desarrollan nuevas versiones de los productos por lo que las descripciones de los productos están sujetas a cambios. Este conjunto de características descrito aquí está basado en la primera versión de Oracle10g. 27.1 Herramientas para el diseño de bases de datos y la consulta

Oracle proporciona una serie de herramientas para el diseño, consulta, generación de informes y análisis de datos para bases de datos, incluyendo OLAP. 27.1.1 Herramientas para el diseño de bases de datos

La mayor parte de las herramientas de diseño de Oracle están incluidas en Oracle Developer Suite. Es una familia de herramientas para los distintos aspectos de desarrollo de aplicaciones, incluyendo herramientas para el desarrollo de formularios, modelado de datos, informes y consultas. La familia de productos soporta el estándar UML (véase el Apartado 2.10) para el modelado en el desarrollo. Proporciona modelado de clases para generar código para componentes de negocio para un entorno Java así 833

www.detodoprogramacion.com


834

Capítulo 27

Oracle

como modelado de actividades para el modelado del flujo de control de propósito general. La familia también soporta XML para el intercambio de datos con otras herramientas UML. La principal herramienta de diseño de bases de datos en la familia es Oracle Designer, que traduce la lógica de negocio y el flujo de datos en definiciones de esquemas y guiones procedimentales para la lógica de las aplicaciones. Soporta varias técnicas de modelado tales como diagramas E-R, ingeniería de información y análisis y diseño de objetos. Oracle Designer almacena el diseño en Oracle Repository, que sirve como un único punto de metadatos para la aplicación. Los metadatos se pueden entonces utilizar para generar formularios e informes. Oracle Repository permite la configuración de los objetos de bases de datos, formularios, clases Java, archivos XML y otros tipos de archivos. La familia también contiene herramientas de desarrollo de aplicaciones para generar formularios, informes, y herramientas para distintos aspectos de desarrollo basado en Java y XML, incluyendo JDeveloper, que proporciona un entorno completo para el desarrollo de aplicaciones J2EE. El componente de inteligencia de negocio proporciona JavaBeans para funcionalidad analítica tal como visualización de datos, consultas y cálculos analíticos. Oracle también tiene una herramienta de desarrollo de aplicaciones para el almacén de datos. Oracle Warehouse Builder. Warehouse Builder es una herramienta para el diseño e implantación de todos los aspectos de un almacén de datos, incluyendo el diseño del esquema, asignaciones de datos y transformaciones, procesamiento de carga de datos y gestión de metadatos. Oracle Warehouse Builder soporta los esquemas 3NF y en estrella y puede también importar diseños desde Oracle Designer. Esta herramienta, junto con características de la base de datos tales como las tablas externas y las funciones de tablas, elimina generalmente la necesidad de herramientas de terceros para la extracción y transformación. 27.1.2 Herramientas de consulta

Oracle proporciona herramientas de consulta, generación de informes y análisis de datos ad hoc, incluyendo OLAP. Oracle Application Server Discoverer es una herramienta basada en Web para realizar consultas, informes, análisis y publicación Web ad hoc para usuarios finales y analistas de datos. Permite a los usuarios abstraer y concretar conjuntos de resultados, datos pivote y almacenar cálculos como informes que se pueden publicar en una serie de formatos tales como hojas de datos o HTML. Discoverer tiene asistentes que ayudan a los usuarios finales a visualizar los datos como gráficos. Oracle soporta un amplio conjunto de funciones analíticas tales como la agregación de clasificación y traslado en SQL. La interfaz de consulta de Discoverer puede generar SQL del que se puede aprovechar su funcionalidad y puede proporcionar a los usuarios finales grandes posibilidades de análisis. Puesto que el procesamiento tiene lugar en el sistema de gestión de la base de datos relacional, Discoverer no requiere generalmente un complejo motor de cálculo en el lado del cliente y existe una versión de Discoverer basada en el explorador. 27.2 Variaciones y extensiones de SQL

Oracle soporta parcial o totalmente todas las características principales de SQL:1999, con algunas pequeñas excepciones tales como distintos tipos de datos. Además, Oracle soporta un gran número de constructores del lenguaje, algunos de los cuales siguen la norma SQL:1999, mientras que otros son específicos de Oracle en sintaxis o funcionalidad. Por ejemplo Oracle soporta las operaciones OLAP descritas en el Apartado 18.2, incluyendo clasificación, agregación de traslado, cubos y abstracción. Algunos ejemplos de las extensiones SQL de Oracle son: • connect by, que es una forma de recorrido de árboles que permite cálculos al estilo del cierre transitivo en una única instrucción SQL. Es una sintaxis para una característica que Oracle tenía desde los años 80. • upsert e inserciones en varias tablas. La operación upsert combina una actualización y una inserción y es útil para combinar datos nuevos con antiguos en aplicaciones de almacén de datos. Si una nueva fila tiene el mismo valor de clave que una fila antigua se actualiza la fila antigua (por ejemplo agregando los valores desde la nueva fila), en otro caso se inserta la nueva fila en la

www.detodoprogramacion.com


27.2

Variaciones y extensiones de SQL

835

tabla. Las inserciones en varias tablas permiten actualizar varias tablas basándose en una única exploración de los nuevos datos. • cláusula with, que se describe en el Apartado 4.8.2. • cláusula model, que permite cálculos algebráicos sobre arrays de datos relacionales. Para algunas aplicaciones, esta cláusula puede ser una alternativa al uso de hojas de cálculo. 27.2.1 Características relacionales orientadas a objetos

Oracle tiene soporte extensivo para constructores relacionales orientados a objetos, incluyendo: • Tipos de objetos. Se soporta un único modelo de herencia para las jerarquías de tipos. • Tipos de colecciones. Oracle soporta varrays, que son arrays de longitud variable, y tablas anidadas. • Tablas de objetos. Se utilizan para almacenar objetos mientras se proporciona una vista relacional de los atributos de los objetos. • Funciones de tablas. Son funciones que producen conjuntos de filas como salida y se pueden utilizar en la cláusula from de una consulta. Las funciones de tablas se pueden anidar en Oracle. Si una función de tablas se utiliza para expresar algún formulario de transformación de datos, el anidamiento de varias funciones permite que se expresen varias transformaciones en una única instrucción. • Vistas de objetos. Proporcionan una vista de tablas de objetos virtuales de datos almacenados en una tabla relacional normal. Permite acceder o ver los datos en un estilo orientado a objetos incluso si los datos están realmente almacenados en un formato relacional tradicional. • Métodos. Se pueden escribir en PL/SQL, Java o C. • Funciones de agregación definidas por el usuario. Se pueden utilizar en instrucciones SQL de la misma forma que las funciones incorporadas tales como sum y count. • XML como tipo de datos nativo. Se puede utilizar para almacenar e indexar documentos XML. Oracle también puede convertir automáticamente el resultado de cualquier consulta SQL en XML. Oracle tiene dos lenguajes procedimentales principales, PL/SQL y Java. PL/SQL fue el lenguaje original de Oracle para los procedimientos almacenados y tiene una sintaxis similar al utilizado en el lenguaje Ada. Java se soporta mediante una máquina virtual Java dentro del motor de la base de datos. Oracle proporciona un paquete para encapsular procedimientos, funciones y variables relacionadas en unidades únicas. Oracle soporta SQLJ (SQL incorporado en Java) y JDBC y proporciona una herramienta para generar las definiciones de clases Java correspondientes a tipos de la base de datos definidos por el usuario. 27.2.2 OLAP

Anteriormente el producto OLAP de Oracle era un servidor de bases de datos multidimensionales separado. Actualmente el procesamiento OLAP se realiza dentro de la propia base de datos relacional. Existen muchas razones para no incluir un motor de almacenamiento multidimensional separado: • Un motor relacional puede dimensionarse a conjuntos de datos mucho mayores. • Se puede utilizar un modelo de seguridad común para las aplicaciones analíticas y el almacén de datos. • El modelado multidimensional se puede integrar con el modelado del almacén de datos. • El sistema de gestión de bases de datos relacional tiene un conjunto mayor de características y funcionalidades en muchas áreas tales como la alta disponibilidad, las copias de seguridad, la recuperación y el soporte de herramientas de terceros.

www.detodoprogramacion.com


836

Capítulo 27

Oracle

• No hay necesidad de formar administradores de bases de datos para dos motores de bases de datos. El principal reto al evitar un motor de bases de datos multidimensional separado es proporcional el mismo rendimiento. Un sistema de gestión de bases de datos mutidimensional que materializa todo o grandes partes de un cubo de datos puede ofrecer tiempos de respuesta muy cortos para muchos cálculos. Oracle ha enfocado este problema desde varias perspectivas. • Oracle ha agregado soporte SQL para un amplio rango de funciones analíticas, incluyendo cubos, abstracciones, conjuntos de agrupación, clasificaciones (ranks), agregación móvil, funciones led y lag, cajones de histograma, regresión lineal y desviación estándar, junto con la capacidad de optimizar la ejecución de dichas funciones en el motor de la base de datos. • Oracle ha extendido las vistas materializadas para permitir funciones analíticas, en particular los conjuntos de agrupación. La capacidad de materializar partes o todo el cubo es primordial para el rendimiento de un sistema de gestión de bases de datos multidimensionales, y las vistas materializadas proporcionan al sistema de gestión de bases de datos relacionales la capacidad de realizar lo mismo. • Oracle ha introducido los espacios de trabajo analíticos, que almacenan los datos en formatos multidimensionales dentro de una tabla relacional y tienen métodos asociados para las operaciones OLAP como el modelado, asignación, agregación, predicciones y análisis de escenarios. Los espacios de trabajo analíticos se pueden acceder con funciones de tablas en SQL.

27.2.3 Disparadores

Oracle proporciona varios tipos de disparadores y varias opciones para el momento y forma en que se invocan (véase el Apartado 8.6 para una introducción a los disparadores en SQL). Los disparadores se pueden escribir en PL/SQL o Java o como llamadas a C. Para los disparadores que se ejecutan sobre instrucciones LMD tales como insert, update y delete, Oracle soporta disparadores de filas (row) y disparadores de instrucciones (statement). Los disparadores de filas se pueden ejecutar una vez por cada fila que se vea afectada (actualización o borrado, por ejemplo) por la operación LMD. Un disparador de instrucciones se ejecuta solamente una vez por instrucción. En cada caso, el disparador se puede definir tanto como un disparador before o after dependiendo de si se va a invocar antes o después de que se lleva a cabo la operación LMD. Oracle permite la creación de disparadores instead of para las vistas que no pueden estar sujetas a operaciones LMD. Dependiendo de la definición de la vista puede no ser posible para Oracle traducir una instrucción LMD en una vista a modificaciones de las tablas base subyacentes sin ambigüedad. Por ello las operaciones LMD sobre vistas están sujetas a numerosas restricciones. Se puede crear un disparador instead of sobre una vista para especificar manualmente las operaciones sobre las tablas base que van a ocurrir en respuesta a la operación LMD sobre la vista. Oracle ejecuta el disparador en lugar de la operación LMD y por consiguiente proporciona un mecanismo de rodeo de las restricciones sobre las operaciones LMD sobre las vistas. Oracle también tiene disparadores que ejecutan otros eventos, tales como el inicio o finalización de la base de datos, mensajes de error del servidor, inicio o finalización de sesión de un usuario e instrucciones LDD tales como las instrucciones create, alter o drop.

27.3 Almacenamiento e índices

En la jerga de Oracle, una base de datos consiste en información almacenada en archivos y se accede a través de un ejemplar, que es un área de memoria compartida y un conjunto de procesos que interactúa con los datos en los archivos.

www.detodoprogramacion.com


27.3

Almacenamiento e índices

837

27.3.1 Espacios de tablas

Una base de datos consiste en una o más unidades de almacenamiento lógicas denominadas espacios de tablas. Cada espacio de tablas, a su vez, consiste en una o más estructuras físicas denominadas archivos de datos. Éstos pueden ser archivos gestionados por el sistema operativo o dispositivos en bruto. Normalmente una base de datos Oracle tendrá los siguientes espacios de tablas: • El espacio de tablas del sistema, que siempre se crea. Contiene las tablas diccionario de datos y almacenamiento para los disparadores y los procedimientos almacenados. • Espacios de tablas creados para almacenar los datos de usuario. Aunque los datos de usuario se pueden almacenar en el espacio de tablas del sistema es frecuentemente deseable separar los datos de usuario de los datos del sistema. Normalmente la decisión sobre los otros espacios de tablas que se deben crear está basada en el rendimiento, disponibilidad, capacidad de mantenimiento y facilidad de administración. Por ejemplo, puede ser útil tener varios espacios de tablas para las operaciones de copia de seguridad parcial y recuperación. • Los espacios de tablas temporales. Muchas operaciones de base de datos requieren la ordenación de los datos y la rutina de ordenación puede tener que almacenar los datos temporalmente en el disco si la ordenación no se puede realizar en memoria. Se asignan espacios de tablas temporales a la ordenación y asociación para realizar las operaciones de gestión de espacio involucradas en un volcado más eficiente a disco. Los espacios de tablas también se pueden utilizar como un medio para trasladar datos entre las bases de datos. Por ejemplo, es común trasladar los datos desde un sistema transaccional a un almacén de datos a intervalos regulares. Oracle permite trasladar todos los datos en un espacio de tablas de un sistema a otro sencillamente copiando los archivos y exportando e importando una pequeña cantidad de metadatos del diccionario de datos. Estas operaciones pueden ser mucho más rápidas que descargar los datos de una base de datos y después usar un descargador para insertarlos en la otra.

27.3.2 Segmentos

El espacio en un espacio de tablas se divide en unidades, denominadas segmentos, cada una de las cuales contiene datos para una estructura de datos específica. Existen cuatro tipos de segmentos • Segmentos de datos. Cada tabla en un espacio de tablas tiene su propio segmento de datos donde se almacenan los datos de la tabla a menos que la tabla esté dividida; si ocurre esto, hay un segmento de datos por división (la división en Oracle se describe en el Apartado 27.3.10). • Segmentos de índices. Cada índice en un espacio de tablas tiene su propio segmento de índices, excepto los índices divididos, los cuales tienen un segmento de índices por división. • Segmentos temporales. Son segmentos utilizados cuando una operación de ordenación necesita escribir datos al disco o cuando los datos se insertan en una tabla temporal. • Segmentos de retroceso. Estos segmentos contienen información para deshacer de forma que se puede deshacer una copia no terminada. También juegan un papel importante en el modelo de control de concurrencia en Oracle y para la recuperación de la base de datos, descrito en los Apartados 27.5.1 y 27.5.2. Debajo del nivel de segmentos se asigna espacio a un nivel de granularidad, denominado extensión. Cada extensión consiste en un conjunto de bloques contiguos de la base de datos. Un bloque de la base de datos es el nivel más bajo de granularidad en el cual Oracle ejecuta E/S a disco. Un bloque de base de la base de datos no tiene que tener el mismo tamaño que un bloque de un sistema operativo, pero debería ser un múltiplo.

www.detodoprogramacion.com


838

Capítulo 27

Oracle

Oracle proporciona parámetros de almacenamiento que permiten un control detallado de cómo se asigna y gestiona el espacio, tales como: • El tamaño de una extensión nueva que se va a asignar para proporcionar espacio a las filas que se insertan en una tabla. • El porcentaje de utilización de espacio con el cual un bloque de la base de datos se considera lleno y con el cual no se introducirán más filas en ese bloque (dejando algo de espacio libre en un bloque se puede conseguir que las filas existentes aumenten su tamaño cuando se realizan actualizaciones, sin agotar el espacio del bloque). 27.3.3 Tablas

Una tabla estándar en Oracle está organizada en montículo; esto es, la ubicación de almacenamiento de una fila en una tabla no está basada en los valores contenidos en la fila y se fija cuando la fila se inserta. Sin embargo, si la tabla se divide, el contexto de la fila afecta a la partición en la cual está almacenada. Hay varias características y variaciones. Las tablas de montículos se pueden comprimir opcionalmente. Oracle usa un algoritmo de compresión sin pérdidas y basado en diccionario que se aplica individualmente a cada bloque de datos. Para las tablas que contienen grandes cantidades de valores repetidos el ahorro en espacio de disco y, por tanto, de operaciones E/S, puede ser muy grande, pero la compresión y descompresión de datos implica una ligera sobrecarga para la CPU. Oracle soporta las tablas anidadas; esto es, una tabla puede tener una columna cuyo tipo de datos sea otra tabla. La tabla anidada no se almacena en línea en la tabla padre sino que se almacena en una tabla separada. Oracle soporta tablas temporales donde la duración de los datos es la de la transacción en la cual se insertan los datos o la sesión de usuario. Los datos son privados a la sesión y se eliminan automáticamente al final de su duración. Una agrupación es otra forma de organización de los datos de la tabla (véase el Apartado 11.7). El concepto, en este contexto, no se debería confundir con otros significados de la palabra agrupación, tales como los relacionados con la arquitectura de la computadora. En una agrupación las filas de tablas diferentes se almacenan juntas en el mismo bloque según algunas columnas comunes. Por ejemplo, una tabla de departamento y una tabla de empleados se podrían agrupar de forma que cada fila en la tabla departamento se almacene junto con todas las filas de los empleados que trabajan en ese departamento. Los valores de la clave principal o clave externa se utilizan para determinar la ubicación de almacenamiento. Esta organización mejora el rendimiento cuando las dos tablas están combinadas pero sin un aumento de espacio de un esquema desnormalizado puesto que los valores en la tabla de departamento no están repetidos para cada empleado. Como compromiso, una consulta que involucra solamente la tabla departamento puede tener que involucrar un número sustancialmente más grande de bloques que si la tabla se almacenara sola. La organización en agrupación implica que una fila pertenece a un lugar específico; por ejemplo, una nueva fila de empleado se debe insertar con las otras filas para el mismo departamento. Por consiguiente, es obligatorio un índice en la columna de agrupación. Una organización alternativa es una agrupación asociativo. Aquí, Oracle calcula la localización de una fila aplicando una función asociativa al valor para la columna de agrupación. La función asociativa asigna la fila a un bloque específico en la agrupación asociativa. Puesto que no es necesario el recorrido del índice para acceder a una fila según su valor de columna de agrupación, esta organización puede ahorrar cantidades significativas de E/S a disco. Sin embargo, el número de cajones asociativos y otros parámetros de almacenamiento se deben establecer cuidadosamente para evitar problemas de rendimiento debido a demasiadas colisiones o malgasto de espacio debido a cajones asociativos vacíos. La organización según agrupación asociativa y según agrupación normal se puede aplicar a una única tabla El almacenamiento de una tabla como una agrupación asociativa con la columna de la clave principal como la clave de la agrupación puede permitir un acceso basado en un valor de clave principal con un una única E/S a disco, siempre que no haya desbordamiento para ese bloque de datos.

www.detodoprogramacion.com


27.3

Almacenamiento e índices

839

27.3.4 Tablas organizadas con índices

En una tabla organizada con índices los registros se almacenan en un índice de árbol B Oracle en lugar de en un montículo. Una tabla organizada con índices requiere que se identifique una clave única para su uso como la clave del índice. Aunque una entrada en un índice normal contiene el valor de la clave y el identificador de fila de la fila indexada, una tabla organizada con índices reemplaza el identificador de fila con los valores de la columna para el resto de columnas en la tabla. Comparado con el almacenamiento de los datos en una tabla en montículo normal y la creación de un índice según las columnas clave, una tabla organizada con índices puede mejorar el rendimiento y el espacio. Considérese la lectura de todos los valores de columna de una fila, dado su valor de clave principal. Para una tabla en montículo se requeriría un examen del índice seguido por un acceso a tabla mediante identificador de fila. Para una tabla organizada con índices solamente es necesario el examen del índice. Los índices secundarios sobre columnas que no sean clave de una tabla organizada con índices son distintos de los índices en una tabla en montículo normal. En una tabla en montículo cada fila tiene una identificador de fila fija que no cambia. Sin embargo, un árbol B se reorganiza al crecer o disminuir cuando se insertan o borran las entradas, y no hay garantía de que una fila permanezca en una ubicación dentro de una tabla organizada con índices. Por ello, un índice secundario en una tabla organizada con índices no contiene identificadores de fila normales, sino identificadores lógicos de fila. Un identificador lógico de fila consiste en: un identificador de fila física correspondiente a donde la fila estaba cuando se creó el índice o la última reconstrucción, y un valor para la clave única. El identificador de fila física se conoce como una “suposición” puesto que sería incorrecto si la fila se ha trasladado. En este caso la otra parte del identificador lógico de fila, el valor de la clave para la fila se utiliza para acceder a la fila; sin embargo, este acceso es más lento que si la suposición hubiera sido correcta puesto que involucra un recorrido del árbol B para la tabla organizada con índices desde la raíz hasta los nodos hoja, incurriendo potencialmente en varias operaciones E/S de disco. Sin embargo, si una tabla es altamente volátil y es probable que un buen porcentaje de suposiciones sean incorrectas, puede ser mejor crear un índice secundario con solamente valores clave, puesto que el uso de una suposición incorrecta puede producir una E/S a disco malgastada. 27.3.5 Índices

Oracle soporta varios tipos distintos de índices. El tipo más comúnmente utilizado es lo que Oracle (y otros fabricantes) denominan un índice de árbol B (aunque realmente es lo que se denomina en el Capítulo 12 como índice de árbol B+ ) creado en una o varias columnas. Las entradas de los índices tienen el siguiente formato: para un índice en las columnas col1 , col2 y col3 , cada fila en la tabla donde al menos una columna tenga un valor no nulo resultaría en la entrada de índice <col1 ><col2 ><col3 ><id-f ila> donde <coli > denota el valor para la columna i e < id-f ila > es el identificador de fila para la fila. Oracle puede opcionalmente comprimir el prefijo de la entrada para ahorrar espacio. Por ejemplo, si hay muchas combinaciones repetidas de valores <col1 ><col2 >, la representación de cada prefijo <col1 ><col2 > distinto se puede compartir entre las entradas que tienen esa combinación de valores, en lugar de almacenarlo explícitamente para cada entrada. La compresión de prefijos puede llevar a ahorros de espacio sustanciales. 27.3.6 Índices de mapas de bits

Los índices de mapas de bits (descritos en el Apartado 12.9) utilizan una representación de mapa de bits para entradas de índice que pueden llevar a un ahorro sustancial de espacio (y por consiguiente ahorro de E/S a disco), cuando la columna indexada tiene un número moderado de valores distintos. Los índices de mapas de bits en Oracle utilizan la misma clase de estructura de árbol B para almacenar las entradas como un índice normal. Sin embargo, donde un índice normal en una columna tendría entradas de la forma <col1 ><id-f ila>, una entrada de índice de mapa de bits tiene la forma <col1 ><id-f ilainicial><id-f ilaf inal><mapabitscomprimido>

www.detodoprogramacion.com


840

Capítulo 27

Oracle

El mapa de bits conceptualmente representa el espacio de todas las filas posibles en la tabla entre los identificadores de la fila inicial y final. El número de tales filas posibles en un bloque depende de cuántas filas se pueden alojar en un bloque, que es una función del número de columnas en la tabla y sus tipos de datos. Cada bit en el mapa de bits representa una fila posible en un bloque. Si el valor de la columna de esa fila es el de la entrada de índice, el bit se establece a 1. Si la fila tiene algún otro valor o la fila no existe realmente en la tabla, el bit se establece a 0 (es posible que la fila no exista realmente porque un bloque de la tabla puede tener un número más pequeño de filas que el número que se calculó como el máximo posible). Si la diferencia es grande, el resultado pueden ser grandes cadenas de ceros consecutivos en el mapa de bits, pero el algoritmo de compresión trata dichas cadenas de ceros por lo que el efecto negativo se limita. El algoritmo de compresión es una variación de una técnica de compresión denominada compresión de mapas de bits alineados (Byte-Aligned Bitmap Compression, BBC). Esencialmente, una sección del mapa de bits donde la distancia entre dos unos consecutivos es suficientemente pequeña se almacena como mapas de bits como tales. Si la distancia entre dos unos es suficientemente grande—esto es, hay un número suficiente de ceros entre ellos—se almacena el número de ceros. Los índices de mapas de bits permiten varios índices en la misma tabla para combinarse en la misma ruta de acceso si hay varias condiciones sobre las columnas indexadas en la cláusula where de una consulta. Por ejemplo, para la condición (col1 = 1 or col1 = 2) and col2 > 5 and col3 <> 10 Oracle podría calcular las filas que coinciden con la condición ejecutando operaciones booleanas sobre los mapas de bits a partir los mapas de bits de índices sobre las tres columnas. En este caso, estas operaciones se realizarían para cada índice: • Para el índice en col1 , se realizaría la disyunción (or) de los valores de clave 1 y 2. • Para el índice en col2 , todos los mapas de bits para los valores de la clave mayores que 5 se mezclarían en una operación que corresponde a una disyunción. • Para el índice en col3 , se obtendrían los mapas de bits para los valores 10 y null. Entonces, se aplicaría una conjunción sobre los resultados de los dos primeros índices, seguido por dos operaciones menos booleanas de los mapas de bits para los valores 10 y null para col3 . Todas las operaciones se realizan directamente sobre la representación comprimida de los mapas de bits— no es necesaria la descompresión—y el mapa de bits resultante (comprimido) representa las filas que cumplen todas las condiciones lógicas. La capacidad de utilizar las operaciones booleanas para combinar varios índices no está limitada a los índices de mapas de bits. Oracle puede convertir identificadores de filas a la representación de mapa de bits comprimidos, por lo que se puede utilizar un índice de árbol B normal en cualquier lugar de un árbol binario u operación de mapa de bits simplemente poniendo un operador id–fila–a–mapa–de– bits en la parte superior del acceso a índices del plan de ejecución. Como regla nemotécnica, los índices de mapas de bits tienden a ser más eficientes en el espacio que los índices de árbol B si el número de valores distintos de la clave es menor que la mitad del número de filas en una tabla. Por ejemplo, en una tabla con un millón de filas, un índice en una columna con menos de 500.000 valores distintos probablemente sería menor si se creara como un índice de mapa de bits. Para las columnas con un número muy pequeño de valores distintos—por ejemplo, las columnas que se refieren a propiedades tales como país, estado, género, estado marital y varios estados indicadores— un índice mapa de bits podría requerir solamente una pequeña fracción del espacio normal de un índice de árbol B normal. Cualquier ventaja en el espacio también puede dar lugar a mejoras en el rendimiento en la forma de menos operaciones E/S a disco cuando se explora el índice. 27.3.7 Índices basados en funciones

Además de crear índices sobre una o varias columnas de una tabla, Oracle permite crear índices sobre expresiones que involucran a una o más columnas, tales como col1 + col2 ∗ 5. Por ejemplo, la creación

www.detodoprogramacion.com


27.3

Almacenamiento e índices

841

de un índice sobre la expresión upper (nombre), donde upper es una función que devuelve la versión en mayúsculas de una cadena y nombre es una columna, es posible realizar búsquedas independientes de la caja (mayúsculas o minúsculas) sobre la columna nombre. Con el fin de buscar todas las filas con el nombre “van Gogh” de una forma eficiente se puede utilizar la condición upper(nombre) = ’VAN GOGH’ en la cláusula where de la consulta. Oracle entonces casa la condición con la definición de índice y concluye que se puede utilizar el índice para recuperar todas las filas que coincidan con “van Gogh” sin considerar las mayúsculas y minúsculas del nombre cuando se almacenó en la base de datos. Se puede crear un índice basado en función como un mapa de bits o como un índice de árbol B. 27.3.8 Índices de reunión

Un índice de reunión es un índice donde las columnas clave no están en la tabla que se referencia mediante los identificadores de filas en el índice. Oracle soporta los índices de reunión mapa de bits principalmente para su uso con esquemas en estrella (véase el Apartado 18.3.2). Por ejemplo, si hay una columna para los nombres de los productos en una tabla de la dimensión productos, se podría utilizar un índice de reunión de mapas de bits sobre la tabla de hechos con esta columna clave para recuperar las filas de la tabla de hechos que corresponden a un producto con un nombre específico, aunque el nombre no esté almacenado en la tabla de hechos. La forma en la que las filas en las tablas de hechos y de la dimensión correspondientes está basada en una condición de reunión que se especifica cuando se crea el índice y se convierte en parte de los los metadatos de índices. Cuando se procesa una consulta, el optimizador buscará la misma condición de reunión en la cláusula where de la consulta con el fin de determinar si es aplicable el índice de reunión. Oracle permite índices de reunión de mapa de bits para tener más de una columna clave y estas columnas pueden estar en tablas diferentes. En todos los casos las condiciones de reunión entre la tabla de hechos donde se construye el índice y las tablas dimensionales se deben referir a claves únicas en las tablas dimensionales; esto es, una fila indexada en la tabla de hechos debe corresponder a una única fila en cada una de las tablas de dimensión. Oracle puede combinar un índice de reunión de mapa de bits en una tabla de hechos con otros índices en la misma tabla — tanto si hay índices de reunión o no—mediante el uso de operadores para las operaciones booleanas del mapa de bits. Por ejemplo, consideremos un esquema con una tabla de hechos para las ventas y tablas dimensionales para los clientes, productos y fechas. Supóngase que una consulta solicita información sobre las ventas a los clientes en un cierto código postal que compraron productos de una cierta categoría de producto durante un cierto periodo de tiempo. Si existe un índice de reunión de mapa de bits sobre varias columnas donde las columnas clave son las columnas de la tabla de dimensión restringidas (código postal, categoría de producto y fecha), Oracle puede utilizar el índice de reunión para buscar las filas en la tabla de hechos que coinciden con las condiciones de restricción. Sin embargo, si existen índices individuales sobre una única columna para las columnas clave (o un subconjunto de ellas), Oracle puede recuperar los mapas de bits de las filas de la tabla de hechos que coinciden con cada condición individual y utilizar la operación and booleana para generar un mapa de bits de la tabla de hechos para aquellas filas que satisfacen todas las condiciones. Si la consulta contiene condiciones sobre algunas columnas de la tabla de hechos, los índices de aquellas columnas se podrían incluir en la misma ruta de acceso, incluso si fueran índices normales de árbol B o índices de dominio (los índices de dominio se describen posteriormente en el Apartado 27.3.9). 27.3.9 Índices de dominio

Oracle permite que las tablas sean indexadas por estructuras de índices que no sean propias de Oracle. Esta característica de extensibilidad del servidor Oracle permite a los fabricantes de software desarrollar los llamados cartuchos con funcionalidad para dominios de aplicación específicos, tales como texto, datos espaciales e imágenes, con la funcionalidad de indexado más allá de la proporcionada por los tipos de índice Oracle estándar. Para implementar la lógica para crear, mantener y buscar en el índice,

www.detodoprogramacion.com


842

Capítulo 27

Oracle

el diseñador de índices debe asegurar que se adhiere a un protocolo específico en su interacción con el servidor Oracle. Un índice de dominio se debe registrar en el diccionario de datos junto con los operadores que soporta. El optimizador de Oracle considera los índices de dominio como una de las posibles rutas de acceso para una tabla. Oracle permite a las funciones de coste registrarse con los operadores de forma que el optimizador pueda comparar el coste del uso del índice de dominio con los de otras rutas de acceso. Por ejemplo, un índice de dominio para búsquedas de texto avanzadas puede soportar un operador contains (contiene). Una vez que se ha registrado este operador, el índice de dominio se considerará como una ruta de acceso para una consulta como select * from empleado where contains(resumen, ’LINUX’) donde resumen es una columna de texto en la tabla empleados. El índice de dominio se puede almacenar en un archivo de datos externo o dentro de una tabla Oracle organizada con índices. Los índices de dominio se pueden combinar con otros índices (mapa de bits o de árbol B) en la misma ruta de acceso con la conversión entre la representación de mapa de bits y el identificador de fila y usando operaciones booleanas del mapa de bits. 27.3.10 División en particiones

Oracle soporta varias clases de división horizontal de tablas e índices. Su función principal es dar soporte a bases de datos muy grandes. Esta capacidad de dividir una tabla o índice resulta de interés en muchas aplicaciones. • La copia de seguridad y recuperación es más sencilla y rápida puesto que se puede realizar sobre particiones individuales en lugar de sobre toda la tabla. • Las operaciones de carga en un entorno de almacén de datos son menos intrusivas: se pueden agregar datos a una partición y después agregar la partición a una tabla, lo que es una operación instantánea. De igual forma, eliminar una partición con datos obsoletos desde una tabla es muy sencillo en un almacén de datos que mantenga una ventana de datos históricos. • El rendimiento de la consulta se mejora sustancialmente puesto que el optimizador puede reconocer que solamente se tiene que acceder a un subconjunto de las particiones de una tabla con el fin de resolver la consulta (poda de particiones). También el optimizador puede reconocer que en una reunión no es necesario intentar hacer corresponder todas las filas en una tabla con todas las filas en la otra, pero que las reuniones se necesitan realizar solamente entre pares coincidentes de divisiones (reunión por particiones). Cada fila en una tabla dividida está asociada con una partición específica. Esta asociación está basada en la columna o columnas de la división que son parte de la definición de una tabla dividida. Hay varias formas para hacer corresponder valores de columna a divisiones, dando lugar a varios tipos de divisiones, cada una con distintas características: divisiones por rangos, asociativas, por listas y compuestas. 27.3.10.1 División por rangos

En la división por rangos los criterios de división son rangos de valores. Este tipo de división está especialmente indicado para columnas de fechas, en cuyo caso todas las filas en el mismo rango de fechas, digamos un día o un mes, pertenecen a la misma partición. En un almacén de datos donde los datos se cargan desde sistemas transaccionales a intervalos regulares, la división por rangos se puede utilizar para implementar eficientemente una ventana de datos históricos. Cada carga de datos obtiene su nueva partición propia, haciendo que el proceso de carga sea más rápido y eficiente. El sistema realmente carga los datos en una tabla separada con la misma definición de columna que en una tabla dividida. Se puede entonces verificar la consistencia de los datos, arreglarlos e indexarlos. Después de eso el sistema

www.detodoprogramacion.com


27.3

Almacenamiento e índices

843

puede hacer de la tabla separada una nueva partición mediante un sencillo cambio de los metadatos en el diccionario de datos — una operación casi instantánea. Mientras no cambien los metadatos, el proceso de carga no afecta a los datos existentes en la tabla dividida en ningún caso. No hay necesidad de realizar ningún mantenimiento de los índices existentes como parte de la carga. Los datos antiguos se pueden eliminar de un tabla sencillamente eliminando su partición; esta operación no afecta al resto de particiones. Además, las consultas en un entorno de almacén de datos frecuentemente contienen condiciones que los restringen a un cierto periodo de tiempo, tal como una quincena o mes. Si se utiliza la división de datos por rangos el optimizador de consulta puede restringir el acceso a los datos de aquellas particiones que son relevantes a la consulta y evitar una exploración de toda la tabla. 27.3.10.2 División asociativa

En la división asociativa, una función asociativa hace corresponder filas con divisiones según los valores en las columnas de la división. Este tipo de división es útil principalmente cuando es importante distribuir las filas equitativamente entre las particiones o cuando las reuniones por particiones son importantes para el rendimiento de la consulta. 27.3.10.3 División compuesta

En la división compuesta la tabla se divide por rangos, pero cada partición tiene subparticiones mediante el uso de la división asociativa o por listas. Este tipo de división combina las ventajas de la división por rangos y la división asociativa o por listas. 27.3.10.4 División por listas

En la división por listas los valores asociados con una partición particular están en una lista. Este tipo de división es útil si los datos en la columna de división tienen un conjunto relativamente pequeño de valores discretos. Por ejemplo, una tabla con una columna para la provincia se puede partir implícitamente por región geográfica si cada lista de particiones tiene las provincias que pertenecen a la misma región. 27.3.11 Vistas materializadas

La característica de la vista materializada (véase el Apartado 3.9.1) permite almacenar el resultado de una consulta SQL y utilizarlo en un procesamiento posterior. Además, Oracle mantiene el resultado materializado, actualizándolo cuando se actualizan las tablas a las que se hicieron referencia en la consulta. Las vistas materializadas se utilizan en el almacén de datos para acelerar el procesamiento de la consulta, pero esta tecnología también se utiliza para la réplica en entornos distribuidos y móviles. En el almacén de datos, un uso común de vistas materializadas es resumir los datos. Por ejemplo, un tipo común de consulta solicita “la suma de las ventas de cada cuatrimestre durante los últimos dos años”. El precálculo de los resultados, o algún resultado parcial, de dicha consulta puede acelerar drásticamente el procesamiento de la consulta comparado con calcularlo desde cero con la agregación de todos los registros de ventas por detalle. Oracle soporta reescrituras automáticas de las consultas que aprovechan cualquier vista materializada útil cuando se resuelve una consulta. La reescritura consiste en cambiar la consulta para utilizar la vista materializada en lugar de las tablas originales en la consulta. Además, la reescritura puede agregar reuniones adicionales o procesamiento de agregación si son necesarias para obtener el resultado correcto. Por ejemplo, si una consulta necesita las ventas por cuatrimestre, la reescritura puede aprovechar una vista que materializa las ventas por mes, añadiendo agregación adicional para agrupar los meses en cuatrimestres. Oracle tiene un tipo de objeto de metadatos denominado dimension que permite las relaciones jerárquicas en las tablas a definir. Por ejemplo, una tabla de la dimensión temporal en un esquema en estrella Oracle puede definir un objeto de metadatos dimension para especificar cómo se

www.detodoprogramacion.com


844

Capítulo 27

Oracle

agrupan los días en meses, los meses en cuatrimestres, los cuatrimestres en años, y así sucesivamente. De igual forma se pueden especificar las propiedades jerárquicas relacionadas con la geografía—por ejemplo, cómo los distritos de ventas se agrupan en regiones. La lógica de la reescritura de la consulta examina estas relaciones puesto que permite utilizar una vista materializada para clases más amplias de consultas. El objeto contenedor para una vista materializada es una tabla, lo que significa que una vista materializada se puede indexar, dividir o estar sujeta a otros controles para mejorar el rendimiento de la consulta. Cuando hay cambios en los datos de las tablas referenciadas en la consulta que define una vista materializada se debe actualizar la vista materializada para reflejar dichos cambios. Oracle soporta tanto la actualización completa de una vista materializada como una actualización rápida incremental. En una actualización completa Oracle vuelve a calcular la vista materializada desde cero, lo cual puede ser la mejor opción si las tablas subyacentes han tenido cambios significativos, por ejemplo, debidos a una carga masiva. En una actualización incremental Oracle actualiza la vista utilizando registros que fueron cambiados en las tablas subyacentes; la actualización de la vista es inmediata—esto es, se ejecuta como parte de la transacción que cambió las tablas subyacentes. La actualización incremental puede ser mejor si el número de filas que se han cambiado es pequeño. Hay algunas restricciones sobre las clases de consultas según las que una vista materializada se puede actualizar de forma incremental (y otras que indican si una vista materializada siquiera se puede crear). Una vista materializada es similar a un índice en el sentido que, aunque puede mejorar el rendimiento de la consulta, usa espacio, y su creación y mantenimiento consume recursos. Para ayudar a resolver este compromiso Oracle proporciona un asesor que puede ayudar al usuario a crear vistas materializadas menos costosas, dada una carga de trabajo particular como entrada.

27.4 Procesamiento y optimización de consultas

Oracle soporta una gran variedad de técnicas de procesamiento en su motor de procesamiento de consultas. Algunas de las más importantes se describen aquí brevemente. 27.4.1 Métodos de ejecución

Se puede acceder a los datos mediante una serie de métodos de acceso: • Exploración de tabla completa. El procesador de consultas explora toda la tabla, obtiene información sobre los bloques que forman la tabla del mapa de extensión y explora estos bloques. • Exploración de índices. El procesador crea una clave de comienzo y/o finalización a partir de las condiciones en la consulta y la utiliza para explorar una parte relevante del índice. Si hay columnas que se tienen que recuperar, y que no son parte del índice, la exploración del índice irá seguida de un acceso a la tabla mediante el índice del identificador de fila. Si no hay disponible ninguna clave de inicio o parada la exploración será una exploración de índice completa. • Exploración rápida completa de índices. El procesador explora las extensiones de la misma forma que la extensión de tabla en una exploración de tabla completa. Si el índice contiene todas las columnas de la tabla que se necesitan en ella y no hay buenas claves de inicio y parada que puedan reducir significativamente esa porción del índice que se exploraría en una exploración de índices normal, este método puede ser la forma más rápida de acceder a los datos. Esto es porque la exploración rápida completa aprovecha de forma completa la E/S de disco de varios bloques. Sin embargo, a diferencia de una exploración completa normal, que recorre los bloques hoja del índice en orden, una exploración rápida completa no garantiza que la salida preserve el orden del índice. • Reunión de índices. Si una consulta necesita solamente un pequeño subconjunto de columnas de una tabla ancha, pero ningún índice contiene todas estas columnas, el procesador puede utilizar una reunión de índices para generar la información relevante sin acceder a la tabla, reuniendo

www.detodoprogramacion.com


27.4

Procesamiento y optimización de consultas

845

varios índices que contienen en conjunto las columnas necesarias. Ejecuta las reuniones como reunión por asociación sobre los identificadores de filas desde los distintos índices. • Acceso a agrupaciones y agrupaciones asociadas. El procesador accede a los datos utilizando la clave de agrupación. Oracle tiene diversas formas de combinar información desde varios índices en una única ruta de acceso. Esta posibilidad permite varias condiciones en la cláusula where que se pueden utilizar conjuntamente para calcular el conjunto de resultados de la forma más eficientemente posible. La funcionalidad incluye la capacidad de ejecutar las operaciones booleanas conjunción, disyunción y diferencia sobre mapas de bits que representan los identificadores de filas. Hay también operadores que hacen corresponder una lista de identificadores de filas con mapas de bits y viceversa, lo que permite que los índices de árbol B normales y los índices de mapas de bits utilicen la misma ruta de acceso. Además, para muchas consultas que involucran count(*) en selecciones sobre una tabla el resultado se puede calcular simplemente contando los bits activados en el mapa de bits generado mediante la aplicación de las condiciones de la cláusula where sin acceder a la tabla. Oracle soporta varios tipos de reuniones en el motor de ejecución: reuniones internas, externas, semirreuniones y antirreuniones (una antirreunión en Oracle devuelve las filas de la parte izquierda de la entrada que no coinciden con ninguna fila en la parte derecha de la entrada; esta operación se denomina antisemirreunión en otros libros). Evalúa cada tipo de reunión mediante uno de los tres métodos: reunión por asociación, reunión por mezcla–ordenación o reunión en bucle anidado.

27.4.2 Optimización

En el Capítulo 14 se ha estudiado el tema general de la optimización de la consulta. Aquí se trata la optimización en el contexto de Oracle. 27.4.2.1 Transformaciones de consultas

Oracle realiza la optimización de consultas en diferentes pasos. Uno es realizar varias transformaciones y reescrituras que fundamentalmente cambian la estructura de la consulta. Otro paso es realizar la selección de la ruta de acceso para determinar las rutas y los métodos y el orden de reunión. Dado que no todas las técnicas de transformación de consultas tienen garantizado su beneficio, Oracle realiza transformaciones basadas en el coste en las que éstas y la selección de camino se entrelazan. Para cada transformación generada se realiza una selección de la ruta de acceso y se genera una estimación del coste, aceptándola o rechazándola dependiendo del coste del plan de ejecución resultante. Algunos de los tipos principales de transformaciones y reescrituras soportados por Oracle son los siguientes: • Mezcla de vistas. La referencia de la vista en una consulta es reemplazada por la definición de la vista. Esta transformación no es aplicable a todas las vistas. • Mezcla compleja de vistas. Oracle ofrece esta característica para ciertas clases de vistas que no están sujetas a la mezcla normal de vistas puesto que tienen un group by o select distinct en la definición de la vista. Si dicha vista se combina con otras tablas, Oracle puede conmutar las reuniones y las operaciones de ordenación y asociación utilizada por group by o distinct. • Subconsultas planas. Oracle tiene una serie de transformaciones que convierten varias clases de subconsultas en reuniones, semirreuniones o antirreuniones. • Reescritura de vistas materializadas. Oracle tiene la capacidad de reescribir una consulta automáticamente para aprovechar las vistas materializadas. Si alguna parte de la consulta se puede casar con una vista materializada existente, Oracle puede remplazar esta parte de la consulta con una referencia a la tabla en la cual la vista está materializada. Si es necesario, Oracle agrega condiciones de reunión u operaciones group by para preservar la semántica de la consulta. Si son aplicables varias vistas materializadas, Oracle recoge la que reduce la mayor cantidad de datos

www.detodoprogramacion.com


846

Capítulo 27

Oracle

que se tienen que procesar. Además, Oracle somete la consulta reescrita y la versión original al proceso completo de optimización produciendo un plan de ejecución y un coste asociado estimado para cada una. Oracle entonces decide si ejecutar la versión original o la reescrita de la consulta según la estimación del coste. • Transformación en estrella. Oracle posee una técnica especial para evaluar las consultas en esquemas en estrella, conocidas como transformación en estrella. Cuando una consulta contiene una reunión de una tabla de hechos con tablas dimensionales y selecciones sobre los atributos de las tablas dimensionales, la consulta se transforma borrando la condición de la reunión entre la tabla de hechos y las tablas dimensionales y remplazando la condición de selección en cada tabla dimensional por una subconsulta del formulario: tabla_de_hechosi in (select cp from tabla_dimensionali where <condiciones sobre tabla_dimensionali >) Se genera dicha subconsulta para cada tabla dimensional que tiene algún predicado restrictivo. Si la dimensión tiene un esquema en copo de nieve (véase el Apartado 18.3) la subconsulta contendrá una reunión de las tablas aplicables que forman la dimensión. Oracle utiliza los valores que son devueltos desde cada subconsulta para probar un índice sobre la columna de la tabla de hechos correspondiente, obteniendo un mapa de bits como resultado. Los mapas de bits generados desde distintas subconsultas se combinan con una operación and de mapas de bits. El mapa de bits resultante se puede utilizar para acceder a las filas de las tablas de hechos coincidentes. Por ello, solamente se accederá a las filas en la tabla de hechos que coinciden simultáneamente en las condiciones de las dimensiones restringidas. Tanto la decisión de si el uso de una subconsulta para una dimensión particular es ventajoso y la decisión de si la consulta reescrita es mejor que la original están basadas en la estimación de coste del optimizador.

27.4.2.2 Selección de la ruta de acceso

Oracle tiene un optimizador basado en el coste que determina el orden de la reunión, métodos de reunión y rutas de acceso. Cada operación que el optimizador considera tiene una función de coste asociada y el optimizador intenta generar la combinación de operaciones que tiene el coste global menor. Para estimar el coste de una operación, el optimizador considera las estadísticas que se han calculado para los objetos del esquema tales como tablas e índices. La estadística contiene información sobre el tamaño del objeto, la cardinalidad, la distribución de datos de las columnas de la tabla y cosas similares. Para la estadística de columnas, Oracle soporta histogramas equilibrados en altura e histogramas de frecuencia. Para facilitar la recogida de las estadísticas del optimizador, Oracle puede supervisar la actividad de la modificación sobre tablas y sigue la pista de aquellas tablas que han sido objeto de suficientes cambios como para que pueda ser apropiado un nuevo cálculo de las estadísticas. Oracle también sigue las columnas que se utilizan en las cláusulas where de las consultas, lo que hace que sean candidatas potenciales para la creación del histograma. Con un solo comando es posible que Oracle actualice las estadísticas de las tablas que se han modificado sustancialmente. Oracle utiliza un muestreo para acelerar el proceso de recoger la nueva estadística y elige de forma automática el menor porcentaje de la muestra que sea adecuado. También determina si la distribución de las columnas marcadas merece la creación de histogramas; si la distribución está cerca de ser uniforme Oracle utiliza una representación más sencilla de la estadística de columnas. En algunos casos puede ser imposible que el optimizador estime de forma precisa la selectividad de una condición en la cláusula where de una consulta simplemente a partir de las estadísticas almacenadas. Por ejemplo, la condición puede ser una expresión sobre una sola columna, como f (col + 3) > 5. Otro caso de consulta problemática es cuando se tienen varios predicados sobre columnas correlacionadas de alguna forma. Puede ser difícil determinar la selectividad combinada de estos predicados. Oracle trata estos problemas con el muestreo dinámico. El optimizador puede muestrear aleatoriamente

www.detodoprogramacion.com


27.4

Procesamiento y optimización de consultas

847

una pequeña parte de la tabla y aplicar todos los predicados relevantes a la muestra para determinar el porcentaje de filas que los cumplen. Oracle utiliza el coste de CPU y E/S en disco en el modelo de coste en el optimizador. Para equilibrar los dos componentes almacena las medidas sobre la velocidad de CPU y rendimiento de E/S de disco como parte de la estadística del optimizador. El paquete de Oracle para recoger la estadística del optimizador calcula estas medidas. Para consultas que involucran un número no trivial de reuniones, el espacio de búsqueda es un tema para el optimizador de consultas. Oracle soluciona este tema de varias formas. El optimizador genera un orden inicial de la reunión y después decide sobre los mejores métodos de la reunión y rutas de acceso para ese orden de la reunión. A continuación cambia el orden de las tablas y determina los mejores métodos de reunión y rutas de acceso para el nuevo orden y así sucesivamente, guardando el mejor plan que se ha encontrado hasta entonces. Oracle mantiene pequeña la optimización si el número de los distintos órdenes de la reunión que se han considerado es tan grande que el tiempo gastado en el optimizador puede ser grande comparado con el que se gastaría para ejecutar el mejor plan encontrado hasta entonces. Puesto que este corte depende del coste estimado para el mejor plan encontrado hasta entonces, es importante hallar pronto un buen plan de forma que el optimizador se pueda parar después de un pequeño número de órdenes de la reunión, resultando un mejor tiempo de respuesta. Oracle utiliza varias heurísticas para el orden inicial y aumentar la probabilidad de que el primer orden de reunión se considere bueno. Por cada orden de reunión que se considera, el optimizador puede hacer pasadas adicionales por las tablas para decidir los métodos de reunión y las rutas de acceso. Tales pasadas adicionales capturarían efectos globales colaterales específicos sobre la selección de la ruta de acceso. Por ejemplo, una combinación específica de métodos de reunión y rutas de acceso pueden eliminar la necesidad de ejecutar una ordenación order by. Puesto que tal efecto lateral global puede no ser obvio cuando se consideran localmente los costes de los distintos métodos de reunión y de rutas de acceso, se utiliza una pasada separada que capture un efecto colateral específico para encontrar un posible plan de ejecución con un mejor coste conjunto. 27.4.3 SQL Tuning Advisor

Además del proceso normal de optimización, el optimizador de Oracle se puede usar en modo de ajuste como parte del asesor de ajuste de SQL (SQL Tuning Advisor) para generar planes de ejecución más eficientes de los que normalmente se generarían. Oracle supervisa la actividad de la base de datos y almacena automáticamente información sobre instrucciones SQL de gran coste en un repositorio de carga de trabajo. Estas instrucciones son las que usan más recursos porque se ejecutan gran número de veces o porque son inherentemente costosas. El asesor se puede usar para mejorar el rendimiento de estas instrucciones sugiriendo recomendaciones que se catalogan en: • Análisis estadístico. Oracle comprueba si están disponibles y actualizadas las estadísticas necesarias para el optimizador y proporciona recomendaciones para recopilarlas. • Perfiles de SQL. El perfil de una instrucción SQL es un conjunto de informaciones para ayudar al optimizador para que realice mejores decisiones la próxima vez que se optimice la instrucción. El optimizador puede generar a veces planes de ejecución ineficientes si no es capaz de estimar de forma precisa las cardinalidades y las selectividades, lo cual puede ocurrir como resultado de una correlación de datos o del uso de ciertos tipos de constructores. Al ejecutar el optimizador en modo de ajuste para generar un perfil, el optimizador intenta comprobar que sus suposiciones son correctas con el muestreo dinámico y la evaluación parcial de la instrucción SQL. Si encuentra pasos en el proceso de optimización en los que las suposiciones son incorrectas, genera un factor de corrección para cada paso que será parte del perfil. La optimización en el modo de ajuste puede consumir mucho tiempo, pero puede ser útil si el perfil mejora significativamente el rendimiento de la instrucción. Si se crea un perfil se almacena de forma persistente y se usa cada vez que se optimice la instrucción. Las perfiles se pueden usar para ajustar las instrucciones SQL sin cambiar su forma textual, lo cual es importante porque a menudo es imposible que el administrador de bases de datos modifique las instrucciones generadas por las aplicaciones.

www.detodoprogramacion.com


848

Capítulo 27

Oracle

• Análisis de la ruta de acceso. Oracle sugiere la creación de índices adicionales que podrían acelerar la ejecución de la instrucción usando el análisis del optimizador. • Análisis de la estructura SQL. Oracle sugiere cambios en la estructura de las instrucciones SQL que permitirían una ejecución más eficiente. Para tablas divididas el optimizador intenta ajustar las condiciones en la cláusula where de una consulta con el criterio de división de la tabla con el fin de evitar acceder a particiones que no son necesarias para el resultado. Por ejemplo, si una tabla se divide por el rango de fechas y la consulta se restringe a datos entre dos fechas específicas, el optimizador determina las particiones que contienen los datos entre las fechas específicas y asegura que solamente se accede a dichas particiones. Este escenario es muy común y la aceleración puede ser dramática si solamente es necesario un pequeño subconjunto de particiones.

27.4.4 Ejecución en paralelo

Oracle permite ejecutar en paralelo una única instrucción SQL mediante la división del trabajo entre varios procesos en una computadora multiprocesadora. Esta característica es especialmente útil para operaciones intensivas en cómputo que de otra forma se ejecutarían en un tiempo inaceptablemente largo. Ejemplos representativos son las consultas de apoyo para la toma de decisiones que necesitan procesar grandes cantidades de datos, cargas de datos en un almacén de datos y creación o reconstrucción de índices. Con el fin de lograr una buena aceleración mediante el paralelismo es importante que el trabajo involucrado en la ejecución de la instrucción se divida en gránulos que se pueden procesar de forma independiente mediante los distintos procesadores en paralelo. Dependiendo del tipo de operación Oracle tiene diversas formas de dividir el trabajo. Para operaciones que acceden a objetos base (tablas e índices) Oracle puede dividir el trabajo mediante segmentos horizontales de datos. Para algunas operaciones, tales como una exploración completa de una tabla, cada uno de dichos segmentos puede ser un rango de bloques—cada proceso de consulta en paralelo explora la tabla desde el bloque al comienzo del rango hasta el bloque al final. Para otras operaciones en una tabla dividida, como la actualización y borrado, el segmento podría ser una partición. Para inserciones en una tabla no dividida, los datos a insertar se dividen de forma aleatoria entre los procesos en paralelo. Las reuniones se pueden realizar en paralelo de distintas formas. Una forma es dividir una de las entradas a la reunión entre procesos paralelos y permitir que cada proceso reúna su segmento con la otra entrada de la reunión; éste es el método de reunión con fragmentos y réplicas del Apartado 21.5.2.2. Por ejemplo, si una tabla grande se reúne con una pequeña mediante una reunión por asociación, Oracle divide la tabla grande entre los procesos y envía una copia de la tabla pequeña a cada proceso, la cual a su vez reúne su segmento con la tabla menor. Si ambas tablas son grandes sería prohibitivamente costoso enviar una de ellas a todos los procesos. En ese caso Oracle logra el paralelismo mediante la división de los datos entre los procesos con la asociación de los valores de las columnas de la reunión (el método de reunión por asociación dividida del Apartado 21.5.2.1). Cada tabla se explora en paralelo mediante un conjunto de procesos y cada fila en la salida se pasa a un proceso de un conjunto de procesos que van a ejecutar la reunión. El proceso que obtiene la fila se determina mediante una función de asociación sobre los valores de la columna de reunión. Por ello, cada proceso de reunión obtiene solamente las filas que podrían potencialmente coincidir y las filas correspondientes que no podrían ir a parar a procesos diferentes. Oracle organiza en paralelo las operaciones de ordenación mediante los rangos de valores de la columna en la cual se ejecuta la ordenación (esto es, usando la ordenación de división por rangos del Apartado 21.5.1). A cada proceso que participa en la ordenación se le envían filas con los valores en este rango y ordena las filas en su rango. Para maximizar las ventajas del paralelismo las filas se tienen que dividir lo más equitativamente posible entre los procesos en paralelo, pero entonces surge el problema de determinar las fronteras de rango que generan una buena distribución. Oracle soluciona el problema

www.detodoprogramacion.com


27.5

Control de concurrencia y recuperación

849

mediante un muestreo dinámico de un subconjunto de las filas en la entrada a la ordenación antes de decidir las fronteras del rango. Los procesos involucrados en la ejecución en paralelo de una instrucción SQL consiste en un proceso coordinador y una serie de procesos servidores en paralelo. El coordinador es responsable de asignar trabajos a los servidores en paralelo y de recoger y devolver los datos a los procesos del usuario que enviaron la instrucción. El grado de paralelismo es el número de procesos servidores en paralelo que se asignan para ejecutar una operación primitiva como parte de la instrucción. El grado de paralelismo se determina mediante el optimizador, pero se puede reducir dinámicamente si la carga en el sistema aumenta. Los servidores en paralelo operan sobre un modelo productor/consumidor. Cuando es necesario una secuencia de operaciones para procesar una instrucción, el conjunto productor de servidores ejecuta la primera operación y pasa los datos resultantes al conjunto de consumidores. Por ejemplo, si una exploración de tabla completa es seguida por una ordenación y el grado de paralelismo es 12 habría 12 servidores productores que ejecutan la exploración de la tabla y pasan el resultado a 12 servidores consumidores que ejecutan la ordenación. Si es necesaria una operación posterior, como otra ordenación, las funciones de los dos conjuntos de servidores se cambian. Los servidores que originalmente ejecutaban la exploración de la tabla adoptan la función de consumidores de la salida producida por la primera ordenación y la utilizan para ejecutar la segunda ordenación. Por ello se realiza una secuencia de operaciones pasando los datos entre dos conjuntos de servidores que alternan sus funciones como productores y consumidores. Los servidores se comunican entre sí mediante las memorias intermedias sobre hardware de memoria compartida y mediante las conexiones de red de alta velocidad sobre configuraciones MPP (sin compartimiento) y sistemas agrupados (discos compartidos). Para sistemas sin compartimiento el coste para acceder a los datos en el disco no es uniforme entre los procesos. Un proceso que se ejecuta en un nodo que tiene acceso directo a un dispositivo puede procesar los datos sobre ese dispositivo más rápidamente que un proceso que tiene que recuperar los datos a través de la red. Oracle utiliza el conocimiento sobre la afinidad dispositivo a nodo y dispositivo a proceso— esto es, la capacidad de acceder a los dispositivos directamente—cuando distribuye el trabajo entre servidores en ejecución paralela. 27.5 Control de concurrencia y recuperación

Oracle soporta técnicas de control de concurrencia y recuperación que proporcionan una serie de características útiles 27.5.1 Control de concurrencia

El control de concurrencia multiversión de Oracle difiere de los mecanismos de concurrencia utilizados por la mayoría de los fabricantes de bases de datos. Para las consultas de sólo lectura se proporcionan instantáneas consistentes en lectura, que son vistas de la base de datos tal como existía en un cierto momento, y que contienen todas las actualizaciones que se comprometieron hasta ese momento y no el resto. Por ello, no se utilizan los bloqueos de lectura y las consultas de sólo lectura no interfieren con otra actividad de la base de datos en términos de bloqueos (esto es básicamente el protocolo de bloqueo multiversión en dos fases descrito en el Apartado 16.5.2). Oracle soporta la consistencia de lectura en un nivel de instrucción y de transacción. Al comienzo de la ejecución de una instrucción o transacción (dependiendo del nivel de consistencia que se utilice) Oracle determina el número de cambio del sistema (System Change Number, SCN) actual. El SCN esencialmente actúa como una marca temporal donde el tiempo se mide en términos de compromisos de la base de datos, en lugar del tiempo de reloj. Si en el transcurso de una consulta se determina que un bloque de datos tiene un SCN mayor que el que se está asociando a la consulta, es evidente que se ha modificado el bloque de datos después del SCN de la consulta original mediante alguna otra transacción y puede o no haberse comprometido. Por ello, los datos en el bloque no se pueden incluir en una vista consistente de la base de datos como existía a la hora del SCN de la consulta. En su lugar, se debe utilizar una versión anterior de los datos en el bloque— en concreto el que tenga el SCN mayor que no exceda el SCN de la consulta. Oracle recupera

www.detodoprogramacion.com


850

Capítulo 27

Oracle

la versión de los datos desde el segmento de retroceso (los segmentos de retroceso se describen en el Apartado 27.5.2). Por esta razón, supuesto que el segmento de retroceso es lo suficientemente grande, Oracle puede devolver un resultado consistente de la consulta incluso si los datos se han modificado varias veces desde que comenzara la ejecución de la consulta. Si el bloque con el SCN deseado ya no existe en el segmento de retroceso, la consulta devolverá un error. Habría una indicación de que el segmento de retroceso no se ha dimensionado adecuadamente, dada la actividad del sistema. En el modelo de concurrencia de Oracle las operaciones de lectura no bloquean las operaciones de escritura y las operaciones de escritura no bloquean las operaciones de lectura, una propiedad que permite un alto grado de concurrencia. En concreto, el esquema permite consultas largas (por ejemplo, consultas de informes) para ejecutar en un sistema con una gran cantidad de actividad transaccional. Esta clase de escenario es normalmente problemático para sistemas de bases de datos donde las consultas utilizan bloqueos de lectura puesto que la consulta puede fallar al adquirirlos o bloquear grandes cantidades de datos por mucho tiempo evitando, por consiguiente, la actividad transaccional de los datos y reduciendo la concurrencia (una alternativa que se emplea en algunos sistemas es utilizar un grado inferior de consistencia, tal como la consistencia en grado dos, pero eso podría producir resultados inconsistentes en la consulta). El modelo de concurrencia de Oracle se utiliza como base para las características Flashback. Estas características permiten a los usuarios establecer un cierto número SCN o tiempo de reloj en su sesión y ejecutar operaciones sobre los datos que existían en esa fecha (supuesto que los datos todavía existían en el segmento de retroceso). Normalmente, en un sistema de bases de datos, una vez que se ha realizado el cambio no hay forma de retroceder al estado anterior de los datos a menos que se realicen restauraciones desde copias de seguridad. Sin embargo, la recuperación de una base de datos muy grande puede ser muy costosa, especialmente si el objetivo es solamente recuperar algunos datos que ha sido borrados inadvertidamente por un usuario. Las características de Flashback proporcionan un mecanismo mucho más sencillo para tratar los errores del usuario. Entre ellas se encuentra la posibilidad de restaurar una tabla o una base de datos completa a un momento pasado sin recuperar de copias de seguridad, la posibilidad de realizar consultas sobre los datos que existieron en algún momento anterior, la posibilidad de realizar un seguimiento del cambio de una o más filas a lo largo del tiempo, y la posibilidad de examinar los cambios de la base de datos en el nivel de transacciones. Oracle soporta dos niveles de aislamiento ANSI/ISO “con compromiso de lectura” y “secuenciable”. No hay soporte para lecturas no actualizadas puesto que no hay necesidad. Los dos niveles de aislamiento corresponden a si se utiliza la consistencia de la lectura en el nivel de instrucción o en el nivel de transacción. El nivel se puede establecer para una sesión o para una transacción individual. La consistencia de lectura en el nivel de la instrucción es el nivel de aislamiento predeterminado. Oracle utiliza un bloqueo en el nivel de las filas. Las actualizaciones de distintas filas no entran en conflicto. Si dos escritores intentan modificar la misma fila, uno espera hasta que el otro comprometa o retroceda y entonces puede devolver un error de conflicto de escritura o seguir y modificar la fila. Los bloqueos se mantienen mientras dura la transacción. Además de los bloqueos en el nivel de las filas que evitan las inconsistencias debido a la actividad, el LMD de Oracle utiliza los bloqueos de tabla para evitar las inconsistencias debido a la actividad LDD. Estos bloqueos evitan que, por ejemplo, un usuario elimine una tabla mientras otro usuario tiene una transacción aún no comprometida que está accediendo a la tabla. Oracle no utiliza el dimensionamiento de bloqueos para convertir los bloqueos de filas a bloqueos de tabla con el propósito de su control de concurrencia normal. Oracle detecta los interbloqueos automáticamente y los resuelve haciendo que retroceda una de las transacciones involucradas en el interbloqueo. Oracle soporta transacciones autónomas que son transacciones independientes generadas con otras transacciones. Cuando Oracle invoca a una transacción autónoma genera una nueva transacción en un contexto separado. La nueva transacción se puede comprometer o retroceder antes de que el control vuelva a la transacción invocante. Oracle soporta varios niveles de anidamiento de transacciones autónomas.

www.detodoprogramacion.com


27.6

Arquitectura del sistema

851

27.5.2 Estructuras básicas de recuperación

Con el fin de comprender cómo se recupera Oracle de un fallo, tal como una caída del disco, es importante comprender las características básicas que están involucradas. Además de los archivos de datos que contienen las tablas e índices hay archivos de control, registros históricos rehacer, registros históricos rehacer archivados y segmentos de retroceso. El archivo de control contiene varios metadatos que son necesarios para operar en la base de datos, incluyendo la información sobre las copias de seguridad. Oracle registra cualquier modificación transaccional de una memoria intermedia de la base de datos en el registro histórico rehacer, que consiste en dos o más archivos. Registra la modificación como parte de la operación que la causa y sin considerar si la transacción finalmente se produce. Registra los cambios de los índices y segmentos de retroceso así como los cambios a la tabla de datos. Cuando se llenan los registros históricos rehacer se archivan mediante uno o varios procesos en segundo plano (si la base de datos se ejecuta en modo archivelog). El segmento de retroceso contiene información sobre versiones anteriores de los datos (esto es, información para deshacer). Además de esta función en el modelo de consistencia de Oracle, la información se utiliza para restaurar la versión anterior de los datos cuando se deshace una transacción que ha modificado los datos. Para poder recuperar un fallo de almacenamiento se debería realizar una copia de seguridad de los archivos de datos y archivos de control periódicamente. La frecuencia de la copia de seguridad determina el tiempo mayor de recuperación, puesto que lleva más tiempo la recuperación si la copia de seguridad es antigua. Oracle soporta copias de seguridad en caliente—copias de seguridad ejecutadas en una base de datos en línea que está sujeta a una actividad transaccional. Durante la recuperación de una copia de seguridad, Oracle ejecuta dos pasos para alcanzar un estado consistente de la base de datos como existía antes del fallo. En primer lugar Oracle rehace las transacciones aplicando los archivos históricos rehacer (archivados) a la copia de seguridad. Esta acción lleva a la base de datos a un estado que existía en la fecha del fallo, pero no necesariamente un estado consistente puesto que los registros históricos deshacer incluyen datos no comprometidos. En segundo lugar, Oracle deshace las transacciones no comprometidas mediante el uso del segmento de retroceso. La base de datos está ahora en un estado consistente. La recuperación en una base de datos que ha sido objeto de una actividad transaccional grande debido a la última copia de seguridad puede ser costosa en tiempo. Oracle soporta recuperación en paralelo en la cual se utilizan varios procesos para aplicar información de rehacer simultáneamente. Oracle proporciona una herramienta GUI, el gestor de recuperación (Recovery Manager), que automatiza la mayor parte de las tareas asociadas con copias de seguridad y recuperación. 27.5.3 Oracle Data Guard

Para asegurar una alta disponibilidad, Oracle proporciona la característica bases de datos en espera denominada Data Guard (esta característica es la misma que la de las copias de seguridad remotas, descrita en el Apartado 17.9). Una base de datos en espera es una copia de la base de datos normal que se instala en un sistema separado. Si ocurre un fallo catastrófico en el sistema principal el sistema en espera se activa y asume el control, minimizando el efecto del fallo en la disponibilidad. Oracle mantiene la base de datos en espera actualizada mediante la aplicación constante de archivos históricos rehacer archivados que se envían desde la base de datos principal. La base de datos de seguridad se puede usar en línea en modo sólo lectura y utilizarla para informes y consultas para el apoyo a la toma de decisiones. 27.6 Arquitectura del sistema

Siempre que una aplicación de base de datos ejecuta una instrucción SQL hay un proceso del sistema operativo que ejecuta código en el servidor de bases de datos. Oracle se puede configurar de forma que el proceso del sistema operativo esté dedicado exclusivamente a la instrucción que se está procesando o de forma que el proceso se pueda compartir entre varias instrucciones. La última configuración, conocida como servidor compartido, tiene propiedades diferentes respecto a la arquitectura del proceso y memoria.

www.detodoprogramacion.com


852

Capítulo 27

Oracle

En primer lugar se estudiará la arquitectura del servidor dedicado y, posteriormente, la arquitectura del servidor multienhebrado.

27.6.1 Servidor dedicado: estructuras de memoria

La memoria utilizada por Oracle se divide principalmente en tres categorías: áreas de código software, que son las partes de la memoria en las que reside el código del servidor Oracle, área global del sistema (System Global Area, SGA) y el área global del programa (Program Global Area, PGA). Para cada proceso se asigna un PGA para albergar sus datos locales e información de control. Este área contiene espacio en pilas para diversos datos de la sesión y la memoria privada para la instrucción SQL que se está ejecutando. También contiene memoria para operaciones de ordenación y asociación que pueden ocurrir durante la evaluación de la instrucción. El rendimiento de estas operaciones depende de la cantidad de memoria disponible. Por ejemplo, una reunión por asociación que se pueda realizar en memoria será más rápida que si es necesario acceder a disco. Dado que hay un gran número de operaciones de ordenación y asociación activas simultáneamente (ya que hay varias consultas y varias operaciones en cada una de ellas), la decisión del tamaño de memoria a asignar para cada operación no es algo trivial, especialmente si fluctúa la carga de trabajo del sistema. Oracle permite que el administrador de bases de datos especifique un parámetro para la cantidad total de memoria que se debería considerar disponible para estas operaciones y decide dinámicamente la mejor forma de dividir esta mrmoria entre las operaciones activas para maximizar la productividad. El algoritmo de asignación de memoria conoce la relación entre la memoria y el rendimiento de las diferentes operaciones y trata de asegurar que la memoria disponible se use de la forma más eficaz posible. SGA es un área de memoria para estructuras que son compartidas entre los usuarios. Está formada por varias estructuras principales, incluyendo: • Caché de memoria intermedia. Esta caché mantiene bloques de datos a los que se accede frecuentemente (tablas e índices) en memoria para reducir la necesidad de ejecutar E/S a disco físico. Se usa la política “utilizado menos recientemente” salvo para los bloques a los que se acceda durante una exploración de tabla completa. Sin embargo, Oracle permite crear varias colas de memoria intermedia que tienen distintos criterios para la datación de los datos. Algunas operaciones Oracle omiten la caché de memoria intermedia y leen los datos directamente del disco. • Memoria intermedia de registro histórico rehacer. Esta memoria intermedia contiene la parte del registro histórico rehacer que no se ha escrito todavía en el disco. • Cola compartida. Oracle busca maximizar el número de usuarios que pueden utilizar la base de datos concurrentemente minimizando la cantidad de memoria que es necesaria para cada usuario. Un concepto importante en este contexto es la capacidad de compartir la representación interna de instrucciones SQL y el código procedimental escrito en PL/SQL. Cuando varios usuarios ejecutan la misma instrucción SQL pueden compartir la mayoría de estructuras de datos que representan el plan de ejecución de la instrucción. Solamente los datos que son locales a cada invocación específica de la instrucción necesitan mantenerse en una memoria privada. Las partes que se pueden compartir de las estructuras de datos que representan la instrucción SQL se almacenan en la cola compartida, incluyendo el texto de la instrucción. El almacenamiento en caché de instrucciones SQL en la cola compartida también se guarda en tiempo de compilación, puesto que una nueva invocación de la instrucción que ya está almacenada en caché no tiene que pasar por el proceso de compilación completo. La determinación de si una instrucción SQL es la misma que la existente en la cola compartida se basa en la coincidencia exacta del texto y en el establecimiento de ciertos parámetros de sesión. Oracle puede remplazar automáticamente las constantes en una instrucción SQL con variables vinculadas; las consultas futuras que son iguales salvo por los valores de constantes coincidirán con la consulta anterior en la cola compartida. La cola compartida también contiene cachés para información de diccionario y diversas estructuras de control.

www.detodoprogramacion.com


27.6

Arquitectura del sistema

853

27.6.2 Servidor dedicado: estructuras de proceso

Hay dos tipos de procesos que ejecutan código servidor Oracle: procesos servidor que procesan instrucciones SQL y procesos en segundo plano que ejecutan diversas tareas administrativas relacionadas con el rendimiento. Algunos de estos procesos son opcionales y en algunos casos se pueden utilizar varios procesos del mismo tipo por razones del rendimiento. Algunos de los tipos más importantes de procesos en segundo plano son: • Escritor de la base de datos. Cuando una memoria intermedia se elimina de la caché de la memoria intermedia se debe volver a escribir en el disco si se ha modificado desde que se introdujo en la caché. Los procesos del escritor de la base de datos ejecutan esta tarea, lo que ayuda al rendimiento del sistema liberando espacio en la caché de la memoria intermedia. • Escritor del registro histórico. El escritor del registro histórico procesa las entradas de escritura de la memoria intermedia del registro histórico rehacer al archivo del registro histórico rehacer en el disco. También escribe un registro de compromiso al disco siempre que se compromete una transacción. • Punto de revisión. El proceso punto de revisión actualiza las cabeceras del archivo de datos cuando ocurre un punto de revisión. • Monitor del sistema. Este proceso realiza la recuperación ante una caída en caso necesario. También ejecuta cierta administración del espacio para reclamar espacio no utilizado en espacios temporales. • Monitor de procesos. Este proceso ejecuta recuperación de procesos para procesos del servidor que fallan, liberando recursos y ejecutando diversas operaciones de limpieza. • Recuperador. El proceso recuperador resuelve los fallos y dirige la limpieza de transacciones distribuidas. • Archivador. El archivador copia el archivo de registro histórico rehacer en línea a un registro histórico rehacer cada vez que se llena el archivo de registro histórico en línea. 27.6.3 Servidor compartido

La configuración de servidor compartido aumenta el número de usuarios que un número dado de procesos servidor puede soportar compartiendo los procesos servidor entre las instrucciones. Difiere de la arquitectura de servidor dedicado en los siguientes aspectos principales: • Un proceso de envío en segundo plano encamina las solicitudes de usuarios al siguiente proceso servidor disponible. Al realizar esto utiliza una cola de solicitudes y una cola de respuestas en el SGA. El distribuidor pone una nueva solicitud en la cola de solicitudes donde será recogida por un proceso servidor. Un proceso servidor completa una solicitud, pone el resultado en la cola de respuestas para ser recogida por el distribuidor y ser devuelta al usuario. • Puesto que un proceso servidor se comparte entre varias instrucciones SQL, Oracle no mantiene datos privados en el PGA. Almacena los datos específicos de la sesión en el SGA. 27.6.4 Oracle Real Application Clusters

Las agrupaciones de aplicaciones reales de Oracle (Oracle Real Application Clusters) es una característica que permite que varios ejemplares de Oracle se ejecuten en la misma base de datos (recuérdese que, en terminología de Oracle, un ejemplar es la combinación de procesos en segundo plano y áreas de memoria). Esta característica permite a Oracle ejecutarse en arquitecturas de hardware agrupadas y MPP (disco compartido y sin compartimiento). La capacidad de agrupar varios nodos tiene importantes ventajas en la dimensionabilidad y disponibilidad que son útiles en entornos OLTP y de almacén de datos.

www.detodoprogramacion.com


854

Capítulo 27

Oracle

Las ventajas de dimensionabilidad de la característica son obvias, puesto que más nodos significa más potencia de procesamiento. En las arquitecturas sin compartimiento la adición de nodos a un agrupamiento normalmente requiere la redistribución de los datos entre los nodos. Oracle usa una arquitectura de disco compartido donde todos los nodos tienen acceso a todos los datos y, como resultado, se pueden añadir más nodos a un RAC sin preocuparse de que los datos se dividan entre los nodos. Oracle optimiza más todavía el uso del hardware a través de las características tales como las reuniones por afinidad y por particiones. RAC también se puede utilizar para lograr una alta disponibilidad. Si un nodo falla, los restantes todavía están disponibles para que la aplicación acceda a la base de datos. Las instancias restantes automáticamente retroceden las transacciones sin compromiso que están siendo procesadas en el nodo que falló con el fin de evitar un bloqueo de la actividad en el resto de nodos. La ejecución de varias instancias en la misma base de datos da lugar a varios temas técnicos que no existen en un único ejemplar. Mientras que algunas veces es posible dividir una aplicación entre los nodos, de forma que los nodos raramente accedan a los mismos datos, siempre hay posibilidad de solapamiento, que afecta a la gestión de la caché. Para solucionarlo, Oracle usa la característica mezcla de cachés, que permite a los bloques de datos fluir directamente entre las cachés de distintos ejemplares mediante el uso de la interconexión, sin ser escritas a disco. 27.7 Réplica, distribución y datos externos

Oracle proporciona soporte para la réplica y las transacciones distribuidas con compromiso de dos fases. 27.7.1 Réplica

Oracle soporta varios tipos de réplica (véase el Apartado 19.2.1 para una introducción a la réplica). En su forma más sencilla los datos en un sitio maestro se duplican en otros sitios en forma de instantáneas (el término instantánea en este contexto no se debería confundir con el concepto de instantánea consistente en lectura en el contexto del modelo de concurrencia). Una instantánea no tiene que contener todos los datos maestros (puede, por ejemplo, excluir ciertas columnas de una tabla por razones de seguridad). Oracle soporta dos tipos de instantáneas: sólo de lectura y actualizable. Una instantánea actualizable se puede modificar en el sitio esclavo y las modificaciones se propagan hasta la tabla maestra. Sin embargo, las instantáneas sólo de lectura permiten un rango más amplio de definiciones de instantánea. Por ejemplo una instantánea de sólo lectura se puede definir en términos de conjuntos de operaciones sobre tablas en el sitio maestro. Oracle también soporta varios sitios maestros para los mismos datos, donde todos los sitios maestros actúan como pares. Se puede actualizar una tabla duplicada en cualquiera de los sitios maestro y la actualización se propaga al resto de sitios. Las actualizaciones se pueden propagar de forma asíncrona o sincrónica. Para la réplica asíncrona la información de actualización se envía mediante procesos por lotes al resto de sitos maestros y a continuación se aplican. Puesto que los mismos datos podrían estar sujetos a modificaciones conflictivas en sitios diferentes, se podría necesitar una resolución del conflicto basada en algunas reglas del negocio. Oracle proporciona una serie de métodos de resolución de conflictos incorporados y permite a los usuarios escribir el suyo propio si fuera necesario. Con la réplica asíncrona una actualización de un sitio maestro se propaga de forma inmediata al resto de sitios. Si falla la transacción de actualización en cualquier sitio maestro, la actualización se deshace en todos los sitios. 27.7.2 Bases de datos distribuidas

Oracle soporta consultas y transacciones sobre varias bases de datos en distintos sistemas. Con el uso de pasarelas los sistemas remotos pueden incluir bases de datos que no sean de Oracle. Oracle tiene capacidades incorporadas para optimizar una consulta que incluya tablas en distintos sitios, recuperar los datos relevantes y devolver los resultados como si hubiera sido una consulta normal local. Oracle también soporta la emisión transparente de transacciones a varios sitios mediante un protocolo de compromiso en dos fases incorporado.

www.detodoprogramacion.com


27.8

Herramientas de gestión de bases de datos

855

27.7.3 Orígenes de datos externos

Oracle tiene varios mecanismos para soportar orígenes de datos externos. El uso más común es el almacén de datos cuando se cargan normalmente grandes cantidades de datos desde un sistema transaccional. 27.7.3.1 SQL*Loader

Oracle tiene una utilidad de carga directa, SQL*Loader, que soporta cargas rápidas en paralelo de grandes cantidades de datos desde archivos externos. Soporta una serie de formatos de datos y puede ejecutar varias operaciones de filtrado sobre los datos que se están cargando. 27.7.3.2 Tablas externas

Oracle permite hacer referencia a los orígenes de datos externos, tales como archivos planos, en la cláusula from de una consulta como si fueran tablas normales. Una tabla externa se define mediante metadatos que describen los tipos de columna Oracle y la correspondencia entre los datos externos y dichas columnas. También es necesario un controlador de acceso para acceder a los datos externos. Oracle proporciona un controlador predeterminado para archivos planos. La característica de tabla externa tiene el objetivo principal de operaciones de extracción, transformación y carga (ETL) en un entorno de almacén de datos. Los datos se pueden cargar en el almacén de datos desde un archivo plano utilizando create table tabla as select ... from < tabla externa > where ... Mediante la agregación de operaciones sobre los datos en la lista select o cláusula where, se pueden realizar transformaciones y filtrados como parte de la misma instrucción SQL. Puesto que estas operaciones se pueden expresar en SQL nativo o en funciones escritas en PL/SQL o Java, la característica de tabla externa proporciona un mecanismo potente para expresar todas las clases de operaciones de transformación y filtrado de los datos. Para la dimensionabilidad, se puede realizar en paralelo el acceso a la tabla externa con la ejecución en paralelo de Oracle. 27.8 Herramientas de gestión de bases de datos

Oracle proporciona a los usuarios una serie herramientas para la gestión del sistema y desarrollo de aplicaciones. Se ha hecho un gran énfasis en la versión Oracle 10g sobre el concepto de administración, es decir, en la reducción de la complejidad de todos los aspectos de la creación y administración de una base de datos Oracle. Este esfuerzo cubre una amplia variedad de áreas, incluyendo la creación de bases de datos, el ajuste, la gestión de espacio, de almacenamiento, la copia de seguridad y la recuperación, la gestión de memoria, los diagnósticos de rendimiento y la gestión de la carga de trabajo. 27.8.1 Repositorio automático de carga de trabajo

El repositorio automático de carga de trabajo (Automatic Workload Repository, AWR) es uno de los componentes principales de la infraestructura proporcionada por Oracle para reducir el esfuerzo de la administración. Oracle supervisa la actividad en el sistema de bases de datos y registra diferentes tipos de información relativa a las cargas de trabajo y al consumo de recursos. Esta información se usa en los diagnósticos de rendimiento y proporciona el fundamento de varios asesores que analizan diferentes aspectos de rendimiento y aconsejan cómo mejorarlo. Oracle tiene asesores para el ajuste de SQL, la creación de estructuras de acceso, como los índices y las vistas materializadas, y el dimensionamiento de la memoria. Oracle también proporciona asesores para la desfragmentación de segmentos y el redimensionamiento.

www.detodoprogramacion.com


856

Capítulo 27

Oracle

27.8.2 Gestión de los recursos de la base de datos

Un administrador de la base de datos necesita poder controlar cómo se divide la potencia de procesamiento entre los usuarios y grupos de usuarios. Algunos grupos pueden ejecutar consultas interactivas donde el tiempo de respuesta es crítico; otros pueden ejecutar informes largos que se pueden ejecutar como tareas de procesos por lotes en segundo plano cuando la carga del sistema sea baja. También es importante poder evitar que un usuario envíe inadvertidamente una consulta ad hoc extremadamente costosa que retrasará demasiado al resto. La característica de gestión de los recursos de la base de datos de Oracle permite al administrador de la base de datos dividir los usuarios entre grupos consumidores de recursos con distintas prioridades y propiedades. Por ejemplo, un grupo de usuarios interactivos de alta prioridad pueden tener garantizado al menos un 60 por ciento de CPU. El resto, más alguna parte del 60 por ciento no utilizado por el grupo de alta prioridad, se asignaría entre los grupos de consumidores de recursos con baja prioridad. Un grupo de, realmente, baja prioridad podría tener asignado un 0 por ciento, lo que significaría que las consultas enviadas por este grupo se ejecutarían solamente cuando hubiera disponibles ciclos de CPU no utilizados. Se pueden establecer para cada grupo límites para el grado de paralelismos para la ejecución en paralelo. El administrador de la base de datos también puede establecer límites de tiempo sobre cuánto tiempo máximo de ejecución se permite a una instrucción SQL. Cuando un usuario envía una instrucción, el gestor de recursos estima cuánto tiempo tardaría en ejecutarse y devuelve un error si la instrucción viola el límite. El gestor de recursos también puede limitar el número de sesiones de usuario que se pueden activar simultáneamente para cada grupo de consumidores de recursos. Otro recurso que puede controlar este gestor es el espacio para deshacer transacciones. 27.8.3 Oracle Enterprise Manager

El gestor corporativo de Oracle (Oracle Enterprise Manager) es la principal característica de Oracle para la gestión de sistemas de bases de datos. Proporciona una interfaz de usuario gráfica (GUI) sencilla de utilizar para la mayoría de tareas asociadas con la administración de bases de datos Oracle, incluyendo la configuración, la supervisión del rendimiento, la gestión de recursos, de la seguridad y acceso a los asesores. 27.9 Minería de datos

El componente de minería de datos de Oracle (Oracle Data Mining) proporciona varios algoritmos que incorporan el proceso de minería de datos dentro de la propia base de datos tanto para la construcción de un modelo sobre un conjunto de programas, como para su aplicación para evaluar los datos de producción reales. El hecho de que no sea necesario que los datos sean externos a la base de datos es una ventaja significativa sobre los motores separados de minería de datos. Tener que extraer e insertar grandes conjuntos de datos en un motor separado es incómodo y costoso, y además puede impedir que los nuevos datos se analicen justo después de que se introduzcan en la base de datos. Oracle proporciona funcionalidades para el aprendizaje supervisado y sin supervisar, tales como: • Clasificación. • Regresión. • Importancia de los atributos. • Agrupamiento. • Análisis de mercado. • Extracción de características. • Minería de texto. • Bioinformática (BLAST).

www.detodoprogramacion.com


Notas bibliográficas

857

Oracle proporciona dos interfaces para la minería de datos: una de Java y otra basada en el lenguaje procedimental PL/SQL de Oracle. Una vez que se construye un modelo en una base de datos de Oracle, se puede enviar o implatar en otras bases de datos de Oracle. Oracle puede importar y exportar modelos usando una representación tanto en PL/SQL como en PMML (Predictive Model Markup Language). Los modelos PMML generados por Oracle se pueden usar con otras herramientas que soporten PMML. Notas bibliográ cas

Se puede encontrar información actualizada, incluyendo documentación, sobre productos Oracle en http://www.oracle.com y http://technet.oracle.com. La indexación extensible en Oracle se describe en Srinivasan et al. [2000b] y en Srinivasan et al. [2000b]. Srinivasan et al. [2000a] describen las tablas organizadas con índices. Banerjee et al. [2000], Murthy y Banerjee [2003], y Krishnaprasad et al. [2004] describen el soporte XML en Oracle8i. Bello et al. [1998] describen las vistas materializadas en Oracle. Antoshenkov [1995] describe la técnica de compresión de mapas de bits alineadas por bytes utilizada en Oracle; véase también Johnson [1999]. Lahiri et al. [2001b] describen la mezcla de caché de RAC. La recuperación en Oracle se describe en Joshi et al. [1998] y en Lahiri et al. [2001a]. La mensajería y las colas en Oracle se describen en Gawlick [1998]. Witkowski et al. [2003a] y Witkowski et al. [2003b] describen la cláusula MODEL. Los algoritmos de gestión de memoria para la ordenación y asociación se describen en Dageville y Zait [2002]. Poess y Potapov [2003] describen la compresión de tablas de Oracle. El algoritmo de conjuntos de elementos frecuentes para el análisis de mercado de Oracle Data Mining se describe en Li y Mozes [2004]. El ajuste automático de SQL se describe en Dageville et al. [2004]. Cruanes et al. [2004] describen la ejecución paralela de Oracle.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

28

DB2 Universal Database de IBM Sriram Padmanabhan Centro de Investigación de IBM T. J. Watson

La familia de productos DB2 Universal Database de IBM es el buque insignia de servidores de base de datos y las familias de productos para inteligencia de negocio, integración de información y gestión de contenidos ampliamente reconocidos por su robustez. El servidor de base de datos DB2 Universal Database Server está disponible en gran número de plataformas hardware y sistemas operativos. La lista de las plataformas del servidor soportadas incluye sistemas de alto nivel como mainframes, procesadores masivamente paralelos (MPP) y grandes servidores multiprocesadores simétricos (SMP); sistemas medios como SMPs de cuatro y ocho vías; estaciones de trabajo; e incluso pequeños dispositivos de bolsillo. Los sistemas operativos que están soportados incluyen variantes de Unix tales como Linux, AIX, Solaris y HP-UX, así como Windows 2000, Windows XP, MVS, VM, OS/400, entre otros. DB2 Everyplace Edition soporta sistemas operativos tales como PalmOS y Windows CE. DB2 Cloudscape es un motor de base de datos Java puro que se puede incluir fácilmente en servidores de aplicaciones y otras aplicaciones. Estas aplicaciones pueden migrarse sin problemas de plataformas de gama baja a grandes servidores debido a la portabilidad de los interfaces y servicios de DB2. Además del motor del núcleo de la base de datos, la familia DB2 incluye otros productos que proporcionan herramientas, administración, replicación, acceso a datos distribuido, acceso ubicuo a datos, OLAP, y muchas otras características. En la Figura 28.1 se describen los diferentes productos de la familia. 28.1 Visión general

El origen de DB2 se remonta al proyecto System R en el Centro de investigación de Almadén (Almaden Research Center) de IBM (entonces denominado Laboratorio de investigación de San José, IBM San Jose Research Laboratory). El primer producto DB2 se comercializó en 1984 sobre la plataforma mainframe de IBM, seguido tiempo después por versiones para otras. IBM ha mejorado continuamente DB2 en áreas tales como procesamiento de transacciones (registro histórico de escritura anticipada y los algoritmos de recuperación ARIES), procesamiento y optimización de consultas (proyecto de investigación Starburst), procesamiento en paralelo (DB2 Parallel Edition), soporte para bases de datos activas (restricciones y disparadores), técnicas avanzadas de consultas y almacenes de datos tales como vistas materializadas, agrupaciones multidimensionales, características “autónomas” y soporte del modelo relacional orientado a objetos (ADTs, UDFs). Puesto que IBM soporta un gran número de plataformas de servidor y de sistema operativo, el motor de base de datos DB2 consiste en cuatro bases de código diferentes: (1) Linux, Unix y Windows, (2) z/OS, (3) VM, y (4) OS/400. Todos estos soportan un subconjunto común de lenguaje de definición de 859

www.detodoprogramacion.com


860

DB2 Universal Database de IBM

CapĂ­tulo 28

•

•

0

*

•

!

"

#

•

%

!

"

#

$

!

!

"

#

&

!

!

!

*

"

•

)

+

(

!

,

+

"

"

'

,

#

#

.

!

!

2

,

!

#

#

%

,

!

#

!

,

"

•

!

*

3

!

+

,

#

)

&

!

!

!

!

"

(

&

'

%

'

%

#

#

,

*

!

!

1

1

'

-

-

&

(

•

'

$

%

#

'

#

$

/

Figura 28.1

!

#

'

.

)

&

!

#

/

Familia de productos DB2.

datos, de SQL y de los interfaces de administración. Sin embargo, los motores presentan características algo diversas debido a los orígenes de cada plataforma. Este capítulo estå centrado en el motor DB2 Universal Database (UDB) para Linux, Unix y Windows. Se reseùarån las características específicas de interÊs en otros sistemas DB2 cuando se considere apropiado. La última versión de la base de datos universal (UDB, Universal Database) DB2 para Linux, Unix y Windows es la 8.2. Esta versión contiene varias características que mejoran la ampliabilidad, la disponibilidad y la robustez general del motor DB2. En el årea de la ampliabilidad, dos características significativas son las tablas de consultas materializadas y las agrupaciones multidimensionales. Con respecto a la disponibilidad, se describen las mejoras en las åreas de utilidades en línea y las rÊplicas. Ademås, esta versión proporciona características autónomas tales como el asesor de diseùo y el ajuste y supervisión automåticos de memoria. Éstas y otras características adicionales se describirån en los apartados correspondientes.

28.2 Herramientas de diseĂąo de bases de datos

La mayor parte de las herramientas de diseĂąo de base de datos y herramientas CASE se pueden usar para diseĂąar una base de datos DB2. En particular, las herramientas de modelado de datos tales como ERWin y Rational Rose permiten al diseĂąador generar sintaxis LDD especĂ­fica de DB2. Por ejemplo, la herramienta UML Data Modeler de Rational Rose puede generar instrucciones create distinct type del LDD especĂ­fico de DB2 para tipos definidos por el usuario y usarlos posteriormente en definiciones de columnas. La mayor parte de herramientas de diseĂąo tambiĂŠn soportan una caracterĂ­stica de ingenierĂ­a inversa que lee las tablas del catĂĄlogo de DB2 y construye un diseĂąo lĂłgico para manipulaciones adicionales. Las herramientas pueden generar restricciones e Ă­ndices. DB2 proporciona constructores SQL para soportar muchas caracterĂ­sticas lĂłgicas de bases de datos, tales como restricciones, disparadores y recursiĂłn. De igual forma, DB2 soporta ciertas caracterĂ­sticas fĂ­sicas de bases de datos tales como espacios de tablas, colas de memoria intermedia, y particionamiento mediante el uso de instrucciones SQL. Para ello, la herramienta Centro de control de DB2 permite a los diseĂąadores o administradores emitir las instrucciones LDD apropiadas. Otra herramienta, db2look, permite al administrador obtener un conjunto completo de instrucciones LDD para una base de datos incluyendo espacios de tablas, tablas, Ă­ndices, restricciones, disparadores y funciones que crean una reproducciĂłn exacta del esquema de la base de datos para pruebas o rĂŠplica.

www.detodoprogramacion.com


28.3

Variaciones y extensiones de SQL

861

select xmlelement(name ’PO’, xmlattributes(idprod, fechapedido), (select xmlagg(xmlelement(name ’producto’, xmlattributes(idproducto, cantidad, fechaenvío), (select xmlelement(name ’descproducto’, xmlattributes(nombre, precio)) from producto where producto.idproducto = líneaproducto.idproducto))) from líneaproducto where líneaproducto.idprod = pedidos.idprod)) from pedidos where pedidos.idprod= 349; Figura 28.2

Consulta XML en SQL de DB2.

El Centro de control de DB2 incluye una serie de herramientas de diseño y administración. Respecto al diseño, el Centro de control proporciona una vista en árbol de un servidor, sus bases de datos, tablas, vistas y todos los demás objetos. También permite que los usuarios definan nuevos objetos, creen consultas SQL ad hoc y visualicen resultados de consultas. Las herramientas de diseño para ETL, OLAP, réplicas y federación también están integradas en el Centro de control. Toda la familia DB2 soporta el Centro de control para la definición de bases de datos, así como otras herramientas relacionadas. DB2 también proporciona módulos predeterminados para el desarrollo de aplicaciones en IBM Rational Application Development, así como en Microsoft Visual Studio. 28.3 Variaciones y extensiones de SQL DB2 soporta un amplio conjunto de características SQL para varios aspectos del procesamiento de bases de datos. Muchas de las características y sintaxis de DB2 han proporcionado la base de los estándares SQL-92 o SQL-99. Este apartado resalta las características XML del modelo relacional orientado a objetos y de integración de aplicaciones en la versión 8 de DB2 UDB. 28.3.1 Características XML

Se ha incluido en DB2 un extenso conjunto de funciones XML. A continuación se muestran algunas funciones XML importantes. • xmlelement. Construye una etiqueta elemento con un nombre dado. Por ejemplo, xmlelement(libro) crea el elemento libro. • xmlattributes. Construye el conjunto de atributos de un elemento. • xmlforest. Construye una secuencia de elementos XML a partir de los argumentos. • xmlconcat. Devuelve la concatenación de un número variable de argumentos XML. • xmlserialize. Proporciona una versión del argumento serializada orientada a caracteres. • xmlagg. Devuelve la concatenación de un conjunto de valores XML. • xml2clob. Construye una representación del XML de tipo objeto de gran tamaño de caracteres (clob). Este clob puede ser recuperado por aplicaciones SQL. Las funciones XML incorporadas en SQL proporcionan una gran capacidad en la manipulación de XML. Por ejemplo, supóngase que se necesita construir un documento XML de pedido de compra de las tablas pedidos, líneaproducto y producto para el número de pedido 349. En la Figura 28.2 se muestra una consulta SQL con extensiones XML que se pueden usar para crear dicho pedido de compra. La salida resultante se muestra en la Figura 28.3.

www.detodoprogramacion.com


862

Capítulo 28

DB2 Universal Database de IBM

<PO idprod = "349" fechapedido = "2004-10-01"> <item idproducto="1", cantidad="10", fechaenvío="2004-10-03"> <descproducto nombre = "IBM ThinkPad T41", precio = "1000.00 EUR¨/> </item> </PO> Figura 28.3

Pedido de compra en XML para el producto 349.

DB2 integra una característica de XML extendido que proporciona procedimientos almacenados y funciones definidas por el usuario para almacenar y manipular XML como grandes objetos de tipo carácter o atributos de varias tablas. Se puede acceder a estos objetos de XML mediante SQL con las extensiones XML antes mencionadas o con las funciones del extensor de XML. 28.3.2 Soporte para tipos de datos

DB2 proporciona soporte para tipos de datos definidos por el usuario. Se pueden definir tipos de datos distintos o estructurados. Los tipos de datos distintos están basados en tipos de datos incorporados en DB2.

Sin embargo, los usuarios pueden definir semánticas adicionales o alternativas para estos nuevos tipos. Por ejemplo, el usuario puede definir un tipo de datos distinto llamado euro, usando create distinct type euro as decimal(9,2) Posteriormente, se puede crear un campo (por ejemplo, precio) en una tabla cuyo tipo sea euro. Este campo se puede usar en predicados de consultas como en el siguiente ejemplo: select producto from ventas_Europa where precio > euro(1000) Los tipos de datos estructurados son objetos complejos que normalmente están formados por dos o más atributos. Por ejemplo, el siguiente código declara un tipo de datos estructurado denominado t_departamento: create type t_departamento as (nombredept varchar(32), directordept varchar(32), número integer) mode db2/sql create type t_punto as (coord_x float, coord_y float) mode db2/sql Los tipos estructurados se pueden usar para definir tablas con tipos. create table departamento of t_departamento Con el LDD se puede crear una jerarquía de tipos y tablas que pueden heredar métodos específicos y privilegios. Los tipos estructurados también se pueden usar para definir atributos anidados dentro de una columna de una tabla. Aunque este tipo de definiciones violaría las reglas de normalización, pueden ser convenientes para aplicaciones orientadas a objetos que se basan en la encapsulación y en métodos bien definidos sobre los objetos. 28.3.3 Funciones y métodos de nidos por el usuario

Otra característica importante es que los usuarios pueden definir sus propias funciones y métodos. Estas funciones se pueden incluir posteriormente en instrucciones y consultas SQL. Las funciones pueden

www.detodoprogramacion.com


28.3

Variaciones y extensiones de SQL

863

create function db2gse.GsegeFilterDist ( operación integer, g1XMín double, g1XMáx double, g1YMín double, g1YMáx double, dist double, g2XMín double, g2XMáx double, g2YMín double, g2YMáx double ) returns integer specific db2gse.GsegeFilterDist external name ’db2gsefn!gsegeFilterDist’ language C parameter style db2 sql deterministic not fenced threadsafe called on null input no sql no external action no scratchpad no final call allow parallel no dbinfo; Figura 28.4

Definición de una FDU.

generar escalares (único atributo) o tablas (fila multiatributo) como resultado. Los usuarios pueden definir funciones (escalares o de tablas) mediante el uso de la instrucción create function. Pueden escribir las funciones en lenguajes de programación comunes tales como C y Java o lenguajes de guiones tales como REXX y PERL. Las funciones definidas por el usuario (FDU) pueden operar en los modos separado (fenced) y compartido (unfenced). En el modo separado las funciones se ejecutan mediante una hebra separada en su propio espacio de dirección. En el modo compartido se permite al agente de procesamiento de la base de datos ejecutar la función en el espacio de direcciones del servidor. Las FDU pueden definir un área de trabajo donde pueden mantener variables locales y estáticas en invocaciones diferentes. Por tanto, las FDU pueden realizar manipulaciones complejas de las filas intermedias que son su entrada. En la Figura 28.4 se muestra una definición de una FDU en DB2, db2gse.GsegeFilterDist, que apunta a un método externo específico el cual realiza realmente la operación. Otra característica son los métodos asociados a un objeto, los cuales definen su comportamiento. A diferencia de las FDU, los métodos están asociados con tipos de datos estructurados particulares y se registran mediante el uso de la instrucción create method. 28.3.4 Objetos de gran tamaño

Las nuevas aplicaciones de las bases de datos requieren la manipulación de texto, imágenes, vídeo y otros tipos de datos típicos de gran tamaño. DB2 soporta estos requisitos proporcionando tres tipos de objetos de gran tamaño (LOB, Large Object) distintos. Cada LOB puede ocupar hasta 2 gigabytes. Los objetos de gran tamaño en DB2 son (1) objetos en binario (Binary Large Objetcs, BLOBs), (2) objetos de caracteres de un único byte (Character Large Objects, CLOBs) y (3) objetos de caracteres de dos bytes (Double Byte Character Large Objects, dbclobs). DB2 organiza estos LOBs como objetos separados, con cada fila en la tabla manteniendo punteros a sus LOBs correspondientes. Los usuarios pueden registrar FDUs que manipulen estos LOBs según los requisitos de la aplicación. 28.3.5 Extensiones de índices y restricciones

Una característica reciente de DB2 proporciona un constructor create index extension que ayuda a crear índices sobre atributos con tipos de datos estructurados mediante la generación de claves a partir de los tipos de datos estructurados. Por ejemplo, un usuario puede crear un índice en un atributo cuyo tipo es t_departamento definido anteriormente mediante la generación de claves con el nombre del departamen-

www.detodoprogramacion.com


864

Capítulo 28

DB2 Universal Database de IBM

create index extension db2gse.índice_espacial( gS1 double, gS2 double, gS3 double) from source key(geometry db2gse.ST_Geometry) generate key using db2gse.GseGridIdxKeyGen(geometry..srid, geometry..xMín, geometry..xMáx, geometry..yMín, geometry..yMáx, gS1, gS2, gS3) with target key(srsId integer, lvl integer, gX integer, gY integer, xMín double, xMáx double, yMín double, yMáx double) search methods <condiciones> <acciones> Figura 28.5

Extensión de índice espacial en DB2.

to. El extensor espacial de DB2 utiliza el método de extensión de índice para crear índices sobre los datos espaciales, como se muestra en la Figura 28.5. Finalmente, DB2 también proporciona un rico conjunto de características de verificación de restricciones para imponer la semántica de los objetos tales como unicidad, validez y herencia. 28.3.6 Servicios Web

En la Versión 8, DB2 permite integrar servicios Web como productor o consumidor. Se puede definir un servicio Web para invocar DB2 usando instrucciones SQL. La llamada al servicio Web resultante es procesada por un motor de servicios Web incorporado en DB2, que genera la correspondiente respuesta SOAP. Por ejemplo, si hay un servicio Web denominado ObtenerActividadReciente(id_cliente) que llama a la siguiente instrucción SQL, el resultado será la última transacción realizada por el cliente. select id_trn, importe, fecha from transacciones where id_cliente = <input> order by fecha fetch first 1 row only; La siguiente instrucción SQL muestra cómo DB2 actúa como un cliente de un servicio Web. En este ejemplo, la función ObtenerCotización() definida por el usuario es un servicio Web. DB2 realiza la llamada al servicio Web mediante un motor incorporado de servicios Web. En este caso, ObtenerCotización devuelve un valor de cotización para cada id_acción que aparece en la tabla cartera. select id_acción, ObtenerCotización(id_acción) from cartera 28.3.7 Colas de mensajes

DB2 también soporta el producto de IBM Websphere MQ mediante la definición de las FDU apropiadas, tanto para interfaces de lectura como de escritura. Estas FDU pueden incluirse en instrucciones SQL para la lectura o escritura sobre colas de mensajes.

28.4 Almacenamiento e indexación

La arquitectura de almacenamiento e indexación de DB2 está formada por la capa de sistema de ficheros o gestión de disco, los servicios para gestionar las memorias intermedias, objetos de datos tales como tablas, LOBs, objetos índices y gestores de concurrencia y recuperación. Este apartado muestra una visión

www.detodoprogramacion.com


28.4

Almacenamiento e indexación

865

general de la arquitectura de almacenamiento. Además, en el siguiente apartado se describe una nueva característica en la versión 8 de DB2 denominada agrupación multidimensional.

28.4.1 Arquitectura de almacenamiento

DB2 proporciona abstracciones de almacenamiento para gestionar tablas de base de datos lógicas en

entornos multinodo (paralelo) y multidisco. Se pueden definir grupos de nodos para soportar la división de la tabla en conjuntos especificados de nodos en un sistema multinodo. Esto permite flexibilidad al asignar particiones de tabla a nodos diferentes en un sistema. Por ejemplo, las tablas de gran tamaño se pueden dividir entre todos los nodos en un sistema, mientras que las tablas pequeñas pueden residir en un único nodo. Dentro de un nodo, DB2 usa espacios de tablas para organizar las tablas. Un espacio de tablas consiste en uno o más contenedores que son referencias a directorios, dispositivos o archivos. Un espacio de tablas puede contener cero o más objetos de base de datos tales como tablas, índices o LOBs. La Figura 28.6 ilustra estos conceptos. En esta figura se definen dos espacios de tablas para un grupo de nodos. Al espacio de tablas RECHUMANOS se le asignan cuatro contenedores mientras que al espacio de tablas smallPLAN sólo uno. Las tablas empleado y departamento se encuentran en el espacio de tablas RECHUMANOS mientras que la tabla proyecto está en el espacio de tablas smallPLAN. La distribución de datos asigna fragmentos (extensiones) de las tablas empleado y departamento a los contenedores del espacio de tablas RECHUMANOS. DB2 permite al administrador crear tanto espacios de tablas gestionados por el sistema como por el SGBD. Los espacios de tablas gestionados por el sistema (System-managed spaces, SMS) son directorios o sistemas de archivo que mantiene el sistema operativo subyacente. En un SMS, DB2 crea objetos archivo en los directorios y asigna datos a cada uno de los archivos. Los espacios de tablas gestionados por el SGBD (Data Managed Spaces, DMS) son dispositivos en bruto o archivos preasignados que son controlados por DB2. El tamaño de estos contenedores nunca puede crecer o disminuir. DB2 crea mapas de asignación y gestiona el espacio de tablas DMS. En ambos casos la unidad de espacio de almacenamiento es una extensión de páginas. El administrador puede elegir el tamaño de la extensión para un espacio de tabla. DB2 soporta la distribución en distintos contenedores. Por ejemplo, cuando se insertan los datos en una tabla recientemente creada, DB2 asigna la primera extensión a un contenedor. Una vez que la extensión está llena asigna los siguientes datos al siguiente contenedor por turnos rotatorios. La distribución proporciona dos ventajas significativas: E/S paralela y equilibrio de carga.

Grupo de nodos MisDepts

Espacio de tablas RECHUMANOS

departamento

empleado

Espacio de tablas PLAN

proyecto

Contenedores

Figura 28.6

Espacios de tablas y contenedores en DB2.

www.detodoprogramacion.com


866

Capítulo 28

DB2 Universal Database de IBM

Vista lógica de la página

0 1

Vista lógica del índice

La página 0 contiene un conjunto de registros internos (por ejemplo, FSCR)

K RID

2 3

500

K RID

registros de usuario

C RID

A RID C 3, 2

Cada página de 500 contiene otro FSCR otros registros de usuario Figura 28.7

RID

K RID

Páginas hoja

S RID

(Record ID, ID de registro) = Página 3, Ranura 2

Vista lógica de las tablas e índices en DB2.

28.4.2 Colas de memorias intermedias

Se puede asociar una o varias memorias intermedias con cada espacio de tablas para gestionar diferentes objetos tales como datos e índices. Una memoria intermedia es un área de datos compartida que mantiene copias de objetos en memoria. Estos objetos habitualmente están organizados en páginas para gestionar la memoria intermedia. DB2 permite la definición de memorias intermedias usando instrucciones SQL. La versión 8 de DB2 incluye la posibilidad de aumentar o disminuir el tamaño de las memorias intermedias de forma interactiva, o bien automáticamente si se selecciona la opción automatic en parámetro de configuración de memorias intermedias. Un administrador puede añadir más páginas a una memoria intermedia o bien disminuir su tamaño sin detener la actividad de la base de datos. create bufferpool <cola-mem-intermedia> .... alter bufferpool <cola-mem-intermedia> size <n> DB2 también soporta la preextracción y escrituras asíncronas mediante el uso de hebras separadas. El componente de gestión de datos de DB2 desencadena la preextracción de páginas de datos y de índices según los patrones de acceso de las consultas. Por ejemplo, una exploración de una tabla siempre desencadena la preextracción de páginas de datos. La exploración del índice puede desencadenar la preextracción de páginas de índices así como las páginas de datos si se está accediendo de una forma agrupada. El número de preextracciones concurrentes, así como el tamaño de la preextracción, son parámetros configurables que es necesario establecer según el número de discos o contenedores en el espacio de tablas. 28.4.3 Tablas, registros e índices

DB2 organiza los datos relacionales como registros en las páginas. La Figura 28.7 muestra la vista lógica

de una tabla y un índice asociado. La tabla consiste en un conjunto de páginas. Cada página consiste en un conjunto de registros (tanto registros de datos del usuario como registros especiales del sistema). La página cero de la tabla contiene registros del sistema especiales sobre la tabla y su estado. DB2 usa un registro del mapa de espacio denominado registro de control de espacio libre (Free Space Control Record, FSCR) para encontrar el espacio libre en la tabla. El registro FSCR normalmente contiene un mapa de espacio de 500 páginas. Una entrada FSCR consiste en unos pocos bits que proporcionan una indicación aproximada del porcentaje de espacio libre en la página. El algoritmo de inserción o actualización debe validar las entradas del FSCR realizando una comprobación física del espacio disponible en la página. Los índices también se organizan como páginas que contienen registros índice y punteros a páginas hijas y hermanas. DB2 proporciona soporte para los mecanismos de índices de árbol B+ . El índice de árbol B+ contiene páginas internas y páginas hoja. Los índices contienen punteros bidireccionales en el

www.detodoprogramacion.com


Agrupación multidimensional

28.5

Núm. página

1056

867

Núm. ranura

1

3 bytes 1 byte Página 473

Espacio libre (se puede usar sin reorganizar la página*)

Página 1056

Cabecera de página 3800 -1 3400

Espacio libre incorporado (se puede usar después de reorganizar la página*)

Cabecera de página 3800 3700

Registro 2 Registro 0

473,2

Registro 0

establecido en la creación del espacio de tablas

*Excepción: no se puede usar ningún espacio reservado por un borrado no comprometido

Figura 28.8

Diseño de las páginas de datos y de los registros en DB2.

nivel hoja para soportar exploraciones hacia delante y hacia atrás. Las páginas hoja contienen entradas de índice que apuntan a los registros de la tabla. Cada registro de una tabla se puede identificar unívocamente usando su información de página y de ranura, que se denominan identificador de registro o RID (Record ID). DB2 admite “columnas incluidas” (include) en la definición del índice, como en: create unique index I1 on T1 (C1) include (C2) Las columnas del índice incluidas permiten a DB2 extender el uso de las técnicas de procesamiento “sólo con índices” siempre que sea posible. Se pueden usar directivas adicionales tales como minpctused y pctfree para controlar la unión de páginas de índices y su asignación de espacio inicial. La Figura 28.8 muestra el formato de datos típico en DB2. Cada página de datos contiene una cabecera y un directorio de ranuras. El directorio de ranuras es un array de 255 entradas que apuntan a los desplazamientos de los registros en la página. La figura muestra que el número de página 473 contiene el registro cero en el desplazamiento 3800 y el registro 2 en el desplazamiento 3400. La página 1056 contiene un registro 1 en el desplazamiento 3700, que es realmente un puntero hacia delante al registro <473,2>. Por ello el registro <473,2> es un registro de desbordamiento que fue creado por una operación de actualización del registro <1056,1> original. DB2 soporta distintos tamaños de página tales como 4 KB, 8 KB, 16 KB y 32 KB. Sin embargo, cada página puede contener solamente 255 registros de usuario. Los tamaños de página mayores son útiles en aplicaciones tales como almacén de datos donde la tabla contiene muchas columnas. Los tamaños de página menores son útiles para datos operacionales con frecuentes actualizaciones. 28.5 Agrupación multidimensional

Esta sección proporciona una breve visión general de las principales características de las agrupaciones multidimensionales (Multidimensional Clustering, MDC). Con la agrupación multidimensional, una tabla DB2 puede crearse especificando una o varias claves como dimensiones para las que se agruparán los datos de la tabla. Existe una nueva cláusula denominada organize by dimensions para este cometido. Por ejemplo, la siguiente instrucción LDD describe una tabla de ventas organizada tomando los atributos idAlmacén, year(fechaPedido) e idProducto como dimensiones.

www.detodoprogramacion.com


Capítulo 28

DB2 Universal Database de IBM

México

1997, México, 1

región

868

Canadá

1997, México, 2

1997, Canadá, 1 1997, Canadá, 2

1

2

idP

rod

uc

Figura 28.9

1997, México, 2

to

31

45 127

1998, México, 2

1998, Canadá, 2

199

8

o) did e P

7 199

a ch

fe ar( ye

Vista lógica de la disposición física de una tabla MDC.

create table ventas(idAlmacén int, fechaPedido date, fechaEnvío date, fechaRecepción date, región int, idProducto int, precio float añoPedido int generated always as year(fechaPedido)) organized by dimensions (región, añoPedido, idProducto) Cada una de estas dimensiones puede estar formada por una o varias columnas, del mismo modo que los índices. De hecho, se crea automáticamente un ’índice dimensional de bloques’ (descrito más adelante) para cada una de las dimensiones especificadas, y se usa para acceder rápida y eficientemente a los datos. Si es necesario, se crea un índice de bloque compuesto que contiene todas las columnas clave de la dimensión y se usa para mantener la agrupación de datos durante las actividades de inserción y actualización. Cada combinación única de valores dimensionales forma una “celda” lógica que está físicamente organizada como bloques de páginas, donde un bloque es un conjunto de páginas consecutivas en disco. El conjunto de los bloques que contienen páginas con datos que verifican un cierto valor de clave de uno de los índices de bloque de dimensión se denomina “banda”. Cada página de la tabla forma parte de exactamente un bloque, y todos los bloques de la tabla están formados por el mismo número de páginas, que se denomina tamaño de bloque. DB2 asocia el tamaño de bloque con el tamaño de extensión del espacio de tablas, de forma que los límites de los bloques estén alineados con los límites de las extensiones. La Figura 28.9 ilustra estos conceptos. Esta tabla MDC se encuentra agrupada por las dimensiones year(fechaPedido)1 , región e idProducto. La figura muestra un cubo lógico sencillo con solamente dos valores por cada atributo de dimensión. En realidad, los atributos de dimensión pueden extenderse fácilmente a gran número de valores sin necesidad de administración. Las celdas lógicas están representadas en la figura por los cubos más pequeños. Los registros de la tabla se almacenan en bloques, que contienen una extensión de páginas consecutivas en disco. En el diagrama se representa cada bloque con una elipse gris, numerada de acuerdo al orden lógico de extensiones realizadas en la tabla. Sólo se muestran 1. Las dimensiones se pueden crear usando una función generada.

www.detodoprogramacion.com


28.5

Agrupación multidimensional

869

Lista BID

Clave Canadá

21

31

45

77

127

376

501

719

(a) Entrada del índice dimensional de bloques para la región ‘Canadá’.

Lista BID

Clave 2

1

7

20

65

101

273

274

476

(b) Entrada del índice dimensional de bloques para el identificador de producto 1 Figura 28.10

Entradas de las claves del índice a bloques.

algunos bloques de datos para la celda identificada por los valores de dimensión <1997,Canadá,2>. Una columna o una fila de la retícula representa una banda para una dimensión particular. Por ejemplo, todos los registros que contienen el valor “Canadá” en la dimensión región se encuentran en los bloques contenidos en la banda definida por la columna “Canadá” del cubo. De hecho, cada bloque en esta banda solamente contiene registros que contienen “Canadá” en el campo región. 28.5.1 Índices de bloque

En el ejemplo anterior, se crea un índice dimensional de bloques sobre cada uno de los atributos región, year(fechaPedido) e idProducto. Cada índice dimensional de bloques se estructura de la misma forma que un árbol B tradicional excepto que, en el nivel de las hojas, las claves apuntan a un identificador de bloque (Block Identifier, BID) en lugar de apuntar a un identificador de registro (Record Identifier, RID). Como cada bloque contiene potencialmente muchas páginas de registros, los índices de bloques son mucho más pequeños que los índices RID, y necesitan actualizarse solamente cuando se añade un nuevo bloque a la celda, o cuando se vacían y eliminan bloques existentes en la celda. Una banda, o el conjunto de bloques que contienen páginas con un valor clave particular en una dimensión, se representan en el índice dimensional de bloques asociado mediante una lista de BIDs para ese valor clave. La Figura 28.10 ilustra las bandas de bloques para valores específicos de las dimensiones región e idProducto, respectivamente. En el ejemplo anterior, para encontrar la banda que contiene todos los registros con valor “Canadá” en la dimensión región hay que buscar este valor clave en el índice dimensional de bloques y encontrar una clave como se muestra en la Figura 28.10a. Esta clave apunta al conjunto exacto de BIDs para ese valor particular. 28.5.2 Mapas de bloques

La tabla también tiene asociado un mapa de bloques. Este mapa registra el estado de cada bloque de la tabla. Un bloque puede estar en diferentes estados tales como in use, free, loaded y requiring constraint enforcement. La capa de gestión de datos usa el estado del bloque para determinar diversas opciones de procesamiento. La Figura 28.11 muestra un ejemplo de mapa de bloques de una tabla. El elemento 0 en el mapa de bloques representa el bloque 0 en el diagrama MDC de la tabla. El estado de disponibilidad del bloque es “U”, que indica que está en uso. Sin embargo, es un bloque especial y no contiene registros de usuario. Los bloques 2, 3, 9, 10, 13, 14 y 17 no se están usando en la tabla, por lo que se consideran “F” (libres) en el mapa de bloques. Los bloques 7 y 18 se han cargado recientemente a la tabla. El bloque 12 fue cargado anteriormente y requiere la comprobación de restricciones.

www.detodoprogramacion.com


870

Capítulo 28

DB2 Universal Database de IBM

0

5

1

2

3

4

6

7

8

9

19 11 12 13 14 15 16 17 18 19

U U

F

F

U U U

L

U

F

F

Figura 28.11

U

C

F

F

U

U

F

L

...

Entradas del mapa de bloques.

28.5.3 Consideraciones de diseño

Un aspecto crucial de las MDCs es la elección del conjunto correcto de dimensiones para agrupar una tabla y el tamaño correcto de bloque para minimizar el uso de espacio. Si las dimensiones y el tamaño de bloque se eligen apropiadamente, los beneficios de la agrupación se traducen en significativas ventajas de rendimiento y mantenimiento. Por otra parte, si se eligen incorrectamente, el rendimiento se puede degradar y el uso de espacio puede ser sensiblemente peor. Hay muchas técnicas de ajuste que se pueden explotar para organizar la tabla. Entre ellas se encuentran la variación del número de dimensiones, la granularidad de una o varias dimensiones, el tamaño de bloque (tamaño de extensión) y el tamaño de página del espacio de tablas que contiene la tabla. Se pueden usar una o varias de estas técnicas para identificar la mejor organización de la tabla. 28.5.4 Impacto sobre las técnicas existentes

Es natural preguntarse si la nueva característica de MDC tiene un impacto adverso o invalida algunas de las características existentes en DB2 para las tablas clásicas. Todas las características existentes tales como índices RID secundarios, restricciones, disparadores, vistas materializadas definidas y opciones de procesamiento de consultas están disponibles para las tablas MDC. Por consiguiente, las tablas MDC se comportan exactamente como las tablas clásicas excepto por sus aspectos mejorados de agrupación y procesamiento. 28.6 Procesamiento y optimización de consultas

El compilador de consultas de DB2 transforma las consultas en un árbol de operaciones. DB2 usa entonces el árbol de operadores de la consulta en tiempo de ejecución para el procesamiento. DB2 soporta un rico conjunto de operadores de consulta que permiten considerar mejores estrategias de procesamiento y proporcionan flexibilidad en la ejecución de consultas complejas. Las Figuras 28.12 y 28.13 muestran una consulta y su plan de consulta asociado. Se trata de una consulta compleja representativa (consulta 5) de la prueba TPC-H y contiene varias reuniones y agregaciones. El plan de consulta en este ejemplo es bastante simple puesto que solamente se definen pocos – – ’Consulta TPCD de volumen de proveedor local (Q5)’; select nac_nombre, sum(lp_precioextendido*(1-lp_descuento)) as ingresos from tpcd.cliente, tpcd.pedidos, tpcd.linea_pedido, tpcd.proveedor, tpcd.nación, tpcd.región where cli_clave_cliente = ped_clave_cliente and ped_clave_pedido = lp_clave_pedido and lp_clave_proveedor = prv_clave_proveedor and cli_clave_nación = prv_clave_nación and prv_clave_nación = nac_clave_nación and nac_clave_región = reg_clave_región and reg_nombre = ’MIDDLE EAST’ and ped_fecha_pedido >= date(’1995-01-01’) and ped_fecha_pedido < date(’1995-01-01’) + 1 year group by nac_nombre order by ingresos desc; Figura 28.12

Consulta SQL.

www.detodoprogramacion.com


28.6

Procesamiento y optimización de consultas

871

Resultados Exploración Ordenación Agrupación Exploración Ordenación Reunión por asociación Exploración Reunión por mezcla productos Ordenación Ordenación

Reunión por mezcla

Exploración del índice Ordenación

Ordenación pedidos

Exploración

NLJOIN

cliente

NLJOIN Exploración Exploración

Exploración

nación

región

proveedor

Figura 28.13

Plan de consulta de DB2 (explicación gráfica).

índices y no están disponibles para esta consulta estructuras auxiliares como las vistas materializadas. DB2 proporciona varias características de “explicación” del plan incluyendo una potente característica visual en el Centro de control que puede ayudar a los usuarios a comprender los detalles del plan de ejecución de la consulta. El plan de consulta en la figura está basado en la explicación visual de la consulta. La explicación visual permite al usuario comprender los costes y otras propiedades relevantes de las distintas operaciones de un plan de consulta. DB2 transforma todas las consultas e instrucciones SQL, sin importar lo complejas que sean, en un árbol de consulta. La base u operadores hoja del árbol de consulta manipulan los registros en tablas de base de datos. Estas operaciones también se denominan métodos de acceso. Las operaciones intermedias del árbol incluyen operaciones del álgebra relacional tales como reuniones, operaciones de conjuntos y agregaciones. La raíz del árbol produce los resultados de la consulta o instrucción SQL.

28.6.1 Métodos de acceso

DB2 soporta un conjunto detallado de métodos de acceso sobre tablas relacionales, incluyendo:

• Exploración de tabla. Con este método, el más básico, se accede a todos los registros en la tabla página por página. • Exploración de índice. DB2 usa un índice para seleccionar los registros específicos que satisfacen la consulta. Accede a los registros usando los RIDs en el índice. DB2 detecta las posibilidades de la preextracción de las páginas de datos cuando observa un patrón de acceso secuencial.

www.detodoprogramacion.com


872

Capítulo 28

DB2 Universal Database de IBM

• Exploración de índice de bloques. Es un nuevo método de acceso para tablas MDC. Se usa uno de los índices de bloque para explorar un conjunto específico de bloques de datos. DB2 accede y procesa los bloques seleccionados mediante operaciones de exploración de tablas de bloques. • Sólo con el índice. Este tipo de exploración se usa cuando el índice contiene todos los atributos que requiere la consulta. Por ello es suficiente una exploración de las entradas de índice y no hay necesidad de extraer los registros. La técnica sólo con el índice es normalmente una buena elección desde el punto de vista del rendimiento. • Lista de preextracción. Este método de acceso es una buena elección para una exploración de índices no agrupada con un número significativo de RIDs. DB2 recoge los RIDs de los registros relevantes usando una exploración de índices, después ordena los RIDs por el número de página y finalmente realiza una extracción de los registros de forma ordenada desde las páginas de datos. El acceso ordenado cambia el patrón E/S de aleatorio a secuencial y también ofrece posibilidades de preextracción. • Conjunción de índices de bloques y de registros. DB2 usa este método cuando determina que se puede usar más de un índice para restringir el número de registros satisfactorios en una tabla base. Procesa el índice más selectivo para generar una lista de BIDs o RIDs. Después procesa el siguiente índice selectivo para devolver los BIDs o RIDs que encuentra. Un BID o RID requiere más procesamiento solamente si está presente en la intersección (operación AND) de los resultados de la exploración del índice. El resultado de una operación AND del índice es una pequeña lista de RIDs o BIDs que se usan para extraer los registros correspondientes desde la tabla base. • Ordenación de índices de bloque y de registro. Esta estrategia es una buena elección si se pueden usar dos o más índices para satisfacer los predicados de la consulta que se combinan usando la operación OR. DB2 elimina los BIDs o RIDs duplicados realizando una ordenación y después extrae el conjunto de registros resultante. La disyunción de índices se ha extendido para considerar combinaciones de índices de bloque y RIDs. DB2 normalmente envía todos los predicados de selección y proyección de una consulta a los métodos de acceso. Además DB2 envía ciertas operaciones tales como la ordenación y la agregación, siempre que

es posible, con el fin de reducir el coste. La característica de MDC aprovecha el nuevo conjunto de mejoras en los métodos de acceso para exploraciones de índices de bloques, preextracción de índices de bloques, conjunción de índices de bloques y disyunción de índices de bloques para procesar los bloques de datos.

28.6.2 Operaciones de reunión, agregación y de conjuntos

DB2 soporta una serie de técnicas para las operaciones de reunión, agregación y de conjuntos. Para la reunión DB2 puede elegir entre técnicas de bucles anidados, mezcla-ordenación y de asociación. Para

describir las operaciones binarias de reuniones y de conjuntos se usará la notación de las tablas “externas” e “internas” para distinguir los dos flujos de entrada. La técnica de bucles anidados es útil si la tabla interna es muy pequeña o se puede acceder usando un índice sobre un predicado de reunión. Las técnicas de reunión de mezcla-ordenación y reunión por asociación son útiles para reuniones que involucran tablas internas y externas grandes. DB2 implementa las operaciones de conjuntos mediante el uso de técnicas de ordenación y mezcla. La técnica de mezcla elimina los duplicados en el caso de la unión mientras que los no duplicados se eliminan en el caso de intersección. DB2 también soporta operaciones de reunión externa de todas las clases. DB2 procesa las operaciones de agregación en modo impaciente o de envío siempre que sea posible. Por ejemplo, puede realizar la agregación mientras que ordena la entrada de la agregación en el grupo por columnas. Los algoritmos de reunión y agregación aprovechan el procesamiento superescalar en CPUs modernas usando técnicas orientadas a bloques y conscientes de la caché de memoria.

www.detodoprogramacion.com


28.6

Procesamiento y optimización de consultas

873

Consulta SQL: select * from ventas where cantidad > 10 Coordinador

P1

Nodos

P2

Recibe conexión

P3

Exploración de ventas Exploración de ventas Filtro cantidad >10 Filtro cantidad >10 Enviar al coordinador Enviar al coordinador Figura 28.14

P4

...

Distribuye subsección Recibe cola de tablas (tablequeue, TQ) Conexión

Subsección Acceso a la tabla (ventas) Predicado (cantidad > 10) Envío de TQ al coordinador

Procesamiento de consultas DB2 MPP usando envío de funciones.

28.6.3 Soporte para el procesamiento de SQL complejo

Uno de los aspectos más importantes de DB2 es que usa la infraestructura de procesamiento de la consulta de forma extensible para soportar operaciones SQL complejas. Las operaciones SQL complejas incluyen soporte para subconsultas profundamente anidadas y correlacionadas, así como restricciones, integridad referencial y disparadores. Como la mayor parte de estas acciones están incluidas dentro del plan de consulta, DB2 está preparado para soportar una gran cantidad de restricciones y acciones. Las restricciones y comprobaciones de integridad se construyen como operaciones del árbol de consulta a partir de las instrucciones SQL de inserción, borrado o actualización. DB2 también soporta el mantenimiento de vistas materializadas mediante el uso de disparadores incorporados. 28.6.4 Procesamiento de consultas en multiprocesadores

DB2 extiende el conjunto base de operaciones de consulta con primitivas de intercambio de datos y control para soportar los modos SMP, MPP y SMP por agrupaciones del procesamiento de consultas. DB2

usa una abstracción tabla-cola para el intercambio de datos entre hebras sobre distintos nodos o sobre el mismo nodo. La tabla-cola es una memoria intermedia que redirige los datos a receptores apropiados mediante el uso de métodos de difusión, uno a uno o multidifusión dirigida. Las operaciones de control crean hebras y coordinan la operación de distintos procesos y hebras. En todos estos modos DB2 usa un proceso coordinador para controlar las operaciones de colas y la reunión del resultado final. Los procesos de coordinación también pueden ejecutar algunas acciones globales de procesamiento de la base de datos si es necesario. Un ejemplo es la operación de agregación global para combinar los resultados de agregación local. Los subagentes o hebras esclavos ejecutan las operaciones base en uno o más nodos. En el modo SMP los subagentes usan memoria compartida para sincronizarse entre sí cuando comparten datos. En un MPP, los mecanismos de tabla-cola proporcionan memoria intermedia y control de flujo para la sincronización entre distintos nodos durante la ejecución. DB2 usa técnicas exhaustivas de optimización y procesa consultas de forma eficiente en entornos MPP o SMP. La Figura 28.14 muestra una consulta simple ejecutándose en un sistema MPP de cuatro nodos. En este ejemplo, la tabla ventas está dividida entre los cuatro nodos P1 , . . . , P4 . La consulta se ejecuta produciendo agentes que se ejecutan en cada uno de los nodos para explorar y filtrar las filas de la tabla ventas en ese nodo (denominado envío de funciones) y las filas resultantes se envían al nodo coordinador. 28.6.5 Optimización de consultas

El compilador de consultas de DB2 utiliza una representación interna de la consulta, denominada Query Graph Model (QGM, modelo de grafos de consultas) con el fin de ejecutar transformaciones y optimizaciones. Después de analizar la instrucción SQL, DB2 ejecuta transformaciones semánticas sobre el QGM para hacer cumplir las restricciones, integridad referencial y los disparadores. El resultado de estas transformaciones es un QGM mejorado. Seguidamente DB2 intenta ejecutar transformaciones de reescritura de la consulta que se consideran beneficiosas en la mayoría de las consultas. Se activan las

www.detodoprogramacion.com


874

Capítulo 28

DB2 Universal Database de IBM

reglas de reescritura, si son aplicables, para ejecutar las transformaciones requeridas. Los ejemplos de transformaciones de reescritura incluyen (1) descorrelación de subconsultas correlacionadas, (2) transformación de subconsultas en reuniones donde sea posible, (3) trasladar las operaciones group by bajo las reuniones si es aplicable y (4) uso de vistas materializadas para fragmentos de la consulta original. El optimizador de consultas usa QGM mejorado y transformado como su entrada para la optimización. El optimizador se basa en el coste y usa un entorno extensible, controlado por reglas. Se puede configurar el optimizador para operar a distintos niveles de complejidad. En el nivel más alto usa un algoritmo de programación dinámica para considerar todas las opciones del plan de consulta y elige el plan de coste óptimo. En un nivel intermedio el optimizador no considera ciertos planes o métodos de acceso (por ejemplo, disyunción de índices) así como algunas reglas de reescritura. En el nivel inferior de complejidad el optimizador usa una heurística impaciente simple para elegir un buen, aunque no necesariamente óptimo, plan de consulta. El optimizador emplea modelos detallados de las operaciones de procesamiento de la consulta (teniendo en cuenta detalles tales como tamaño de la memoria y preextracción) para obtener estimaciones adecuadas de los costes de E/S y CPU. Depende de la estadística de los datos para estimar la cardinalidad y selectividades de las operaciones. DB2 permite a un usuario generar histogramas de distribuciones en el nivel de las columnas y combinaciones de columnas mediante el uso de la utilidad runstats. Los histogramas contienen información sobre las apariciones del valor más frecuente así como sobre las distribuciones de frecuencia basadas en los cuantiles de los atributos. El optimizador de consultas utiliza estas estadísticas. El optimizador genera el que considera el mejor plan de consulta interno y entonces lo convierte en hebras de operadores y estructuras de datos asociados de la consulta para su ejecución mediante el motor de procesamiento de consultas. 28.7 Tablas de consultas materializadas

Las vistas materializadas están permitidas en la versión 8 de DB2 en Linux, Unix y Windows, así como en las plataformas z/OS. Cualquier definición de vista sobre una o varias tablas o vistas puede ser una vista materializada. La utilidad de este tipo de vistas estriba en que mantienen una copia persistente de los datos de la vista para proporcionar un procesamiento de consultas más rápido. En DB2 estas vistas materializadas se denominan tablas de consultas materializadas (materializad query tables, MQTs). Las MQTs se especifican usando una instrucción create table como la mostrada en el ejemplo de la Figura 28.15. En DB2 las MQTs pueden referirse a otras MQTs para crear un árbol o un bosque de vistas dependientes. Las MQTs son muy ampliables ya que pueden ser divididas en un entorno MPP y pueden tener claves de agrupación MDC. Las MQTs resultan de máximo valor si el motor de la base de datos es capaz de encaminar perfectamente consultas hacia la MQT, y también cuando el motor de la base de datos puede mantenerlas eficientemente siempre que sea posible. DB2 proporciona ambas características. 28.7.1 Encaminamiento de consultas a MQTs

La infraestructura del compilador de consultas de DB2 resulta ideal para impulsar toda la potencia de las MQTs. El modelo interno del QGM permite al compilador comparar la consulta de entrada con las definiciones de MQTs disponibles y elegir las MQTs apropiadas. Después de la comparación, el compilador considera varias opciones de optimización. Entre ellas se encuentran tanto la consulta base como las versiones de reencaminamiento de MQTs apropiadas. El optimizador itera a través de estas opciones create table empleado_departamento(id_departamento integer, id_empleado integer, nombre_empleado varchar(100), id_jefe integer) as select id_departamento, id_empleado, nombre_empleado, id_jefe from empleado, departmento data initially deferred refresh immediate – – (o deferred) maintained by user – – (o system) Figura 28.15

Tablas de consultas materializadas de DB2.

www.detodoprogramacion.com


28.7

Tablas de consultas materializadas

875

consulta SQL

Semántica de la consulta (validar posibilidad de reencaminamiento)

Fase de comparación de MQTs candidatas

Definiciones de MQTs

Consultas candidatas

Fase de optimización

Seleccionar el mejor plan

Comparación y optimización de MQTs en DB2.

Figura 28.16

antes de elegir la versión de ejecución óptima. El flujo completo de reencaminamiento y optimización se muestra en la Figura 28.16. 28.7.2 Mantenimiento de MQTs

Las MQTs sólo son útiles si el motor de la base de datos proporciona técnicas eficientes de mantenimiento. Hay dos dimensiones en el mantenimiento: tiempo y coste. En la dimensión temporal, las dos opciones son inmediato y diferido. DB2 soporta ambas. Si se selecciona mantenimiento inmediato, se crean disparadores internos que se compilan en las instrucciones de inserción, actualización o borrado de los objetos fuente para procesar las actualizaciones de las MQTs dependientes. En el caso del mantenimiento diferido, las tablas actualizadas se pasan a modo integridad y se debe ejecutar una instrucción refresh explícitamente para realizar la actualización. Con respecto a la dimensión de coste, se puede elegir entre incremental o completo. En el mantenimiento incremental sólo se utilizan para el mantenimiento las filas que han sido actualizadas recientemente. El mantenimiento completo actualiza toda la MQT desde las fuentes. La matriz de la Figura 28.17 muestra ambas dimensiones y las opciones más útiles en cada una de ellas. Por ejemplo, mantenimiento inmediato y completo sólo son compatibles si las fuentes son extremadamente pequeñas. DB2 también permite que las MQTs sean mantenidas por el usuario (user). En este caso, la actualización de las MQTs viene determinada por procesos explícitamente realizados por los usuarios usando SQL o utilidades. Los siguientes comandos (mandatos en DB2) proporcionan un ejemplo sencillo de mantenimiento diferido de la vista materializada emp_dept después de una operación de carga de una de sus fuentes. load from datosnuevos.txt of type del insert into empleado; refresh table empleado_departamento Elecciones Inmediata Diferida

Figura 28.17

Incremental

Completa

Sí, Normalmente no Después de insert/update/delete Sí, Después de la carga

Opciones para el mantenimiento de MQTs en DB2.

www.detodoprogramacion.com


876

Capítulo 28

DB2 Universal Database de IBM

28.8 Características autónomas de DB2

La versión 8.2 de DB2 UDB proporciona varias características para simplificar el diseño y la administración de bases de datos. La informática autónoma engloba un conjunto de técnicas que permiten a un entorno informático administrarse a sí mismo y reducir dependencias externas frente a cambios en la seguridad externa e interna, carga del sistema u otros factores. La configuración, optimización, protección y supervisión son ejemplos de áreas que se benefician de las mejoras de la computación autónoma. En los siguientes apartados se describen las áreas de configuración y optimización. 28.8.1 Con guración

DB2 proporciona soporte de ajuste automático de diversos parámetros de configuración de memoria

y del sistema. Por ejemplo, los parámetros de tamaño de la memoria intermedia y del montículo de ordenación se pueden especificar como automáticos. En este caso, DB2 supervisa el sistema y aumenta o disminuye lentamente estos tamaños en función de las características de la carga de trabajo. 28.8.2 Optimización

Las estructuras de datos auxiliares (índices, MQTs) y las características de organización de datos (división, agrupación) son aspectos importantes para la mejora del rendimiento de bases de datos en DB2. En el pasado, el administrador de la base de datos (DBA) tenía que basarse en su experiencia y en pautas conocidas para elegir índices, MQTs, claves de división y claves de agrupación significativos. Dado el número potencial de opciones, ni siquiera los más expertos son capaces de encontrar la combinación exacta de estas características para una carga de trabajo dada en un tiempo limitado. La versión 8.2 de DB2 introduce un asesor de diseño (Design Advisor) que proporciona sugerencia para todas estas características. El asesor de diseño analiza automáticamente la carga de trabajo y usa técnicas de optimización para presentar una serie de recomendaciones. La sintaxis del comando del asistente es: db2advis -d <nombre BD> -i <fichero carga de trabajo> -m MICP El parámetro “-m ” permite al usuario especificar las siguientes opciones: • M —Tablas de consultas materializadas • I— Índices • C —Agrupaciones (MDC) • P— Selección de claves de división El asesor utiliza todo el poder del marco de optimización de consultas de DB2 en estas recomendaciones. Usa una carga de trabajo y restricciones de tamaño y tiempo como parámetros de entrada. Al ser la base del marco de optimización de DB2, tiene un conocimiento completo del esquema y las estadísticas de los datos subyacentes. El asesor emplea varias técnicas combinatorias para identificar índices, MQTs, MDCs y claves de división para mejorar el rendimiento de la carga de trabajo dada. Otro aspecto de la optimización es el equilibrado de la carga de procesamiento en el sistema. En particular, las utilidades tienden a aumentar la carga en el sistema y causan la reducción significativa del rendimiento en la carga de trabajo del usuario. Dada la tendencia hacia el empleo de utilidades interactivas, hay una necesidad de equilibrar el consumo de la carga de las utilidades. La versión 8.2 de DB2 introduce un mecanismo de regulación de carga. La técnica de regulación se basa en la teoría de control de realimentación, que ajusta y regula continuamente el funcionamiento de la utilidad de copia de seguridad usando parámetros específicos de control. 28.9 Herramientas y utilidades DB2 proporciona una serie de herramientas para facilitar su uso y administración. Se ha aumentado y

mejorado el núcleo de este conjunto de herramientas mediante con un gran número de herramientas de otros fabricantes.

www.detodoprogramacion.com


28.9

Figura 28.18

Herramientas y utilidades

877

Centro de control de DB2.

El Centro de control de DB2 es la herramienta primaria para el uso y administración de bases de datos DB2. El Centro de control se ejecuta sobre muchas plataformas del tipo estación de trabajo. Está organizado a partir de objetos de datos tales como servidores, bases de datos, tablas e índices. Contiene interfaces orientadas a las tareas para ejecutar comandos y permite a los usuarios generar guiones SQL. La Figura 28.18 es una pantalla del panel principal del Centro de control. Muestra una lista de tablas en la base de datos SAMPLE en la instancia DB2 sobre el nodo PC-FERNAN. El administrador puede utilizar el menú para invocar un conjunto de herramientas componentes. Los componentes principales del Centro de control son el centro de comandos, el centro de guiones, diario, centro de licencias, centro de alertas, supervisor del rendimiento, explicación visual, administración de bases de datos remotas, gestión de almacenamiento y soporte para la réplica. El centro de comandos permite a los usuarios y administradores ejecutar comandos de la base de datos y SQL. El centro de guiones permite a los usuarios ejecutar guiones SQL construidos de forma interactiva o desde un archivo. El supervisor del rendimiento permite al usuario supervisar varios eventos en el sistema de la base de datos y obtener instantáneas del rendimiento. “SmartGuides” proporciona ayuda para la configuración de parámetros del sistema DB2. Un constructor de procedimientos almacenados ayuda al usuario a desarrollar e instalar estos procedimientos. La explicación visual proporciona al usuario vistas gráficas del plan de ejecución de la consulta. Un asistente de índices ayuda al administrador sugiriendo índices de rendimiento. Aunque el Centro de control es una interfaz integrada de muchas de las tareas, DB2 también proporciona acceso directo a la mayoría de las herramientas. Para los usuarios las herramientas tales como el servicio de explicación, las tablas de explicación y la explicación gráfica proporcionan un análisis detallado de los planes de consulta. Los usuarios pueden usar el Centro de control para modificar las estadísticas (si tienen privilegios para ello) con el fin de generar los mejores planes de consulta. 28.9.1 Utilidades

Para los administradores, DB2 proporciona un soporte completo para la carga, importación, exportación, reorganización, redistribución y otras utilidades relacionadas con los datos. En la versión 8 la mayor parte de ellas permiten su ejecución de forma incremental e interactiva. Por ejemplo, se puede ejecutar un comando de carga en modo interactivo para permitir que las aplicaciones accedan a los contenidos

www.detodoprogramacion.com


878

Capítulo 28

DB2 Universal Database de IBM

originales de una tabla de forma concurrente. Las utilidades de DB2 están completamente preparadas para ejecutarse en modo paralelo. Además, DB2 soporta varias herramientas tales como: • Auditoría para el mantenimiento de la traza de auditoría de las acciones sobre la base de datos. • Regulador para controlar la prioridad y tiempos de ejecución en distintas aplicaciones. • Supervisor de consultas para gestionar los trabajos de consulta en el sistema. • Características de traza y diagnóstico para la depuración. • Supervisión de eventos para seguir los recursos y eventos durante la ejecución del sistema. DB2 para OS/390 tiene un gran conjunto de herramientas. QMF es una herramienta ampliamente usada para generar consultas ad hoc e integrarlas en aplicaciones.

28.10 Control de concurrencia y recuperación DB2 soporta un completo conjunto de técnicas de control de concurrencia, aislamiento y recuperación.

28.10.1 Concurrencia y aislamiento

Para el aislamiento DB2 soporta los modos lectura repetible (Repeatable Read, RR), estabilidad en lectura (Read Stability, RS), estabilidad del cursor (Cursor Stability, CS) y lectura no comprometida (Uncommitted Read, UR). Los modos RR, CS y UR no necesitan mayor explicación. El modo de aislamiento RS bloquea solamente las filas que recupera una aplicación en una unidad de trabajo. En una exploración posterior la aplicación tiene garantizado ver todas estas filas (como RR) pero podría no ver nuevas filas que debería ver. Sin embargo esto podría ser un compromiso aceptable para algunas aplicaciones con respecto al aislamiento RR estricto. Normalmente el nivel de aislamiento predeterminado es CS. Las aplicaciones pueden elegir el nivel de aislamiento en la fase de enlace. La mayoría de las aplicaciones comerciales disponibles soportan los distintos niveles de aislamiento y los usuarios pueden elegir la versión correcta de la aplicación para sus requisitos. Los distintos modos de aislamiento se implementan mediante el uso de bloqueos. DB2 soporta bloqueos en el nivel de registros y de tablas. Mantiene una estructura de datos de bloqueo de tablas separado del resto de información de bloqueo. DB2 dimensiona el bloqueo del nivel de registros al de tablas si la tabla de bloqueos se llena. DB2 implementa un bloqueo estricto de dos fases para todas las transacciones de actualización. Mantiene bloqueos de escritura y actualización hasta el momento del compromiso o retroceso. La Figura 28.19 muestra los distintos modos de bloqueo y sus descripciones. Los modos de bloqueo incluyen bloqueos intencionales en el nivel de tabla para maximizar la concurrencia. DB2 también implementa el bloqueo de clave siguiente y variaciones de este esquema para las actualizaciones que afecten a las exploraciones de índices para eliminar el problema de la lectura fantasma y de Halloween. Una transacción puede seleccionar la granularidad de bloqueo en el nivel de tabla usando la instrucción lock table. Esto es útil para aplicaciones que saben que el nivel de aislamiento deseado es de nivel de tabla. Además, DB2 elige la granularidad de bloqueo apropiada para utilidades tales como reorg y load. Las versiones no interactivas de estas utilidades habitualmente bloquean la tabla en modo exclusivo, mientras que las versiones interactivas permiten a otras transacciones acceder concurrentemente realizando bloqueos de fila. Por cada base de datos se activa un agente de detección de interbloqueos que comprueba periódicamente si se producen interbloqueos entre transacciones. El intervalo de detección de interbloqueos es un parámetro configurable. Si se produce un interbloqueo, el agente elige una víctima y aborta su ejecución con un código de error de interbloqueo.

www.detodoprogramacion.com


28.10

Control de concurrencia y recuperación

Modo de bloqueo IN (intent none, sin intención) IS (intent share, intentar compartir) NS (next key share, siguiente clave compartido) S (share, compartido) IX (intent exclusive, intencional exclusivo) SIX (share with intent exclusive, compartido intencional exclusivo) U (Update, actualización)

Objetos Espacios de tablas, tablas Espacios de tablas, tablas

Interpretación Lectura sin bloqueos de filas Lectura con bloqueos de filas

Filas

Bloqueos de lectura para los niveles de aislamiento RS o CS Bloqueo de lectura Intención de actualizar filas

NX (next-key exclusive, siguiente clave exclusivo)

Filas

X (exclusive, exclusivo)

Filas, tablas

Z (superexclusive, superexclusivo)

Espacios de tablas, tablas

Filas, tablas Espacios de tablas, tablas Tablas Filas, tablas

Figura 28.19

879

Sin bloqueos de lectura en las filas pero con bloqueos X en las filas actualizadas Bloqueo de actualización pero permitiendo leer a otros Bloqueo de la siguiente clave para inserciones y borrados para prevenir las lecturas fantasma durante las exploraciones de índice RR Sólo se permiten lectores no comprometidos Acceso completo exclusivo

Modos de bloqueo de DB2.

28.10.2 Compromiso y retroceso

Las aplicaciones pueden comprometerse o retrocederse mediante el uso de las instrucciones explícitas commit y rollback. Las aplicaciones también pueden emitir instrucciones begin transaction y end transaction para controlar el ámbito de las transacciones. No se soportan las transacciones anidadas. Normalmente DB2 libera todos los bloqueos que se mantienen por una transacción en commit o rollback. Sin embargo, si se ha declarado una instrucción de cursor mediante la cláusula with hold entonces se mantienen algunos bloqueos durante los compromisos. 28.10.3 Registro histórico y recuperación

DB2 implementa estrictamente el registro histórico y los esquemas de recuperación ARIES. Emplea el re-

gistro histórico de escritura anticipada para enviar registros del registro histórico al archivo de registro histórico persistente antes de que las páginas de datos se escriban en el compromiso. DB2 soporta dos tipos de modos de registro: registro histórico circular y registro de archivo. En el registro histórico circular, se utiliza un conjunto predefinido de archivos de registro histórico primario y secundario. El registro histórico circular es útil para la recuperación de caídas o la recuperación de un fallo de la aplicación. En el registro histórico de archivo, DB2 crea nuevos archivos de registro histórico y debe guardar los archivos de registro histórico antiguos con el fin liberar espacio en el sistema de archivos. Los registros históricos de archivo son necesarios para la recuperación hacia adelante de una copia de seguridad de archivo. En ambos casos DB2 permite al usuario configurar el número de archivos de registro histórico y los tamaños de los archivos de los registros históricos. En entornos con muchas actualizaciones, DB2 puede configurarse para buscar compromisos en grupo con el fin de acumular las operaciones de escritura de archivo histórico. DB2 soporta retroceso de transacciones y recuperación de caídas, así como recuperaciones por instantes (point-in-time) o hacia adelante (roll-forward). En el caso de una recuperación tras una caída, DB2 ejecuta las fases de deshacer estándar de procesamiento y procesamiento rehacer hasta y desde el último punto de revisión con el fin de recuperar el estado comprometido adecuado de la base de datos. Para la recuperación por instantes, se puede restaurar la base de datos desde una copia de seguridad y avanzar a un punto específico en el tiempo usando los archivos históricos guardados. El comando de recuperación hacia adelante soporta tanto los niveles de bases de datos como de espacios de tablas. También se pueden emitir en nodos específicos sobre un sistema multinodo. Recientemente se ha implementado un esquema de recuperación en paralelo para mejorar el rendimiento en sistemas multiprocesador SMP me-

www.detodoprogramacion.com


880

Capítulo 28

DB2 Universal Database de IBM

diante el uso de muchas CPUs. DB2 ejecuta la recuperación coordinada a través de nodos MPP mediante un esquema global de puntos de revisión. 28.11 Arquitectura del sistema

La Figura 28.20 muestra algunos de los distintos procesos o hebras en un servidor DB2. Las aplicaciones remotas cliente se conectan al servidor de la base de datos empleando agentes de comunicación tales como db2tcpcm. Se asigna un agente a cada aplicación (agente coordinador en entornos MPP o SMP) denominado hebra db2agent. Este agente y sus agentes subordinados ejecutan las tareas relacionadas con la aplicación. Cada base de datos tiene un conjunto de procesos o hebras que ejecutan tareas tales como preextracción, limpieza de páginas de la cola de la memoria intermedia, archivo histórico y detección de interbloqueos. Finalmente, se encuentra disponible un conjunto de agentes en el entorno del servidor para ejecutar tareas tales como detección de caídas, servicios de licencia, creación de procesos y control de recursos del sistema. DB2 proporciona parámetros de configuración para controlar el número de hebras y procesos en un servidor. Casi todos los tipos distintos de agentes se pueden controlar mediante el uso de parámetros de configuración. La Figura 28.21 muestra los distintos tipos de segmentos de memoria en DB2. La memoria privada en los agentes o hebras se utiliza principalmente para variables locales y estructuras de datos que son relevantes solamente para la actividad actual. Por ejemplo, una ordenación privada podría asignar memoria desde el montículo privado del agente. La memoria compartida se divide en memoria compartida del servidor, memoria compartida de la base de datos y memoria compartida de la aplicación. El nivel de la base de datos de memoria compartida contiene estructuras de datos útiles tales como las colas de memoria intermedia, las listas de bloqueos, las cachés de los paquetes de aplicación y las áreas de ordenación compartida. Las áreas de memoria compartida del servidor y de la aplicación se usan principalmente para estructuras de datos y memorias intermedias de comunicaciones. Modelo de procesamiento: partición única

Máquina Máquina cliente Servidora remota Usuario DB2 Procesos Procesos (hebras)

Procesos UDFs db2udfp aislados

EDUs por ejemplar EDUs Por base de por conexión datos activa db2agent db2agntp

Memoria db2agntp Apl A compartida "Conexión y semáforos Apl A SQL a Test" db2agent db2agntp Apl B "Conexión SQL a Test"

db2ipccm Apl B

db2tcpcm

App C "Conexión SQL a Prod"

TCPIP

db2dari Procesos de procedimientos almacenados aislados

db2agntp

db2pclnr

db2cart

db2resyn

db2dart

db2pfchr

db2loggi db2dlock Base de datos "TEST"

Subagente activo db2agent db2agntp

db2pclnr db2pfchr

db2agntp Agente coordinador Subagentes db2loggi db2dlock en espera Apl C Base de datos "PROD"

Figura 28.20

db2wdog db2gds db2sysc

Modelo de procesos en DB2.

www.detodoprogramacion.com

db2agent Agentes en espera sin asociar EDUs por solicitud

db2bm, db2med, ...


28.12

Réplicas, distribución y datos externos

881

Memoria compartida del ejemplar incluye memoria intermedia FCM (Fast Communication Manager) Memoria compartida de la base de datos

Memoria compartida de la base de datos

colas de memoria intermedia (buffpage o ALTERBUF..) lista de bloqueos (locklist) caché de paquetes (pakcachesz) ordenaciones compartidas (sortheap, sheapthresh) montículo de la base de datos (dbheap) memoria intermedia del registro histórico (logbufsz) 1...númbd caché del catálogo (catalogcache_sz) montículo de utilidades (util_heap_sz)

1...máxapls

1...máxagentes

Figura 28.21

Memoria compartida de la aplicación estructuras internas (appl_ctl_heap_sz) Memoria privada de agentes ordenaciones privadas (sortheap, sheapthresh) montículo de aplicaciones (applheapsz) pila de agentes (agent_stack_sz) montículo de consultas (query_heap_sz) montínculo de instrucciones (stmtheap) montículo de estadísticas (stat_heap_sz)

Modelo de memoria DB2.

DB2 soporta varias colas de memoria intermedia para una base de datos. Las colas de memoria intermedia se pueden crear mediante el uso de la instrucción create bufferpool y se puede asociar con espacios de tablas. Es útil disponer de varias colas de memoria intermedia por diversas razones, pero se deberían definir después de un cuidadoso análisis de los requisitos de la carga de trabajo. DB2 soporta una completa lista de configuración de memoria y parámetros de ajuste. Esto incluye parámetros para todas las áreas de montículos de estructuras de datos grandes tales como las colas de memoria intermedia predeterminadas, el montículo de ordenación, la caché de paquetes, los montículos de control de la aplicación y el área de lista de bloqueos.

28.12 Réplicas, distribución y datos externos

La réplica de DB2 (DB2 Replication) es un producto en la familia DB2 que proporciona réplica de datos entre DB2 y otros sistemas de bases de datos relacionales tales como Oracle, SQL Server de Microsoft, SQL Server de Sybase e Informix, y orígenes de datos no relacionales tales como IMS de IBM. Consiste en componentes capturar y aplicar que se controlan mediante interfaces de administración. Los mecanismos de captura de cambios se basan en tablas DB2 basadas en registros históricos o “basadas en disparadores” en el caso de otros orígenes de datos. Los cambios capturados se almacenan en áreas temporales de tablas bajo el control de DB2 Replication. Estas tablas intermedias con cambios se aplican después a las tablas destino mediante el uso de instrucciones SQL normales: inserciones, actualizaciones y borrados. Las transformaciones basadas en SQL se pueden ejecutar sobre estas tablas intermedias usando condiciones de filtro además de agregaciones. Las filas resultantes se pueden aplicar a una o más tablas destino. Los medios de administración controlan todas estas acciones. La versión 8.2 de DB2 soporta una nueva característica denominada réplica de colas (queue replication). La réplica de colas (Q) crea un mecanismo de transporte de colas usando el producto de IBM de colas de mensajes para enviar registros de archivo históricos como mensajes. Estos mensajes se extraen de las colas en el receptor y se aplican a los destinos. El proceso de aplicación se puede paralelizar y tiene en cuenta las reglas de resolución de conflictos especificadas por el usuario. Otro miembro de la familia DB2 es el producto integrador de información, que proporciona soporte para federación, réplica (usando el motor de réplica descrito anteriormente) y búsqueda. La edición federada integra tablas en bases de datos DB2 remotas u otras bases de datos relacionales en una única base de datos distribuida. Los usuarios y desarrolladores pueden acceder a diversas fuentes de datos

www.detodoprogramacion.com


882

Capítulo 28

DB2 Universal Database de IBM

no relacionales en formato tabular usando envolturas. El motor de la edición federada proporciona un método basado en el coste para la optimización de consultas entre los distintos sitios de datos. DB2 soporta funciones de tabla definidas por el usuario que pueden permitir el acceso de orígenes de datos no relacionales y externos. Se pueden crear funciones de tabla definidas por el usuario mediante la instrucción create function con la cláusula returns table. Con estas características DB2 puede participar en los protocolos OLE-DB. Finalmente DB2 proporciona soporte completo para procesamiento de transacciones distribuidas mediante el protocolo de compromiso en dos fases. DB2 puede actuar como el coordinador o agente para el soporte XA distribuido. Como coordinador, DB2 puede ejecutar todos los estados del protocolo de compromiso en dos fases. Como participante, DB2 puede interactuar con cualquiera de los administradores de transacciones distribuidas comerciales. 28.13 Características de inteligencia de negocio DB2 Data Warehouse Edition es un producto de la familia DB2 que incorpora características de inteligencia de negocio. Esta edición tiene como base el motor de DB2, y lo mejora con características para ETL, OLAP, minería y generación interactiva de informes. El motor de DB2 proporciona dimensionabilidad mediante sus características MPP. En el modo MPP, DB2 puede soportar configuraciones dimensionables

a varios cientos de nodos para bases de datos de gran tamaño (terabytes). Adicionalmente, las características como MDC y MQT proporcionan soporte para los requisitos de procesamiento de consultas complejas de la inteligencia de negocio. Otro aspecto de la inteligencia de negocio es el procesamiento analítico interactivo (On-Line Analytical Processing, OLAP). La familia DB2 incluye un componente denominado vista de cubos que proporciona un mecanismo para construir estructuras de datos apropiadas para MQTs dentro de DB2 que se puedan usar para procesamiento OLAP relacional. La vista de cubos porporciona soporte para el modelado de cubos multidimensionales y proporciona un mecanismo de correspondencia con un esquema relacional en estrella. Este modelo se usa para recomendar los MQTs, índices y definiciones MDC apropiados para mejorar el rendimiento de consultas OLAP sobre la base de datos. Además, las vistas de cubos pueden aprovechar el soporte nativo en DB2 para las operaciones cube by y rollup para la generación de cubos agregados. La vista de cubos es una herramienta que se puede usar para integrar estrechamente DB2 con distribuidores de productos OLAP como Business Objects, Microstrategy y Cognos. Además, DB2 también proporciona soporte multidimensional OLAP usando el servidor OLAP de DB2. Este servidor puede crear un almacén de datos (data mart) desde una base de datos DB2 para realizar análisis usando técnicas OLAP. El servidor OLAP de DB2 usa el motor OLAP del producto Essbase. DB2 Alphablox es una nueva característica que permite crear informes y realizar análisis interactivamente. Un aspecto muy atractivo de Alphablox es la posibilidad de construir rápidamente formularios de análisis basados en Web usando un enfoque basado en bloques constructivos denominados blox. Para análisis avanzados, DB2 Intelligent Miner proporciona diversos componentes para modelar, puntuar (scoring) y visualizar datos. La minería de datos permite a los usuarios realizar clasificaciones, predicciones, agrupaciones, segmentaciones y asociaciones en grandes conjuntos de datos. Notas bibliográ cas

El origen de DB2 se remonta al proyecto del Sistema R (Chamberlin et al. [1981]). Las contribuciones de investigación de IBM incluyen áreas tales como procesamiento de transacciones (archivo histórico con escritura anticipada y algoritmos de recuperación ARIES) (Mohan et al. [1992]), procesamiento y optimización de consultas (Starburst) (Haas et al. [1990]), procesamiento paralelo (DB2 Parallel Edition) (Baru et al. [1995]), soporte para bases de datos activas (restricciones, disparadores) (Cochrane et al. [1996]), técnicas avanzadas de consultas y gestión de almacenes de datos tales como vistas materializadas (Zaharioudakis et al. [2000], Lehner et al. [2000]), agrupaciones multidimensionales (Padmanabhan et al. [2003], Bhattacharjee et al. [2003]), características autónomas (Zilio et al. [2004]) y soporte del modelo relacional orientado a objetos (ADTs, UDFs) (Carey et al. [1999]). Se pueden encontrar detalles sobre el procesamiento de consultas en multiprocesadores en Baru et al. [1995] o en las guías de administración y rendimiento de la documentación en línea de DB2 DB2 Online documentation.

www.detodoprogramacion.com


Notas bibliográficas

883

A continuación se detalla una lista de material de referencia sobre DB2. Los libros de Don Chamberlin proporcionan una buena revisión de y las características de SQL y programación de DB2 (Chamberlin [1996], Chamberlin [1998]). Los primeros libros de C. J. Date y otros proporcionan un buen repaso de las características de DB2 para OS/390 (Date [1989], Martin et al. [1989]). Los manuales de DB2 proporcionan revisiones definitivas de cada versión particular de DB2. La mayoría de estos manuales están disponibles en línea (Documentación en línea de DB2 DB2 Online documentation ). Libros recientes como DB2 for Dummies (Zikopoulos et al. [2000]), DB2 SQL developer’s guide (Sanders [2000]) y DB2 Administration Certification Guides (Cook et al. [1999]) proporcionan formación práctica para usar y administrar DB2. Finalmente, Prentice Hall está publicando una serie de completa de libros sobre el enriquecimiento y certificación sobre varios aspectos de DB2. Chamberlin [1998], Zikopoulos et al. [2004] y la biblioteca de documentación de DB2 proporcionan una descripción completa del soporte de SQL.

www.detodoprogramacion.com


www.detodoprogramacion.com


C

A

P

Í

T

U

L

O

29

SQL Server de Microsoft Sameet Agarwal, José A. Blakeley, Thierry D'Hers, Gerald Hinson, Dirk Myers, Vaqar Pirzada, Bill Ramos, Balaji Rathakrishnan, Michael Rys, Florian Waas, Michael Zwilling Microsoft

SQL Server de Microsoft es un sistema de gestión de bases de datos relacionales que se puede instalar

tanto en computadoras portátiles y de sobremesa como en servidores corporativos y en dispositivos de bolsillo, como los PocketPC y los lectores de códigos de barras, con una versión basada en el sistema operativo PocketPC. SQL Server se desarrolló originalmente en los años ochenta del siglo veinte en SyBase para sistemas UNIX y posteriormente Microsoft lo tradujo a sistemas Windows NT. Desde 1994 Microsoft ha distribuido versiones de SQL Server desarrolladas independientemente de Sybase, que dejó de usar el nombre SQL Server a finales de los años noventa. La última versión, SQL Server 2005, está disponible en las ediciones exprés (Express), estándar (Standard) y corporativa (Enterprise), y se ha traducido a muchos idiomas de todo el mundo. En este capítulo el término SQL Server se refiere a todas estas ediciones de SQL Server 2005. SQL Server proporciona servicios de duplicación (réplica) entre varias copias de SQL Server y con otros sistemas de bases de datos. Su componente Analysis Services (servicios de análisis), una parte esencial del sistema, incluye servicios de procesamiento analítico en línea (OLAP, Online Analytical Processing) y de minería de datos. SQL Server proporciona una gran colección de herramientas gráficas y de “asistentes” que guían a los administradores de las bases de datos en tareas como la configuración de copias de seguridad periódicas, la duplicación de datos entre los distintos servidores y el ajuste del rendimiento de las bases de datos. Muchos entornos de desarrollo soportan SQL Server, incluidos Visual Studio de Microsoft y los productos relacionados, en especial los productos y servicios .NET.

29.1 Herramientas para la administración, el diseño y la consulta de las bases de datos SQL Server proporciona un conjunto de herramientas para gestionar todos los aspectos del desarrollo, la consulta, el ajuste, la prueba y la administración de SQL Server. La mayor parte de estas herramientas giran alrededor de Management Studio (conocido formalmente como Enterprise Manager) de SQL Server. Management Studio ofrece una interfaz de comandos común para la administración de todos los servicios asociados con SQL Server, que incluye el motor de la base de datos (Database Engine), los

servicios de análisis (Analysis Services), los servicios de informes (Reporting Services), el servidor móvil de SQL Server (SQL Server Mobile) y los servicios de integración (Integration Services). 885

www.detodoprogramacion.com


886

Capítulo 29

SQL Server de Microsoft

Figura 29.1

View Designer abierto para la vista HumanResources.vEmployee.

29.1.1 Desarrollo de bases de datos y herramientas visuales para las bases de datos

Al diseñar una base de datos, el administrador de la base de datos crea objetos de la base de datos como las tablas, las columnas, las claves, los índices, las relaciones, las restricciones y las vistas. Management Studio de SQL Server proporciona acceso a herramientas visuales para la creación de estos objetos en las bases de datos. Estas herramientas proporcionan tres mecanismos de ayuda al diseño de las bases de datos: Database Designer (diseñador de bases de datos), Table Designer (diseñador de tablas) y View Designer (diseñador de vistas). Database Designer es una herramienta visual que permite al propietario de la base de datos y a sus delegados crear tablas, columnas, claves, índices, relaciones y restricciones. En esta herramienta el usuario puede interactuar con los objetos de la base de datos mediante los diagramas de la base de datos, que muestran de forma gráfica la estructura de la base de datos. View Designer proporciona una herramienta visual de consulta que permite al usuario crear y modificar vistas de SQL mediante el uso de las posibilidades de arrastrar y soltar de Windows. La Figura 29.1 muestra una vista abierta desde Management Studio. 29.1.2 Herramientas para la consulta y el ajuste de las bases de datos

Management Studio de SQL Server proporciona varias herramientas de ayuda al proceso de desarrollo de las aplicaciones. Se pueden desarrollar y probar inicialmente las consultas y los procedimientos almacenados mediante Query Editor (editor de consultas) integrado que sustituye al Analizador de

www.detodoprogramacion.com


29.1

Figura 29.2

Herramientas para la administración, el diseño y la consulta de las bases de datos

887

Plan de ejecución de una reunión de cuatro tablas con la agregación group by.

consultas de SQL Server. Query Editor soporta la creación y edición de guiones para T-SQL, SQLCMD, MDX, DMX, XMLA y SQL Server Mobile. Se pueden realizar más análisis usando ServerProfiler de SQL. Las recomendaciones de ajuste de las bases de datos las proporciona una tercera herramienta: Database Tuning Advisor. 29.1.2.1 Query Editor

Query Editor proporciona una interfaz de usuario gráfica sencilla para la ejecución de consultas de SQL y el examen de sus resultados. Query Editor proporciona también una representación gráfica de showplan, los pasos elegidos por el optimizador para la ejecución de cada consulta. Query Editor está integrado con Object Explorer de Management Studio, que permite que el usuario arrastre objetos o tablas a las ventanas de las consultas y ayuda a crear instrucciones select, insert, update y delete para cualquier tabla. El administrador o desarrollador de la base de datos puede usar Query Editor para: • Analizar consultas: Query Editor puede mostrar el plan de ejecución en formato gráfico o de texto de cualquier consulta, así como mostrar las estadísticas relativas al tiempo y a los recursos necesarios para su ejecución. • Dar formato a las consultas de SQL: incluido el sangrado y la codificación sintáctica por colores. • Usar plantillas para los procedimientos almacenados, las funciones y las instrucciones básicas de SQL: Management Studio trae docenas de plantillas predefinidas para la creación de instrucciones de LDD, y los usuarios también pueden definir las suyas propias. La Figura 29.2 muestra Management Studio y Query Editor con el plan gráfico de ejecución de una consulta que supone una reunión de cuatro tablas y una agregación.

www.detodoprogramacion.com


888

Capítulo 29

SQL Server de Microsoft

29.1.2.2 SQL Pro ler

SQL Profiler es una utilidad gráfica que permite a los administradores de bases de datos supervisar y registrar la actividad de Database Engine y de Analysis Services de SQL Server. Puede mostrar toda la

actividad del servidor en tiempo real o crear filtros que se centren en las acciones de usuarios, aplicaciones o tipos de comandos concretos. También permite mostrar cualquier instrucción o procedimiento almacenado de SQL enviado a cualquier ejemplar de SQL Server (si los privilegios de seguridad lo permiten), así como los datos de rendimiento que indican el tiempo que la consulta ha tardado en ejecutarse, la cantidad de CPU y de E/S necesarias y el plan de ejecución usado. SQL Profiler permite ahondar aún más en SQL Server para supervisar automáticamente cada instrucción ejecutada como parte de un procedimiento almacenado, cada operación de modificación de los datos, cada bloqueo adquirido o liberado, o cada ocasión en que crece un archivo de la base de datos. Se pueden capturar docenas de eventos distintos y, para cada evento, se pueden capturar docenas de elementos de datos. SQL Server divide realmente la funcionalidad de seguimiento en dos componentes diferentes, aunque conectados. SQL Profiler es el servicio de traza en los clientes. Mediante SQL Profiler los usuarios pueden decidir guardar los datos capturados en un archivo o en una tabla, además de mostrarlos en la interfaz de usuario (UI) de Profiler. Esta herramienta muestra todos los eventos que cumplen el criterio del filtro en el momento en que se producen. Una vez que se han guardado los datos de la traza, SQL Profiler puede leer los datos guardados para mostrarlos o analizarlos. En el lado del servidor está el servicio de traza de SQL, que gestiona las colas de los eventos generados por los productores de eventos. Una hebra (subproceso en DB2) consumidora lee los eventos desde las colas y los filtra antes de enviarlos al proceso que los ha solicitado. Los eventos son la unidad principal de actividad en lo que se refiere a la traza, y un evento puede ser cualquier cosa que suceda dentro de SQL Server o entre SQL Server y un cliente. Por ejemplo, la creación o eliminación de un objeto, la ejecución de un procedimiento almacenado, la adquisición o liberación de un bloqueo y el envío de un archivo de procesamiento por lotes de Transact-SQL desde un cliente a SQL Server son eventos. Hay un conjunto de procedimientos almacenados del sistema para definir los eventos que hay que seguir, los datos de cada evento que son interesantes y el lugar en el que se debe guardar la información recogida de los eventos. Los filtros aplicados a los eventos pueden reducir la cantidad de información recogida y almacenada. SQL Server garantiza que se recoja siempre cierta información crítica, y se puede usar como un útil mecanismo de auditoría. SQL Server está certificado para el nivel C2 de seguridad y muchos de los eventos de los que se puede realizar una traza sólo están disponibles para cumplir los requisitos de la certificación C2. 29.1.2.3 Database Tuning Advisor

Las consultas y las actualizaciones se pueden ejecutar mucho más rápido si se dispone de un conjunto de índices adecuado. El diseño de los mejores índices posibles para las tablas de una base de datos de gran tamaño es una tarea compleja: no sólo exige un conocimiento completo del modo en que SQL Server usa los índices y de la manera en que el optimizador de consultas toma las decisiones, sino del modo en que las aplicaciones y las consultas interactivas usan realmente los datos. Database Tuning Advisor (DTA) de SQL Server (que sustituye al Asistente para optimización de índices de SQL Server 2000) es una potente herramienta para el diseño de los mejores índices y de las mejores vistas indexadas (materializadas) posibles, de acuerdo con las cargas de trabajo observadas de consultas y de actualizaciones. DTA puede ajustar varias bases de datos a la vez y basa sus recomendaciones en una carga de trabajo que puede ser un archivo de eventos de traza capturados, un archivo con instrucciones de SQL o un archivo de datos de XML. SQL Profiler está diseñado para capturar todas las instrucciones de SQL remitidas por todos los usuarios en un periodo de tiempo determinado. DTA puede examinar luego los patrones de acceso a los datos de todos los usuarios, las aplicaciones y las tablas, y realizar recomendaciones equilibradas. 29.1.3 Management Studio de SQL Server

Además de proporcionar acceso a las herramientas de diseño de bases de datos y a las herramientas visuales para bases de datos, Management Studio de SQL Server, fácil de usar, soporta la administración

www.detodoprogramacion.com


29.2

Figura 29.3

Variaciones y extensiones de SQL

889

La interfaz de Management Studio de SQL Server.

centralizada de todos los aspectos de varias instalaciones de Database Engine, Analysis Services, Reporting Services, Integration Services y SQL Server Mobile, incluidos la seguridad, los eventos, las alertas, la programación, las copias de seguridad, la configuración del servidor, los ajustes, la búsqueda de texto completo y la duplicación. Management Studio de SQL Server permite que el administrador de la base de datos cree, modifique y copie los esquemas y los objetos de las base de datos de SQL Server como las tablas, las vistas y los desencadenadores. Debido a que se puede organizar en grupos varias instalaciones de SQL Server y tratarlas como una unidad, Management Studio de SQL Server puede gestionar cientos de servidores de manera simultánea. Aunque se puede ejecutar en la misma computadora que el motor de SQL Server, Management Studio de SQL Server ofrece las mismas posibilidades de gestión cuando se ejecuta en cualquier máquina de Windows 2000 (o posterior). Además, la arquitectura eficiente cliente–servidor de SQL Server hace práctico el uso de las posibilidades de acceso remoto (acceso telefónico a redes) de Windows para la administración y la gestión. Management Studio de SQL Server libera al administrador de la base de datos de tener que conocer los pasos y la sintaxis concretos necesarios para completar cada trabajo. Ofrece asistentes que guían a los administradores de bases de datos en el proceso de configuración y mantenimiento de las instalaciones de SQL Server. La interfaz de Management Studio se muestra en la Figura 29.3 e ilustra la manera en que se puede crear de manera directa un guión para las copias de seguridad de las bases de datos a partir de los cuadros de diálogo. 29.2 Variaciones y extensiones de SQL SQL Server permite a los desarrolladores de aplicaciones escribir la lógica corporativa del lado del servidor usando Transact-SQL o algún lenguaje de programación .NET, como C#, Visual Basic, COBOL o J++. Transact-SQL es un lenguaje de programación de bases de datos completo que incluye instrucciones para

la definición y la manipulación de los datos, instrucciones iterativas y condicionales, variables, procedimientos y funciones. Transact-SQL soporta la mayor parte de las instrucciones y estructuras de consulta y de modificación de datos del LDD obligatorias de la norma SQL-2003. Véase el Apartado 29.2.1 para

www.detodoprogramacion.com


890

Capítulo 29

SQL Server de Microsoft

conocer la lista de tipos de datos de SQL-2003 soportados. Además de las características obligatorias, Transact-SQL también soporta muchas características opcionales de la norma de SQL-2003, como las consultas recursivas, las expresiones comunes de las tablas, las funciones definidas por los usuarios y los operadores relacionales como intersect y except, entre otros.

29.2.1 Tipos de datos

SQL Server soporta todos los tipos de datos escalares obligatorios de la norma de SQL-2003, excepto el de fecha (date) y el de hora (time). Soporta el tipo de datos de marca de tiempo (timestamp, también denominado datetime), que permite guardar los componentes de fecha y de hora. SQL Server también soporta la posibilidad de dar otros nombres a los tipos del sistema usando nombres facilitados por los usuarios; el uso de alias es parecido en funcionalidad a los diferentes tipos de SQL-2003, pero no cumple completamente con ellos. Entre los tipos primitivos exclusivos de SQL Server se encuentran:

• Los tipos de cadenas de caracteres y binarias de gran tamaño de tamaño variable hasta los 231 − 1 bytes (text/ntext/image, varchar/nvarchar/varbinary(max)). Los tipos de datos text/ntext/image exigen el uso de un textptr especializado que actúe de manejador o un puntero a los valores LOB. Los tipos de datos varchar/nvarchar/varibinary(max) tienen la misma capacidad de bytes que text/ntext/image, pero el modelo de programación es parecido al de los tipos small character y byte string. • El tipo XML, descrito en el Apartado 29.11, se usa para guardar datos de XML en las columnas de las tablas. El tipo XML puede tener, opcionalmente, una colección de esquemas de XML asociado que especifique la restricción de que los ejemplares de este tipo deben adherirse a uno de los tipos de XML definidos en la colección de esquemas. • sql_variant es un tipo de datos escalares que puede contener valores de cualquier tipo escalar de SQL (excepto los tipos large character, large binary y sql_variant). Este tipo lo usan las aplicaciones que necesitan guardar datos cuyo tipo no se puede anticipar en el momento de definición de los datos. sql_variant también es el tipo de las columnas formadas a partir de la ejecución del operador relacional unpivot (véase el Apartado 29.2.2). Internamente, el sistema realiza un seguimiento del tipo original de los datos. Es posible filtar, reunir y ordenar las columnas sql_variant. La función del sistema sql_variant_property devuelve los detalles de los datos reales guardados en las columnas de tipo sql_variant, incluida la información sobre el tipo básico y sobre el tamaño. Además, SQL Server soporta los tipos el tipo table y el tipo cursor, que no se pueden usar como columnas de las tablas, pero se pueden usar como variables del lenguaje Transact-SQL: • El tipo table permite que una variable guarde un conjunto de filas. Los ejemplares de este tipo se usan, sobre todo, para guardar los resultados temporales de los procedimientos almacenados o como valor devuelto por funciones cuyo resultado es una tabla. Las variables table se comportan como variables locales. Tienen un ámbito bien definido, que es la función, el procedimiento almacenado o el procesamiento por lotes en que se declaran. Dentro de su ámbito las variables table se pueden utilizar como las tablas normales. Se pueden aplicar en cualquier lugar en que se utilicen tablas o expresiones de tabla en las instrucciones select, insert, update o delete. • El tipo cursor permite las referencias a objetos cursor. El tipo cursor puede usarse para declarar variables, o argumentos de entrada/salida de las rutinas, para hacer referencia a cursores de unas llamadas a rutinas a otras.

www.detodoprogramacion.com


29.2

Variaciones y extensiones de SQL

891

29.2.2 Mejoras del lenguaje de consultas

Además de los operadores relacionales de SQL como la reunión interna y la reunión externa, SQL Server soporta los operadores relacionales pivot, unpivot y apply. • pivot es un operador que transforma su conjunto de resultados de entrada con dos columnas, que representan pares nombre-valor, en varias columnas, una por cada nombre de la entrada. La columna de nombres de la entrada se denomina columna pivote. El usuario debe indicar los nombres que hay que trasponer de la entrada a las diferentes columnas de la salida. Considérese la tabla VentasMensuales (IDProducto, Mes, CantidadVentas). La consulta siguiente, que usa el operador pivot, devuelve la CantidadVentas de los meses de enero, febrero y marzo como columnas diferentes. Téngase en cuenta que el operador pivot también lleva a cabo una agregación implícita de todas las otras columnas de la tabla y una agregación explícita de la columna pivote. select * from VentasMensuales pivot( sum(CantidadVentas) for mes in (’Ene’, ’Feb’, ’Mar’)) T La operación inversa a pivot es unpivot. • El operador apply es un operador binario que toma dos entradas valoradas como tablas, de las que la parte derecha suele ser la llamada a una función que devuelve una tabla que toma como argumentos una o varias columnas de la parte izquierda. Las columnas generadas por este operador son la unión de las columnas de sus dos entradas. El operador apply se puede usar para valorar su entrada derecha para cada fila de su entrada izquierda y llevar a cabo una union all de las filas a lo largo de todas estas evaluaciones. Hay dos variedades del operador apply parecidas a las de join, es decir, cross y outer. Las dos variedades se diferencian en lo relativo al manejo el caso de que la entrada derecha produzca un conjunto de resultados vacío. En el caso de cross apply, hace que la fila correspondiente de la entrada izquierda no aparezca en el resultado. En el caso de outer apply, la fila de la entrada izquierda aparece con valores NULL para las columnas de la entrad derecha. Considérese una función que se valora como tabla denominada HallarInformes, que toma como entrada el ID de un empleado dado y devuelve el conjunto de empleados de la organización que informa directa o indirectamente a ese empleado. La consulta siguiente llama a esta función para el Jefe de cada departamento desde la tabla Departamentos: select * from Departmentos D cross apply HallarInformes(D.IDJefe)

29.2.3 Rutinas

Los usuarios pueden escribir rutinas que se ejecuten dentro del proceso servidor como funciones escalares o tabulares, como procedimientos almacenados o como disparadores usando Transact-SQL o algún lenguaje .NET. Todas estas rutinas se definen para la base de datos mediante la instrucción create [function, procedure, trigger] del LDD. Las funciones escalares se pueden usar en cualquier expresión escalar de las instrucciones LMD o LDD de SQL. Las funciones que devuelven tablas se pueden usar en cualquier parte en que se permitan tablas en las instrucciones select. Las funciones que devuelven tablas de Transact-SQL cuyo cuerpo contiene una sola instrucción select de SQL se tratan como vistas (expandidas en línea) en la consulta que hace referencia a la función. Dado que las funciones que devuelven tablas permiten argumentos de entrada, las funciones en línea valoradas como tablas se pueden considerar vistas parametrizadas. 29.2.3.1 Vistas indexadas

Además de las vistas tradicionales definidas en la norma ANSI de SQL, SQL Server soporta las vistas indexadas (materializadas). Las vistas indexadas pueden mejorar sustancialmente el rendimiento de las consultas complejas de ayuda a la toma de decisiones que recuperan gran número de filas y agregan grandes cantidades de información en sumas, recuentos y medias. SQL Server soporta la creación de

www.detodoprogramacion.com


892

Capítulo 29

SQL Server de Microsoft

índices agrupados en cada vista y, en consecuencia, cualquier número de índices no agrupados. Una vez indexada una vista, el optimizador puede usar sus índices en consultas que hagan referencia a la vista o a sus tablas base. Las consultas ya existentes se pueden beneficiar de la eficiencia mejorada de recuperar los datos directamente de la vista indexada sin que haga falta reescribirlas para que hagan referencia a la vista. Las instrucciones de actualización de las tablas base de la vista se propagan automáticamente a las vistas indexadas. 29.2.3.2 Vistas actualizables y disparadores

Generalmente, las vistas puede ser objetivo de las instrucciones update, delete o insert si la modificación de los datos sólo se aplica a una de las tablas base de la vista. Las actualizaciones de las vistas divididas se pueden propagar a varias tablas base. Por ejemplo, la siguiente instrucción update incrementa los precios para el editor “0736” en un diez por ciento. update vistatítulos set precio = precio * 1.10 where id_editorial = ’0736’ Para las modificaciones de los datos que afectan a más de una tabla base, la vista se puede actualizar si hay algún disparador instead definido para la operación: los disparadores instead para las operaciones insert, update o delete se pueden definir sobre una vista para especificar las actualizaciones que hay que ejecutar en las tablas base para implementar las modificaciones de la vista correspondientes. Los disparadores son procedimientos de Transact-SQL o de .NET que se ejecutan automáticamente cuando se envía una instrucción de LMD (update, insert o delete) a una tabla base o a una vista. Los disparadores son mecanismos que posibilitan la aplicación de la lógica corporativa de forma automática al modificar los datos o al ejecutar instrucciones de LDD. Los disparadores pueden extender la lógica de comprobación de la integridad de las restricciones declarativas, de las predeterminadas y de las reglas, aunque las restricciones declarativas se deben usar preferentemente siempre que sean suficientes. Los disparadores se pueden clasificar en LMD y en LDD, según el tipo de evento que los desencadene. Los disparadores LMD se definen contra tablas o vistas que se están modificando. Los disparadores LDD se definen contra bases de datos completas para una o varias instrucciones de LDD, como create table, drop procedure, etc. Los disparadores se pueden clasificar en disparadores after e instead, según el momento en que se los invoca en relación con la acción que los desencadena. Los desencadenadores after se ejecutan después de la instrucción de disparo y luego se aplican restricciones declarativas. Los disparadores instead se ejecutan en lugar de la acción que los dispara. Se puede considerar que los disparadores instead son parecidos a los disparadores before, pero sustituyen realmente a la acción de disparo. En SQL Server, los disparadores after de LMD sólo se pueden definir sobre las tablas base, mientras que los disparadores instead de LMD se pueden definir sobre las tablas base o sobre las vistas. Los disparadores instead permiten hacer actualizable prácticamente cualquier vista. Los disparadores instead LDD se pueden definir sobre cualquier instrucción del LDD.

29.3 Almacenamiento e índices

En SQL Server cada base de datos hace referencia a un conjunto de archivos que contienen datos y están soportados por un único registro histórico de transacciones. La base de datos es la unidad principal de administración de SQL Server, y también proporciona un contenedor para estructuras físicas como las tablas y los índices y para estructuras lógicas como las restricciones, las vistas, etc. 29.3.1 Grupos de archivos

Con el fin de gestionar el espacio de la base de datos de forma efectiva, el conjunto de archivos de datos de la base de datos se divide en grupos denominados grupos de archivos. Cada grupo de archivos contiene uno o más archivos del sistema operativo.

www.detodoprogramacion.com


29.3

Almacenamiento e índices

893

Cada base de datos tiene, al menos, un grupo de archivos conocido como grupo de archivos principal. Este grupo de archivos contiene todos los metadatos de la base de datos en tablas del sistema. El grupo de archivos principal también puede contener datos de usuario. Si se crean grupos de archivos definidos por el usuario adicionales, los usuarios pueden controlar de forma explícita la ubicación de cada tabla, de cada índice o de cada columna de objetos de gran tamaño de las tablas colocándolas en un grupo de archivos. Por ejemplo, el usuario puede decidir guardar una tabla en el grupo de archivos A, su índice no agrupado en el grupo de archivos B y las columnas de objetos de gran tamaño de la tabla en el grupo de archivos C. La ubicación de estas tablas y de estos índices en grupos de archivos diferentes permite al usuario controlar el uso de los recursos de hardware (esto es, de los discos y del subsistema de E/S). Siempre se considera a un grupo de archivos determinado el grupo de archivos predeterminado; inicialmente, el grupo de archivos predeterminado es el grupo de archivos principal, pero se puede otorgar la propiedad predeterminado a cualquier grupo de archivos definido por los usuarios. Si una tabla o índice no se ubica específicamente en un grupo de archivos, se crea en el grupo de archivos predeterminado.

29.3.2 Gestión del espacio en los grupos de archivos

Uno de los principales propósitos de los grupos de archivos es permitir una gestión efectiva del espacio. Todos los archivos de datos se dividen en unidades de tamaño fijo de ocho kilobytes denominadas páginas. El sistema de asignación es responsable de asignar esas páginas a las tablas y a los índices. El objetivo del sistema de asignación es minimizar la cantidad de espacio desperdiciado y, al tiempo, mantener el grado de fragmentación de la base de datos al mínimo para garantizar un buen rendimiento de exploración. Con el fin de lograr este objetivo, el administrador de asignación suele asignar y extraer todas las páginas en grupos de ocho páginas contiguas denominadas extensiones. El sistema de asignación gestiona estas extensiones mediante varios mapas de bits. Estos mapas de bits permiten al sistema de asignación encontrar una página o una extensión para asignarla de forma rápida. Estos mapas de bits también se usan cuando se ejecuta una exploración de tabla completa o de índices. La ventaja de usar mapas de bits basados en la asignación para la exploración es que permite recorrer en el orden del disco todas las extensiones que pertenecen al nivel de hojas de la tabla o del índice, lo que mejora significativamente el rendimiento de la exploración. Si hay más de un archivo en un grupo de archivos, el sistema de asignación asigna extensiones para cualquier objeto de ese grupo de archivos mediante un algoritmo de “relleno proporcional”. Cada archivo se rellena en proporción a la cantidad de espacio libre de ese archivo en comparación con los demás archivos. Esto rellena todos los archivos del grupo de archivos aproximadamente al mismo ritmo, y permite al sistema usar por igual todos los archivos del grupo de archivos. Una de las decisiones más importantes al configurar una base de datos es la determinación del tamaño que se desea que tenga. SQL Server permite que los archivos de datos cambien de tamaño después de la creación de la base de datos. El usuario puede, incluso, decidir que el archivo de datos crezca automáticamente si la base de datos se está quedando sin espacio. Por ello, el usuario puede configurar la base de datos con una aproximación razonable de su tamaño esperado y dejar que los archivos de la base de datos crezcan y se ajusten al patrón de uso, si la aproximación inicial es errónea. SQL Server permite que los archivos disminuyan de tamaño. Para disminuir el tamaño de un archivo de datos SQL Server traslada todos los datos desde el extremo físico del archivo a un punto más cercano al inicio del archivo y luego reduce realmente su tamaño, devolviendo el espacio liberado al sistema operativo.

29.3.3 Tablas

SQL Server soporta las organizaciones de las tablas en montones (o montículos—heap) y en agrupacio-

nes (clusters). En las tablas organizadas en montones la ubicación de cada fila de la tabla la determina completamente el sistema y el usuario no la especifica en absoluto. Las filas de los montones tienen un identificador fijo conocido como identificador de la fila (RID, Row Identifier), y su valor no cambia nunca, a no ser que se reduzca el tamaño del archivo y la fila se traslade. Si la fila se hace tan grande que no cabe en la página en la que se insertó originalmente, el registro se traslada a un lugar distinto,

www.detodoprogramacion.com


894

Capítulo 29

SQL Server de Microsoft

pero se deja un resguardo de entrega en la ubicación original, de modo que el registro todavía se pueda encontrar usando su RID original. En la organización de índices agrupados de las tablas, las filas de la tabla se guardan en un árbol B+ ordenado por la clave de agrupamiento del índice. La clave del índice agrupado también sirve como identificador único de cada fila. La clave del índice agrupado se puede definir como no única, en cuyo caso SQL Server agrega una columna oculta adicional para hacer que la clave sea única. El índice agrupado también sirve como estructura de búsqueda para identificar una fila de la tabla con una clave concreta o explorar un conjunto de filas de la tabla con las claves ubicadas dentro de un cierto rango. Los índices agrupados son el tipo más frecuente de organización de las tablas. 29.3.4 Índices

SQL Server también soporta los índices de árbol B+ secundarios (no agrupados). Las consultas que sólo

hacen referencia a las columnas que están disponibles mediante índices secundarios se procesan mediante la recuperación de las páginas desde el nivel hoja de los índices sin necesidad de recuperar los datos del índice agrupado o montón. Los índices no agrupados de las tablas con índices agrupados contienen las columnas clave del índice agrupado. Por tanto, las filas del índice agrupado se pueden trasladar a una página diferente (mediante divisiones, desfragmentaciones o recreaciones del índice) sin necesidad de modificaciones en los índices no agrupados. SQL Server soporta la adición de columnas calculadas a las tablas. Las columnas calculadas son columnas cuyo valor es una expresión, normalmente basada en el valor de otras columnas de esa fila. SQL Server permite que el usuario construya índices secundarios en términos de las columnas calculadas. 29.3.5 Particiones

SQL Server soporta la división de las tablas y de los índices no agrupados. Los índices divididos están

constituidos por varios árboles B+ , uno por partición. Las tablas divididas sin índices (montones) están constituidas por varios montones, uno por partición. Por brevedad, a partir de aquí sólo se hará referencia a los índices divididos (agrupados o sin agrupar) y se ignorarán los montones. La división de índices de gran tamaño permite al administrador mayor flexibilidad en la gestión del almacenamiento del índice y puede mejorar el rendimiento de algunas consultas, ya que las particiones actúan como índices de grano grueso. La división de los índices se especifica proporcionando una función y un esquema de partición. La función de partición asigna el dominio de la columna de partición (cualquier columna del índice) a las particiones numeradas de 1 a N. El esquema de la partición asigna los números de las particiones generadas por la función de partición a grupos de archivos concretos en los que se guardan las particiones. 29.3.6 Creación en línea de índices

La creación de índices nuevos y la reconstrucción de los ya existentes en una tabla se puede llevar a cabo en línea, es decir, mientras se están llevando a cabo las operaciones de selección, inserción, borrado o actualización en esa tabla. La creación del nuevo índice tiene lugar en tres fases. La primera fase no es más que la creación de un árbol B+ vacío para el nuevo índice con el catálogo que muestre que el nuevo índice está disponible para operaciones de mantenimiento. Esto es, todas las operaciones posteriores de inserción, borrado o actualización deben mantener el nuevo índice, pero éste no se halla disponible para las consultas. La segunda fase consiste en la exploración de la tabla para recuperar las columnas del índice de cada fila, ordenar las filas e insertarlas en el nuevo árbol B+ . Estas inserciones deben tener cuidado al interactuar con las otras filas del nuevo árbol B+ colocadas allí por las operaciones de mantenimiento del índice debidas a las actualizaciones de la tabla base. La exploración es de instantáneas que, sin bloqueos, garantiza que la exploración vea toda la tabla únicamente con los resultados de las transacciones comprometidas en el momento de comienzo de la exploración. Esto se consigue usando la tecnología de aislamiento de instantáneas descrita en el Apartado 29.5.1. La fase final de la creación del índice supone la actualización del catálogo para que indique que la creación del índice se ha completado y que éste se halla disponible para las consultas.

www.detodoprogramacion.com


29.4

Procesamiento y optimización de consultas

895

29.3.7 Exploraciones y lecturas anticipadas

La ejecución de las consultas en SQL Server puede involucrar varios modos de exploración diferentes de las tablas y de los índices subyacentes. Entre estos modos de exploración están las exploraciones ordenadas y las desordenadas, las exploraciones en serie y las paralelas, las unidireccionales y las bidireccionales, las exploraciones hacia delante y hacia atrás y la exploración de toda la tabla o de todo el índice y las exploraciones de rango o filtradas. Cada uno de estos modos de exploración tiene un mecanismo de lectura anticipada que intenta que la exploración se anticipe a las necesidades de ejecución de la consulta, con el fin de reducir las sobrecargas de búsqueda y de latencia y de usar el tiempo de disco no ocupado. El algoritmo de lectura anticipada de SQL Server usa el conocimiento del plan de ejecución de la consulta con el fin de conducir la lectura anticipada y asegurarse de que solamente se lean los datos que la consulta necesita realmente. Además, la cantidad de lectura anticipada se dimensiona de forma automática según el tamaño de la memoria intermedia agrupada, el volumen de E/S que el subsistema del disco puede sostener y la velocidad a la que la ejecución de la consulta consume los datos. 29.4 Procesamiento y optimización de consultas

El procesador de consultas de SQL Server está basado en un entorno extensible que permite la rápida incorporación de nuevas técnicas de ejecución y de optimización. Cualquier consulta de SQL se puede expresar en forma de árbol de operadores del álgebra relacional extendida de SQL Server. Mediante la abstracción de los operadores de este álgebra en iteradores, la ejecución de la consulta encapsula los algoritmos de procesamiento de datos como unidades lógicas que se comunican entre sí usando la interfaz GetNextRow(). A partir del árbol inicial de la consulta, el optimizador de consultas de SQL Server genera alternativas usando transformaciones en árbol y estima su coste de ejecución teniendo en cuenta el comportamiento de los iteradores y los modelos estadísticos para realizar selecciones. 29.4.1 Visión general del proceso de optimización

Las consultas complejas presentan oportunidades significativas de optimización que exigen la ordenación de los operadores de unos bloques de consulta a otros y la selección de los planes con base únicamente en los costes estimados. Para aprovechar estas oportunidades, el optimizador de consultas de SQL Server se desvía de los enfoques tradicionales de la optimización de consultas usados en otros sistemas comerciales en favor de un entorno más general, puramente algebraico, que se basa en el prototipo de optimizador Cascades. La optimización de las consultas forma parte de su proceso de compilación, que consta de cuatro pasos: • Análisis/vinculación. El analizador resuelve los nombres de tablas y columnas mediante los catálogos. SQL Server usa una caché de plan para evitar repetir la optimización de consultas idénticas o estructuralmente parecidas. Si no se dispone de plan guardado en la caché, se genera un árbol de operadores inicial. El árbol de operadores no es más que una combinación de operadores relacionales y no está restringido por conceptos como los bloques de consulta o las tablas derivadas, que suelen obstaculizar la optimización. • Simplificación/normalización. El optimizador aplica las reglas de simplificación al árbol de operadores para obtener una forma normal y simplificada. Durante la simplificación, el optimizador determina y carga las estadísticas necesarias para la estimación de la cardinalidad. • Optimización basada en el coste. El optimizador aplica las reglas de exploración y de implementación para generar alternativas, estimar el coste de ejecución y escoger el plan con el coste anticipado más bajo. Las reglas de exploración implementan la reordenación de un amplio conjunto de operadores, incluida la reordenación de la reunión y de la agregación. Las reglas de implementación introducen alternativas de ejecución como las reuniones por mezcla y las reuniones por asociación. • Preparación del plan. El optimizador crea las estructuras del plan de ejecución para el plan seleccionado.

www.detodoprogramacion.com


896

Capítulo 29

SQL Server de Microsoft

Para obtener mejores resultados, la optimización basada en el coste de SQL Server no se divide en fases que optimicen distintos aspectos de la consulta por separado; además, no está restringida a una sola dimensión, como puede ser la enumeración de reuniones. En vez de eso, un conjunto de reglas de transformación define el espacio de interés, y la estimación del coste se usa de manera uniforme para seleccionar un plan eficiente. 29.4.2 Simpli cación de las consultas

Durante la simplificación sólo se aplican las transformaciones que garantizan la generación de sustitutos menos costosos. El optimizador envía las selecciones tan abajo del árbol de operadores como sea posible; comprueba los predicados en búsqueda de contradicciones, teniendo en cuenta las restricciones declaradas. Usa las contradicciones para identificar subexpresiones que se puedan eliminar del árbol. Una situación frecuente es la eliminación de las ramas union que recuperan los datos de las tablas con diferentes restricciones. Una serie de reglas de simplificación son dependientes del contexto, es decir, la sustitución solamente es válida en el contexto de uso de la subexpresión. Por ejemplo, una reunión externa se puede simplificar en reunión interna si una operación de filtrado posterior elimina las reglas no coincidentes que se rellenaron con null. Otro ejemplo es la eliminación de las reuniones sobre las claves externas, que no hace falta ejecutar si no hay uso posterior de las columnas de la tabla a la que se hace referencia. Un tercer ejemplo es el contexto de insensibilidad a los duplicados, que especifica que la entrega de una o más copias de una fila no afecta al resultado de la consulta. Las subexpresiones bajo las semirreuniones y bajo distinct son insensibles a los duplicados, lo que permite cambiar union por union all. Para la agrupación y la agregación se usa el operador GbAgg, que crea grupos y, opcionalmente, aplica una función agregada a cada grupo. La eliminación de duplicados, expresada en SQL mediante la palabra clave distinct es sencillamente un GbAgg sin funciones agregadas que calcular. Durante la simplificación, la información sobre las claves y sobre las dependencias funcionales se usa para reducir el agrupamiento de columnas. Las subconsultas se normalizan mediante la eliminación de las especificaciones de consulta correlacionadas y el uso de algunas variantes de la reunión en su lugar. La eliminación de las correlaciones no es una “estrategia de ejecución de subconsultas”, sino simplemente un paso de la normalización. Luego se considera una serie de estrategias de ejecución, durante la optimización basada en el coste. 29.4.3 Reordenación y optimización basadas en el coste

En SQL Server las transformaciones se integran completamente en la generación basada en el coste y en la selección de los planes de ejecución. El optimizador de consultas de SQL Server incluye alrededor de trescientas cincuenta reglas de transformación lógica y física. Además de la reordenación de la reunión interna, el optimizador de consultas usa transformaciones de reordenación para los operadores reunión externa, semirreunión y antisemirreunión del álgebra relacional estándar (con duplicados para SQL). También se reordena GbAgg, trasladándolo por debajo de las reuniones siempre que sea posible. La agregación parcial, esto es, la introducción de un nuevo GbAgg con agrupación sobre un superconjunto de las columnas de un GbAgg posterior, se considera por debajo de las reuniones y de union all, y también en los planes paralelos. Véanse las referencias dadas en las notas bibliográficas para obtener más detalles. La ejecución correlacionada se considera durante la exploración del plan; el caso más simple es una reunión de búsqueda en el índice. SQL Server modela la ejecución correlacionada como un operador algebraico único, denominado apply, que opera sobre la tabla T y la expresión relacional parametrizada E(t). Apply ejecuta E para cada fila de T , que proporciona los valores de los parámetros. La ejecución correlacionada se considera como una alternativa a la ejecución, independientemente del uso de subconsultas en la formulación original de SQL. Es una estrategia muy eficiente cuando la tabla T es muy pequeña y los índices soportan la ejecución parametrizada eficiente de E(t). Además, se considera la reducción del número de ejecuciones de E(t) cuando hay valores duplicados de los parámetros mediante dos técnicas: ordenar T según el valor de los parámetros, de forma que se reutilice un único resultado de E(t) mientras que el valor del parámetro sigue siendo el mismo, o usar una tabla de asociación

www.detodoprogramacion.com


29.4

Procesamiento y optimización de consultas

897

que realice un seguimiento del resultado de E(t) para (algún subconjunto de) los valores anteriores del parámetro. Algunas aplicaciones seleccionan las filas según algún resultado agregado obtenido para su grupo. Por ejemplo “Hallar los clientes cuyo saldo sea mayor que el doble de la media de su segmento de mercado”. La formulación de SQL exige una autorreunión. Durante la exploración se detecta este patrón y se considera la ejecución por segmentos como alternativa a la autorreunión. También se considera el uso de vistas materializadas durante la optimización basada en el coste. Las interacciones de la coincidencia de vistas con la ordenación de operadores en ese uso puede que no resulte evidente hasta que se haya tenido lugar otra reordenación. Cuando se encuentra que una vista coincide con alguna subexpresión, la tabla que contiene el resultado de esa vista se agrega como alternativa a la expresión correspondiente. En función de la distribución de los datos y de los índices disponibles, puede que sea mejor que la expresión original—la selección se realizará en términos de la estimación del coste. Para estimar el coste de ejecución del plan el modelo tiene en cuenta el número de filas que se espera procesar, denominado objetivo de filas, así como el número de veces que se ejecuta cada subexpresión. El número de filas puede ser menor que la estimación de la cardinalidad en casos tales como Apply/semijoin. Apply/semijoin devuelve la fila t de T tan pronto como E(t) produce una fila (es decir, comprueba que E(t) existe). Por tanto, el objetivo de filas del resultado de E(t) es 1, y los objetivos de filas de los subárboles de E(t) se calculan para este objetivo de filas de E(t) y se usan para la estimación del coste. 29.4.4 Planes de actualización

Los planes de actualización optimizan el mantenimiento de índices, comprueban las restricciones, aplican las acciones en cascada y mantienen las vistas materializadas. Para el mantenimiento de los índices, en lugar de tomar cada fila y mantener todos sus índices, los planes de actualización aplican las modificaciones índice a índice, ordenando las filas y aplicando la operación update según el orden de la clave. Esto minimiza las operaciones aleatorias de E/S, especialmente cuando el número de filas que hay que actualizar es grande. Las restricciones las maneja un operador assert, que ejecuta un predicado y envía un mensaje de error si el resultado es false. Las restricciones de integridad referencial se definen mediante predicados exist que, a su vez, se convierten en semirreuniones y se optimizan considerando todos los algoritmos de ejecución. El problema de Halloween se aborda usando elecciones basadas en el coste. El problema de Halloween hace referencia a la siguiente anomalía: supóngase que se lee un índice salarial en orden ascendente y se están subiendo los sueldos un diez por ciento. Como resultado de la actualización, las filas se desplazarán hacia arriba en el índice, se volverán a encontrar y se actualizarán de nuevo, lo que lleva a un bucle infinito. Una forma de abordar este problema es separar el procesamiento en dos fases: en primer lugar se leen todas las filas que se van a actualizar y se hace una copia de ellas en algún emplazamiento temporal, después se leen desde ese emplazamiento y se aplican todas las actualizaciones. Otra alternativa es leer desde un índice distinto donde las filas no se trasladen como consecuencia de la actualización. Algunos planes de ejecución proporcionan la separación de las fases de forma automática, si se ordena o crea una tabla de asociación con las filas que se van a actualizar. En el optimizador de SQL Server la protección contra Halloween se modela como una de las propiedades de los planes. Se generan varios planes que proporcionan la propiedad requerida y se selecciona uno en función del coste de ejecución estimado. 29.4.5 Análisis de los datos durante la optimización

SQL fue de los primeros en introducir técnicas para llevar a cabo la recogida de estadísticas como parte

de las optimizaciones en proceso. El cálculo de las estimaciones de tamaño del resultado se basa en las estadísticas de las columnas usadas en una expresión dada. Estas estadísticas consisten en histogramas de diferencias máximas de los valores de las columnas y en varios contadores que capturan la densidad y el tamaño de las filas, entre otras cosas. Los administradores de las bases de datos pueden crear estadísticas de manera explícita mediante la sintaxis extendida de SQL. Si no se dispone de estadísticas para una columna determinada, no obstante, el optimizador de SQL Server detiene la optimización en proceso y reúne las estadísticas necesarias. En cuanto se han calculado

www.detodoprogramacion.com


898

Capítulo 29

SQL Server de Microsoft

las estadísticas, se reanuda la optimización original, que aprovechará las estadísticas recién creadas. La optimización de las consultas posteriores reúsa las estadísticas generadas anteriormente. Normalmente, tras un breve periodo de tiempo, ya se han creado las estadísticas de las columnas usadas con frecuencia y las interrupciones para la elaboración de estadísticas nuevas se hacen menos frecuentes. Mediante el seguimiento del número de filas modificadas en cada tabla se tiene una medida de la antigüedad de todas las estadísticas afectadas. Una vez que la antigüedad supera un cierto umbral, se vuelven a calcular esas estadísticas y los planes guardados en la caché se vuelven a compilar para que tengan en cuenta las distribuciones de datos modificadas. SQL Server 2005 puede llevar a cabo el cálculo automático de las estadísticas de manera asíncrona. Esto evita los tiempos de compilación potencialmente largos debidos a la elaboración síncrona de las estadísticas. La optimización que desencadena el cálculo de las estadísticas usa estadísticas potencialmente antiguas. No obstante, las consultas posteriores pueden aprovechar las estadísticas recalculadas. Esto permite lograr un equilibrio aceptable entre el tiempo empleado en la optimización y la calidad del plan de consultas resultante. 29.4.6 Búsquedas parciales y heurísticas

Los optimizadores basados en el coste se enfrentan con el problema de la explosión del espacio de búsqueda, puesto que las aplicaciones realizan consultas que implican a docenas de tablas. Para abordar esto, SQL Server usa varias etapas de optimización, cada una de los cuales usa transformaciones de la consulta para explorar regiones sucesivamente mayores del espacio de búsqueda. Hay transformaciones sencillas y completas diseñadas para la optimización exhaustiva, así como transformaciones inteligentes que implementan varias heurísticas. Las transformaciones inteligentes generan planes que están muy lejos entre sí en el espacio de búsqueda, mientras que las transformaciones sencillas exploran zonas vecinas. Las etapas de optimización aplican una mezcla de ambas clases de transformaciones, poniendo en primer lugar el énfasis en las transformaciones inteligentes y pasando luego a las transformaciones sencillas. Se conservan los resultados óptimos de los subárboles, de forma que las etapas posteriores puedan aprovechar los resultados generados con anterioridad. Cada etapa debe equilibrar técnicas de generación de planes opuestas: • Generación exhaustiva de alternativas. Para generar el espacio completo el optimizador usa transformaciones completas, locales, no redundantes—una regla de transformación equivalente a una secuencia de transformaciones más primitivas solamente introduce una sobrecarga adicional. • Generación heurística de candidatos. Es probable que una serie de candidatos interesantes (seleccionados en términos del coste estimado) estén lejos entre sí en términos de las reglas de transformación primitivas. En este caso, las transformaciones deseadas son incompletas, globales y redundantes. La optimización se puede terminar en cualquier momento tras la generación del primer plan. Esta terminación se basa en el coste estimado del mejor plan encontrado y en el tiempo ya empleado en la optimización. Por ejemplo, si una consulta sólo necesita buscar unas cuantas filas de algunos índices, se producirá rápidamente un plan muy barato en las primeras etapas, lo que terminará la optimización. Este enfoque permite agregar fácilmente nuevas heurísticas en el transcurso del tiempo, sin comprometer la selección de planes basada en el coste ni la exploración exhaustiva del espacio de búsqueda, cuando resulta conveniente. 29.4.7 Ejecución de las consultas

Los algoritmos de ejecución soportan tanto el procesamiento basado en la ordenación como el basado en la asociación, y sus estructuras de datos se diseñan para optimizar el uso de la caché del procesador. Las operaciones de asociación soportan la agregación y la reunión básicas, con una serie de optimizaciones, extensiones y ajustes dinámicos del sesgo de datos. La operación flow–distinct es una variante diferente de la asociación (hash distinct), en la que las filas se devuelven antes, tan pronto como se encuentra un valor diferente nuevo, en lugar de esperar a procesar todos los datos de entrada. Este operador es

www.detodoprogramacion.com


29.5

Concurrencia y recuperación

899

efectivo para las consultas que usan distinct y sólo piden unas cuantas filas, por ejemplo, cuando se usa el constructor top n. Los planes correlacionados especifican la ejecución de E(t), e incluyen a menudo varias búsquedas en el índice basadas en el parámetro, para cada fila t de la tabla T . La captura previa asíncrona permite la solicitud al motor de almacenamiento de varias solicitudes de búsqueda en el índice. Se implementa de esta manera: se realiza una solicitud de búsqueda en el índice sin bloqueo para la fila t de T , luego t se coloca en la cola de captura previa. Las filas se sacan de la cola y apply las usa para ejecutar E(t). La ejecución de E(t) no necesita que los datos se hallen ya en la memoria intermedia agrupada, pero tener buenas operaciones de captura previa maximiza el uso del hardware e incrementa el rendimiento. El tamaño de la cola se determina dinámicamente como función de los aciertos de la caché. Si no se necesita ninguna ordenación de las filas de salida de apply, las filas de esa cola se pueden tomar sin prestar atención al orden, para minimizar la espera en las operaciones de E/S. La ejecución en paralelo la implementa el operador exchange, que gestiona varias hebras, realiza particiones o difunde datos y proporciona los datos a varios procesos. El optimizador de consultas decide la ubicación de exchange según el coste estimado. El grado de paralelismo se determina dinámicamente en el momento de la ejecución, en función del uso del sistema en ese momento. Los planes de índices están constituidos por los fragmentos que se han descrito anteriormente. Por ejemplo, se considera el uso de una reunión de índices para resolver las conjunciones de predicados (o una unión de índices para las disyunciones), en términos de su coste. Esta reunión se puede realizar en paralelo, usando cualquiera de los algoritmos de reunión de SQL Server. También se consideran reuniones de índices con el único propósito de ensamblar una fila con el conjunto de columnas necesario en una consulta, lo cual, a veces, es más rápido que explorar una tabla base. Tomar los identificadores de registros de un índice secundario y localizar la fila correspondiente de la tabla base es equivalente, en efecto, a ejecutar una reunión de búsqueda de índices. Para ello se usan las técnicas genéricas de ejecución correlacionada, como la captura previa asíncrona. La comunicación con el motor de almacenamiento se realiza mediante OLE-DB, lo que permite el acceso a otros proveedores de datos que también implementan esa interfaz. OLE-DB es el mecanismo usado para las consultas distribuidas y para las remotas, que maneja directamente el procesador de consultas. Los proveedores de datos se clasifican según el rango de funcionalidad que proporcionan, desde simples proveedores de conjuntos de filas sin capacidades de indexado a proveedores con soporte completo de SQL. 29.5 Concurrencia y recuperación

Los subsistemas de transacciones, registro histórico, bloqueos y recuperación de SQL Server hacen que se cumplan las propiedades ACID esperadas de los sistemas de bases de datos. 29.5.1 Transacciones

El control de concurrencia basado en los bloqueos es el predeterminado para SQL Server. SQL Server también ofrece el control de concurrencia optimista para los cursores. El control de concurrencia optimista se basa en la suposición de que los conflictos de recursos entre varios usuarios son poco probables (aunque no imposibles) y permite que las transacciones se ejecuten sin bloquear ningún recurso. Sólo cuando se intenta modificar los datos, SQL Server comprueba los recursos para determinar si se ha producido algún conflicto. Si se produce algún conflicto, la aplicación debe leer los datos e intentar el cambio de nuevo. Las aplicaciones pueden elegir si se detectan los cambios comparando los valores o comprobando la columna especial rowversion de cada fila. SQL Server soporta los niveles de aislamiento de SQL de lectura no comprometida, lectura comprometida, lectura repetible y serializable. La lectura comprometida es el nivel predeterminado. Además, SQL Server soporta dos niveles de aislamiento basados en las instantáneas. • Instantánea. Especifica que los datos leídos por cualquier instrucción de la transacción son la versión consistente transaccionalmente de los datos que existían al comienzo de esa transacción. La transacción sólo puede ver las modificaciones de los datos que se comprometieron antes de su comienzo. Las modificaciones de los datos llevadas a cabo por otras transacciones tras el comienzo de esta transacción no son visibles para las instrucciones que se ejecutan en la transacción

www.detodoprogramacion.com


900

Capítulo 29

SQL Server de Microsoft

actual. El efecto es como si las instrucciones de la transacción vieran una instantánea de los datos comprometidos tal y como eran al principio de la transacción. • Instantánea de lectura comprometida. Especifica que cada instrucción ejecutada en la transacción ve una instantánea transaccionalmente consistente de los datos tal y como eran al comienzo de la instrucción. Las modificaciones de los datos llevadas a cabo por otras transacciones tras el comienzo de la instrucción no son visibles para ella. Esto es diferente de lo que ocurre con el aislamiento de lectura comprometida, en el que la instrucción puede ver las actualizaciones comprometidas de las transacciones que se comprometen mientras se ejecuta. 29.5.2 Bloqueos

El bloqueo es el principal mecanismo de los usados para hacer cumplir la semántica de los niveles de aislamiento. Todas las actualizaciones adquieren los bloqueos exclusivos suficientes, mantenidos toda la duración de la transacción, para evitar que se produzcan actualizaciones que entren en conflicto entre sí. Los bloqueos compartidos se mantienen en duraciones diferentes para proporcionar los diversos niveles de aislamiento de SQL para las consultas. SQL Server proporciona bloqueos de varias granularidades que permiten que cada transacción bloquee diferentes tipos de recursos (véase la Figura 29.4, en la que los recursos se relacionan en orden creciente de granularidad). Para minimizar el coste de los bloqueos, SQL Server bloquea de manera automática los recursos con la granularidad apropiada para cada tarea. El bloqueo con una granularidad menor, como pueden ser las filas, aumenta la concurrencia, pero tiene una sobrecarga mayor, ya que hay que realizar más bloqueos si se bloquean muchas filas. Los modos de bloqueos fundamentales de SQL Server son el compartido (S, shared), el de actualización (U, update) y el exclusivo (X, exclusive); los bloqueos intencionales (intent) se usan para evitar una forma frecuente de interbloqueo que se produce cuando varias sesiones leen, bloquean y, potencialmente, actualizan posteriormente los recursos. Los modos adicionales de bloqueo—denominados bloqueos de rango de claves — sólo se toman en el nivel de aislamiento serializable para bloquear el rango entre dos filas de un índice. 29.5.2.1 Bloqueos dinámicos

Los bloqueos de granularidad fina pueden mejorar la concurrencia a cambio de ciclos adicionales de CPU y de memoria extra para adquirir y mantener muchos bloqueos. Para muchas consultas, una granularidad de bloqueo más gruesa proporciona mejor rendimiento sin pérdida (o con una pérdida mínima) de la concurrencia . Los sistemas de base de datos han exigido tradicionalmente sugerencias de consulta y opciones de tabla para que las aplicaciones especificaran la granularidad del bloqueo. Además, hay parámetros de configuración (frecuentemente estáticos) para la cantidad de memoria que se debe dedicar al administrador de bloqueos. En SQL Server la granularidad del bloqueo se optimiza automáticamente para un rendimiento y una concurrencia óptimos de cada índice de la consulta. Además, la memoria dedicada al administrador de bloqueos se ajusta dinámicamente según la realimentación de las demás partes del sistema, incluidas otras aplicaciones de la máquina. La granularidad del bloqueo se optimiza antes de la ejecución de las consultas para cada tabla y para cada índice usados en esa consulta. El proceso de optimización del bloqueo tiene en cuenta el nivel de Recurso RID Clave Página Extensión Tabla BD

Descripción Identificador de fila, usado para bloquear una sola fila de la tabla. Bloqueo de fila en un índice; protege rangos de la clave en transacciones secuenciables. Página de tabla o de índice de ocho kilobytes. Grupo contiguo de ocho páginas de datos o de índices. Tabla completa, incluidos todos los datos y todos los índices. Base de datos. Figura 29.4

Recursos bloqueables.

www.detodoprogramacion.com


29.5

Concurrencia y recuperación

901

aislamiento (esto es, el tiempo que se mantienen los bloqueos), el tipo de exploración (rango, sonda o toda la tabla), el número estimado de filas que hay que explorar, la selectividad (porcentaje de filas visitadas que son aceptables para la consulta) la densidad de las filas (número de filas por página), el tipo de operación (exploración, actualización), los límites del usuario sobre la granularidad y la memoria de sistema disponible. Una vez se está ejecutando la consulta, la granularidad de bloqueo se dimensiona automáticamente hasta el nivel de las tablas si el sistema adquiere significativamente más bloqueos que los esperados por el optimizador, o si la cantidad de memoria disponible baja y no se puede soportar el número de bloqueos necesario. 29.5.2.2 Detección de los interbloqueos

SQL Server detecta de forma automática los interbloqueos que involucran tanto a bloqueos como a otros

recursos. Por ejemplo, si la transacción A mantiene un bloqueo sobre Tabla1 y está esperando que haya memoria disponible y la transacción B tiene algo de memoria que no puede liberar hasta que adquiera un bloqueo sobre Tabla1, las transacciones sufrirán un interbloqueo. Las hebras y las memorias intermedias de comunicación también pueden estar implicados en los interbloqueos. Cuando SQL Server detecta un interbloqueo, elige como víctima del interbloqueo la transacción que es menos costosa de hacer retroceder, considerando la cantidad de trabajo que la transacción ya ha realizado. La detección frecuente de interbloqueos puede perjudicar al rendimiento del sistema. SQL Server ajusta automáticamente la frecuencia de detección de los interbloqueos a la frecuencia con la que se producen. Si los interbloqueos no son frecuentes, el algoritmo de detección se ejecuta cada cinco segundos. Si son frecuentes, comenzará a comprobar si hay alguno cada vez que una transacción espere un bloqueo. 29.5.2.3 Versiones de las las para el aislamiento de instantáneas

Los dos niveles de aislamiento basados en las instantáneas usan las versiones de las filas para conseguir el aislamiento de las consultas sin bloquear las consultas que se hallan tras las actualizaciones, y viceversa. Bajo el aislamiento de instantáneas las operaciones de actualización y de borrado generan versiones de las filas afectadas y las guardan en una base de datos temporal. El sistema se deshace de estas versiones cuando no hay ninguna transacción activa que pueda necesitarlas. Por tanto, las consultas ejecutadas bajo el aislamiento de instantáneas no necesita adquirir bloqueos y, en vez de eso, puede leer las versiones más antiguas de cualquier registro que otra transacción actualice o borre. Las versiones de las filas se usan también para proporcionar instantáneas de tablas para las operaciones de creación de índices en línea. 29.5.3 Recuperación y disponibilidad

SQL Server está diseñado para recuperarse de los fallos del sistema y de los medios, y el sistema de

recuperación se puede adaptar a máquinas con grupos de memorias intermedias de tamaño muy grande (cien gigabytes) y millares de unidades de disco. 29.5.3.1 Recuperación de caídas

El registro histórico es, desde un punto de vista lógico, una corriente potencialmente infinita de registros históricos identificados por los números de secuencia del registro histórico (Log Sequence Numbers, LSNs). Desde un punto de vista físico, parte de la corriente se almacena en los archivos del registro histórico. Los registros históricos se guardan en los archivos del registro histórico hasta que se realiza una copia de seguridad y el sistema ya no los necesita para el retroceso o para la duplicación. Los archivos del registro histórico aumentan y disminuyen de tamaño para acomodarse a los registros que hay que almacenar. Se pueden añadir más archivos del registro histórico a la base de datos (en nuevos discos, por ejemplo) mientras que el sistema se está ejecutando y sin bloquear ninguna operación actual, y todos los registros históricos se tratan como si fueran un archivo continuo.

www.detodoprogramacion.com


902

Capítulo 29

SQL Server de Microsoft

El sistema de recuperación de SQL Server tiene muchos aspectos en común con el algoritmo de recuperación ARIES (véase el Apartado 17.8.6), y en este apartado se muestran algunas de las diferencias fundamentales. SQL Server tiene una opción de configuración denominada intervalo de recuperación, que permite que el administrador limite el tiempo que SQL Server debe tardar en recuperarse después de una caída. El servidor ajusta dinámicamente la frecuencia de los puntos de comprobación para reducir el tiempo de recuperación a valores comprendidos dentro del intervalo de recuperación. Los puntos de comprobación eliminan todas las páginas desfasadas de la memoria intermedia agrupada y se ajustan a las capacidades del sistema de E/S y a su carga de trabajo actual para eliminar de forma efectiva cualquier efecto sobre las transacciones que se estén ejecutando. En el inicio, después de una caída, el sistema inicia varias hebras (dimensionadas automáticamente al número de CPUs) para iniciar la recuperación de varias bases de datos en paralelo. La primera fase de la recuperación es una pasada de análisis del registro histórico, que crea una tabla de páginas desfasadas y una lista de transacciones activas. La siguiente fase es una pasada de recreación que se inicia desde el último punto de comprobación y rehace todas las operaciones. Durante la fase de recreación se usa la tabla de páginas desfasadas para leer anticipadamente las páginas de datos. La fase final es una fase de destrucción en la que se retroceden las transacciones incompletas. La fase de destrucción se divide realmente en dos partes, puesto que SQL Server usa un esquema de recuperación de dos niveles. Las transacciones del primer nivel (aquéllas que implican operaciones internas como la asignación de espacio y las divisiones de páginas) retroceden en primer lugar, seguidas por las transacciones de los usuarios. Una vez que las transacciones del primer nivel han retrocedido, la base de datos se conecta al exterior y queda disponible para que comiencen nuevas transacciones de los usuarios mientras se llevan a cabo las últimas operaciones de retroceso. Esto se consigue haciendo que la pasada de recreación vuelva a adquirir los bloqueos para todas las transacciones de usuario incompletas que retrocederán en la fase de destrucción. 29.5.3.2 Recuperación de los medios

Las capacidades de copia de seguridad y de restauración de SQL Server permiten que se recupere de muchos fallos, incluidos la pérdida o corrupción de los medios de disco, los errores del usuario y la pérdida permanente de servidores. Además, la realización de copias de seguridad y de restauraciones de las bases de datos es útil para otros fines, como la copia de bases de datos de un servidor a otro y el mantenimiento de sistemas en espera. SQL Server tiene tres modelos de recuperación diferentes entre los que los usuarios pueden elegir para cada base de datos. Mediante la especificación del modelo de recuperación, el administrador declara el tipo de capacidades de recuperación necesarias (como la restauración en un momento determinado y el envío de registros históricos) y las copias de seguridad necesarias para conseguirlas. Se pueden realizar copias de seguridad de las bases de datos, de los archivos, de los grupos de archivos y del registro histórico de transacciones. Todas las copias de seguridad son difusas y se realizan completamente en línea; es decir, no bloquean ninguna operación de LMD ni de LDD mientras se ejecutan. Las recuperaciones también se pueden llevar a cabo en línea, de modo que sólo se deje desconectada la parte de la base de datos que se está recuperando (por ejemplo, un bloque de disco corrupto). Las operaciones de copia de seguridad y de restauración están muy optimizadas y sólo quedan limitadas por la velocidad de los medios a los que se dirige la copia de seguridad. SQL Server puede realizar copias de seguridad tanto en dispositivos de disco como en los de cinta (hasta sesenta y cuatro en paralelo) y tiene APIs de gran rendimiento para usarlas con productos de copia de seguridad de otros fabricantes. 29.5.3.3 Copias exactas de las bases de datos

El uso de copias exactas de las bases de datos supone la reproducción inmediata de todas las actualizaciones de una de las bases de datos (la base de datos principal) en una copia diferente y completa de la base de datos (la base de datos copia exacta) que se suele ubicar en otra máquina. En caso de desastre en el servidor principal, o simplemente por labores de mantenimiento, el sistema puede recurrir de manera inmediata a la copia exacta en cuestión de segundos. Se consigue un estrecho acoplamiento entre la base

www.detodoprogramacion.com


29.6

Arquitectura del sistema

903

de datos principal y la copia exacta mediante el envío de bloques de registros históricos de transacciones a la copia exacta a medida que se generan en la base de datos principal y mediante la reconstrucción de los registros del registro histórico en la copia exacta. En el modo de seguridad completa las transacciones no se pueden comprometer hasta que los registros del registro histórico de la transacción han llegado al disco de la copia exacta. La biblioteca de comunicaciones usadas por las aplicaciones es consciente de la realización de la copia exacta y se vuelve a conectar a ella de manera automática en caso de conmutación debida a un error. 29.6 Arquitectura del sistema

Cada ejemplar de SQL Server es un único proceso del sistema operativo, que es también un punto de referencia para las solicitudes de ejecución de SQL. Las aplicaciones interactúan con SQL Server mediante diferentes bibliotecas del lado del cliente (como ODBC y OLE-DB) con el fin de ejecutar SQL. 29.6.1 Agrupación de hebras en el servidor

Para minimizar el cambio de contextos en el servidor y para controlar el grado de multiprogramación, el proceso de SQL Server mantiene un grupo de hebras que ejecutan las solicitudes del cliente. Cuando llegan las solicitudes del cliente se les asigna una hebra en el que ejecutarse. La hebra ejecuta las instrucciones de SQL enviadas por el cliente y le devuelve el resultado. Una vez completada la solicitud del usuario, la hebra se devuelve al grupo de hebras. Además de las solicitudes de los usuarios, el grupo de hebras también se usa para asignar hebras para tareas internas que se ejecutan en segundo plano como: • Escritor diferido (lazywriter). Esta hebra se dedica a garantizar que una cierta cantidad del grupo de memorias intermedias está libre y disponible en todo momento para su asignación por el sistema. Esta hebra también interactúa con el sistema operativo para determinar la cantidad óptima de memoria que debe consumir el proceso de SQL Server. • Punto de comprobación (checkpoint). Esta hebra comprueba de forma periódica todas las bases de datos para mantener un intervalo de recuperación breve para el inicio de las bases de datos al reiniciar el servidor. • Monitor de interbloqueo (deadlock monitor). Esta hebra supervisa otras hebras, buscando interbloqueos en el sistema. Es responsable de la detección de interbloqueos y también selecciona una víctima para permitir que el sistema progrese. Cuando el procesador de consultas elige un plan paralelo para ejecutar una consulta determinada puede asignar varias hebras que trabajen en nombre de la hebra principal para ejecutar la consulta. Puesto que la familia de sistemas operativos de Windows NT proporciona soporte nativo de las hebras, SQL Server usa las hebras de NT para su ejecución. No obstante, SQL Server se puede configurar para que ejecute hebras en modo usuario además de las hebras del núcleo en sistemas de prestaciones muy elevadas para evitar el coste de un cambio de contexto del núcleo en los intercambios de hebras. 29.6.2 Gestión de la memoria

Hay muchos usos distintos de memoria en el proceso de SQL Server: • Grupo de memorias intermedias. El mayor consumidor de memoria del sistema es el grupo de memorias intermedias. El grupo de memorias intermedias mantiene una caché de las páginas de la base de datos usadas más recientemente. Usa un algoritmo de sustitución de reloj con una política de robo sin fuerza; esto es, las páginas de la memoria intermedia con actualizaciones no comprometidas se pueden sustituir (“robar”), y no se fuerza su envío al disco cuando se compromete la transacción. Las memorias intermedias también obedecen el protocolo del registro histórico de escritura anticipada para garantizar la corrección de la recuperación de las caídas y de los medios.

www.detodoprogramacion.com


904

Capítulo 29

SQL Server de Microsoft

• Asignación de la memoria dinámica. Se trata de la memoria que se asigna de forma dinámica para ejecutar solicitudes remitidas por el usuario. • Caché de planes y de ejecución. Esta caché almacena los planes compilados para varias consultas que los usuarios han ejecutado previamente en el sistema. Esto permite que varios usuarios compartan el mismo plan (lo cual ahorra memoria) y también ahorra tiempo de compilación de la consulta para consultas parecidas. • Concesiones de grandes cantidades de memoria. Para los operadores de consulta que consumen grandes cantidades de memoria, como las reuniones por asociación y las ordenaciones. SQL Server usa un esquema elaborado de gestión de la memoria para dividir su memoria entre los varios usos que se han descrito. Un solo administrador de memoria gestiona de forma centralizada toda la memoria usada por SQL Server. El administrador de memoria es responsable de realizar de forma dinámica la división y la redistribución de la memoria entre los diversos consumidores de memoria del sistema. Distribuye esa memoria de acuerdo con un análisis de la relación entre costes y beneficios de la memoria para cualquier uso concreto. Hay disponible un mecanismo generalizado con infraestructura LRU para todos los componentes. Esta infraestructura de caché no sólo realiza un seguimiento del tiempo de vida de los datos guardados en la caché, sino también de los costes relativos de CPU y de E/S necesarios para crearlos y guardarlos en la caché. Esta información se usa para determinar los costes relativos de los diferentes datos guardados en la caché. El administrador de memoria se centra en la expulsión de los datos guardados en la caché que no han sido tocados recientemente y que eran baratos de guardar en la caché. Como ejemplo, es más probable que permanezcan en la memoria los planes de consulta complejos que necesitan segundos de CPU para compilarse que los planes triviales para frecuencias de acceso equivalentes. El administrador de memoria interactúa con el sistema operativo para decidir de forma dinámica la cantidad de memoria que se debe consumir de la cantidad total de memoria del sistema. Esto permite que SQL Server sea bastante agresivo en el uso de la memoria del sistema, pero también que pueda devolver memoria al sistema cuando otros programas la necesiten sin causar excesivos fallos de página. 29.6.3 Seguridad

SQL Server ofrece mecanismos de seguridad generales y directivas para la autenticación, la autorización

y el cifrado. Dos cosas son todavía más importantes para la seguridad de los usuarios: (1) la calidad de todo el código base y (2) la posibilidad de que los usuarios determinen si han protegido adecuadamente el sistema. La calidad del código base se mejora haciendo que todos los desarrolladores y probadores del producto reciban formación de seguridad. Siempre que es posible, SQL Server usa las características de seguridad subyacentes del sistema operativo en vez de implementar las suyas propias. Además, se usan numerosas herramientas internas para analizar el código base, en búsqueda de posibles fallos de seguridad. Varias de estas características se proporcionan para ayudar a los usuarios a proteger el sistema adecuadamente. Una de ellas es una directiva fundamental denominada “deshabilitado de forma predeterminada”, por la que se deshabilitan de forma predeterminada muchos componentes usados escasamente de entre los que necesitan una preocupación adicional por la seguridad. Otra característica es un “analizador de buenas prácticas”, que avisa a los usuarios sobre las configuraciones de los parámetros del sistema que pueden provocar vulnerabilidades de seguridad. 29.7 Acceso a los datos SQL Server soporta las siguientes interfaces de programación de aplicaciones (Application Programming

Interface, API) para la creación de aplicaciones intensivas en datos: • ODBC (Conectividad abierta de bases de datos, Open Database Connectivity). Se trata de la implementación de Microsoft de la interfaz del nivel de llamadas (call–level interface, CLI) de la norma SQL:1999. Incluye los modelos de objetos—Remote Data Objects, RDOs (objetos de datos

www.detodoprogramacion.com


29.8

Procesamiento de consultas heterogéneas distribuidas

905

remotos) y Data Access Objects, DAOs (objetos de acceso a datos)— que facilitan la programación de las aplicaciones de bases de datos multicapa a partir de lenguajes de programación como Visual Basic. • OLE-DB (Object Linking and Embedding—Database, Vinculación e incrustación de objetos para bases de datos). Se trata de una API de bajo nivel orientada a sistemas diseñada para los programadores que crean componentes de bases de datos. La interfaz está construida de acuerdo con el modelo de objetos componentes (Component Object Model, COM) de Microsoft, y permite la encapsulación de servicios de bajo nivel de la base de datos como los proveedores de conjuntos de filas, los proveedores ISAM y los motores de consultas. OLE-DB se usa en SQL Server para integrar el procesador de consultas relacionales y el motor de almacenamiento y permitir la duplicación y el acceso distribuido a SQL y a otros orígenes externos de datos. Al igual que ODBC, OLE-DB incluye un modelo de objetos de nivel superior denominado Objetos de datos ActiveX (ActiveX Data Objects, ADO) para facilitar la programación de aplicaciones de bases de datos desde Visual Basic. • ADO.NET. Se trata de una API más nueva diseñada para las aplicaciones escritas en lenguajes .NET como C# y Visual Basic.NET. Esta interfaz simplifica algunos patrones frecuentes de acceso a datos soportados por ODBC y por OLE-DB. Además, proporciona un nuevo modelo de conjuntos de datos (data set) para permitir las aplicaciones de acceso a datos desconectadas y sin estado. • DB-Lib. La biblioteca de bases de datos para la API de C que se desarrolló específicamente para usarla con versiones anteriores de SQL Server anteriores a la norma SQL-92. • HTTP/SOAP. Las aplicaciones pueden usar las solicitudes HTTP/SOAP para invocar las consultas y los procedimientos de SQL Server. Las aplicaciones pueden usar URLs que especifiquen raíces virtuales de Internet Information Server (IIS, Servidor de información de Internet) que hagan referencia a ejemplares de SQL Server. El URL puede contener una consulta XPath, una instrucción de Transact-SQL o una plantilla de XML. 29.8 Procesamiento de consultas heterogéneas distribuidas

La posibilidad de realizar consultas distribuidas heterogéneas de SQL Server permite formular consultas transaccionales y actualizaciones de gran variedad de orígenes relacionales y no relacionales mediante proveedores de datos OLE-DB que se ejecutan en una o más computadoras. SQL Server soporta dos métodos para hacer referencia a los orígenes de datos OLE-DB heterogéneos en las instrucciones TransactSQL. El método de los nombres de servidor vinculados usa procedimientos almacenados del sistema para asociar el nombre de un servidor con cada origen de datos OLE-DB. Se puede hacer referencia a los objetos de estos servidores vinculados en las instrucciones de Transact-SQL usando el convenio de nombres de cuatro partes que se describe más adelante. Por ejemplo, si el nombre de un servidor vinculado de DeptSQLSrvr se define en otra copia de SQL Server, la siguiente instrucción hace referencia a una tabla de ese servidor: select * from DeptSQLSrvr.Northwind.dbo.Employees En SQL Server los orígenes de datos OLE-DB se registran como servidores vinculados. Una vez que se define un servidor vinculado, se puede tener acceso a sus datos usando el nombre de cuatro partes <servidor_vinculado>.<catálogo>.<esquema>.<objeto> El ejemplo siguiente establece un servidor vinculado a un servidor Oracle mediante un proveedor OLEDB para Oracle: exec sp_addlinkedserver OraSvr, ’Oracle 7.3’, ’MSDAORA’, ’OracleServer’

www.detodoprogramacion.com


906

Capítulo 29

SQL Server de Microsoft

Una consulta a este servidor vinculado se expresa como: select * from OraSvr.CORP.ADMIN.VENTAS Además, SQL Server soporta funciones intrínsecas parametrizadas de tipo tabla denominadas openrowset y openquery, que permiten enviar consultas no interpretadas a proveedores o a servidores vinculados, respectivamente, en el dialecto soportado por cada proveedor. La siguiente consulta combina la información almacenada en un servidor de Oracle y en un servidor de Microsoft Index Server. Relaciona todos los documentos que contienen las palabras Datos y Acceso, junto con sus autores, ordenadas por el departamento y el nombre del autor. select e.dept, f.AutorDoc, f.NombreArchivo from OraSvr.Corp.Admin.Empleado e, openquery(ArchivosEmp, ’select AutorDoc, NombreArchivo from scope(“c:\EmpDocs”) where contains(’ ’ “Datos” near() “Acceso” ’ ’)>0’) as f where e.nombre = f.AutorDoc order by e.dept, f.AutorDoc El motor relacional usa las interfaces OLE-DB para abrir los conjuntos de filas de los servidores vinculados, capturar las filas y gestionar las transacciones. Para cada origen de datos OLE-DB al que se tiene acceso como servidor vinculado debe estar presente un proveedor OLE-DB en el servidor en el que se ejecuta SQL Server. El conjunto de operaciones de Transact-SQL que se pueden usar en un origen de datos OLE-DB concreto depende de las capacidades del proveedor OLE-DB. Siempre que sea efectivo en el coste, SQL Server envía las operaciones relacionales como reuniones, restricciones, proyecciones, ordenaciones y agrupaciones al origen de datos OLE-DB. SQL Server usa el coordinador de transacciones distribuidas de Microsoft (Microsoft Distributed Transaction Coordinator) y las interfaces de transacciones OLE-DB del proveedor para garantizar la atomicidad de las transacciones que abarcan varios orígenes de datos.

29.9 Duplicación

La duplicación (réplica) de SQL Server son un conjunto de tecnologías para la copia y distribución de datos y de objetos de las bases de datos entre unas bases de datos y otras, el seguimiento de las modificaciones y la sincronización entre las bases de datos para conservar la consistencia. Las versiones más recientes de la duplicación de SQL Server también ofrecen la duplicación en línea de la mayor parte de las modificaciones de los esquemas de las bases de datos sin necesidad de interrupciones ni reconfiguraciones. Los datos se suelen duplicar para aumentar su disponibilidad. La duplicación pueden reunir datos corporativos desde sitios geográficamente dispersos con destino a informes y diseminar datos a usuarios remotos de redes de área local o a usuarios itinerantes de conexiones de acceso telefónico a redes o de Internet. La duplicación de Microsoft SQL Server también mejora el rendimiento de las aplicaciones mediante su dimensionado para mejorar el rendimiento total de lectura entre duplicados, como es habitual al proporcionar servicios de caché de datos de capa intermedia para sitios Web. 29.9.1 Modelo de duplicación

SQL Server introdujo la metáfora Publicar–Suscribir para la duplicación de las bases de datos y extien-

de esta metáfora de la industria editorial a sus herramientas de administración y supervisión de los duplicados. El publicador es un servidor que pone los datos a disposición de otros servidores para su duplicación. El publicador puede tener una o más publicaciones, cada una de las cuales representa un conjunto

www.detodoprogramacion.com


29.9

Duplicación

907

de datos y de objetos de la base de datos relacionados lógicamente. Los objetos discretos de cada publicación, incluidas las tablas, los procedimientos almacenados, las funciones definidas por el usuario, las vistas, las vistas materializadas, etc., se denominan artículos. Añadir un artículo a una publicación permite la personalización extensiva de la forma en que se duplica ese objeto, por ejemplo, las restricciones sobre los usuarios que pueden suscribirse para recibir esos datos y sobre la manera en que ese conjunto de datos debe filtrarse de acuerdo con la proyección o la selección de una tabla, mediante un filtro “horizontal” o “vertical”, respectivamente. Los suscriptores son servidores que reciben los datos duplicados de los publicadores. Los suscriptores se pueden suscribir, como resulte oportuno, sólo a las publicaciones que necesiten de uno o varios publicadores, independientemente del número o del tipo de opciones de duplicación que implemente cada uno. Dependiendo del tipo de opciones de duplicación seleccionadas, el suscriptor se puede usar como duplicado de sólo lectura o bien se pueden realizar modificaciones en los datos que se propagan automáticamente al publicador y, por consiguiente, al resto de duplicados. Los suscriptores también pueden volver a publicar los datos a los que se suscriben, dando soporte a una topología de duplicación tan flexible como la empresa necesite. El distribuidor es un servidor que desempeña varios roles, en función de las opciones de duplicación escogidas. Como mínimo, se usa como repositorio de la información histórica y de los estados de error. En otros casos se usa también como cola intermedia de almacenamiento y entrega para redimensionar la entrega de la carga de duplicación a todos los suscriptores.

29.9.2 Opciones de duplicación

La duplicación de Microsoft SQL Server ofrece un amplio espectro de opciones tecnológicas. Para decidir sobre las opciones de duplicación adecuadas que se pueden usar, el diseñador de bases de datos debe determinar los requisitos de la aplicación con respecto a la operación autónoma del sitio implicado y el grado de consistencia transaccional necesario. La duplicación instantánea copia y distribuye los datos y los objetos de la base de datos exactamente como aparecen en un momento dado. La duplicación instantánea no exige un seguimiento continuo de las modificaciones, puesto que los cambios no se propagan a los suscriptores de forma incremental. Los suscriptores se actualizan de manera periódica con una renovación completa del conjunto de datos definido por la publicación. Las opciones disponibles para la duplicación instantánea pueden filtrar los datos publicados y permitir que los suscriptores modifiquen los datos duplicados y propaguen esos cambios al publicador. Este tipo de duplicación es más indicado para datos de pequeño tamaño y cuando las actualizaciones suelen afectar a suficientes datos como para que la duplicación de una renovación completa de los datos resulte eficiente. Con la duplicación transaccional el publicador propaga una instantánea inicial de los datos a los suscriptores y luego envía las modificaciones incrementales de esos datos a los suscriptores en forma de transacciones discretas y comandos. El seguimiento del cambio incremental se produce dentro del motor principal de SQL Server, que marca las transacciones que afectan a los objetos duplicados en el registro histórico de transacciones de la base de datos publicadora. Un proceso de duplicación denominado agente de lector del registro (histórico) lee estas transacciones del registro histórico de transacciones de la base de datos, aplica un filtro opcional y las almacena en la base de datos de distribución, que actúa como cola fiable que soporta el mecanismo de almacenamiento y entrega de la duplicación transaccional (el concepto de cola fiable es el mismo que el de colas duraderas descrito en el Apartado 25.1.1). Otro proceso de duplicación, denominado agente de distribución, envía luego las modificaciones a cada suscriptor. Al igual que la duplicación instantánea, la duplicación transaccional ofrece a los suscriptores la opción de realizar actualizaciones que utilicen un compromiso de dos fases que refleje esas modificaciones de forma consistente en el publicador o de colocarlas en cola en el suscriptor para su recuperación asíncrona por un proceso de duplicación que propague posteriormente la modificación al publicador. Este tipo de duplicación resulta adecuada cuando hay que conservar los estados intermedios entre varias actualizaciones. La duplicación por mezcla permite que cada duplicado de la empresa funcione con total autonomía tanto en conexión como sin conexión. El sistema realiza un seguimiento de los metadatos según las modificaciones de los objetos publicados en los publicadores y en los suscriptores de todas las bases

www.detodoprogramacion.com


908

Capítulo 29

SQL Server de Microsoft

de datos duplicadas y el agente de duplicación mezcla esas modificaciones de los datos durante la sincronización entre los pares duplicados y asegura la convergencia de los datos mediante la detección y resolución automática de los conflictos. El agente de duplicación usado en el proceso de sincronización incorpora numerosas opciones de políticas de resolución de conflictos, y se puede escribir una política de resolución de conflictos personalizada mediante el uso de procedimientos almacenados o de una interfaz extensible del modelo de objetos componentes (Component Object Model, COM). Este tipo de duplicación no duplica todos los estados intermedios, sino sólo el estado actual de los datos en el momento de la sincronización. Resulta adecuado cuando los duplicados necesitan la posibilidad de llevar a cabo actualizaciones autónomas mientras no se hallan conectadas a ninguna red. 29.10 Programación de servidores en .NET SQL Server soporta el motor común en tiempo de ejecución de lenguajes .NET (.NET Common Language Runtime, CLR) en el proceso de SQL Server para permitir que los programadores de bases de datos

escriban la lógica corporativa en forma de funciones, procedimientos almacenados, disparadores, tipos de datos y agregados. La posibilidad de ejecutar el código de las aplicaciones dentro de la base de datos añade flexibilidad al diseño de las arquitecturas de las aplicaciones que necesita que la lógica corporativa se ejecute cerca de los datos y no puede permitirse el coste de enviar los datos a un proceso de una capa intermedia para llevar a cabo el cálculo fuera de la base de datos. CLR es un entorno de tiempo de ejecución con un lenguaje intermedio de tipos fuertes que ejecuta varios lenguajes de programación modernos como C#, Visual Basic, C++, COBOL y J++, entre otros, tiene memoria con recogida de basura, hebras con derecho preferente, servicios de metadatos (reflexión de tipos), comprobación de los tipos y seguridad de acceso al código. El tiempo de ejecución usa los metadatos para localizar y cargar las clases, dejar los ejemplares en la memoria, resolver las invocaciones a los métodos, generar código nativo, hacer que se cumpla la seguridad y definir las fronteras de contexto en el tiempo de ejecución. El código de las aplicaciones se implanta en la base de datos mediante ensamblados, que son las unidades de empaquetado, implantación y versiones del código de las aplicaciones en .NET. La implantación del código de las aplicaciones en la base de datos proporciona una manera uniforme de administrar, realizar copias de seguridad de las aplicaciones de bases de datos completas y restaurarlas (el código y los datos). Una vez se ha registrado un ensamblado en la base de datos, los usuarios pueden mostrar los puntos de entrada del ensamblado mediante las instrucciones de LDD de SQL, que pueden actuar como funciones escalares o de tablas, procedimientos, disparadores, tipos y agregados mediante el uso de contratos de extensión bien definidos, que se hacen cumplir durante la ejecución de esas sentencias de LDD. Los procedimientos almacenados, los disparadores y las funciones suelen necesitar ejecutar consultas y actualizaciones de SQL. Esto se consigue mediante un componente que implementa el API de acceso a los datos ADO.NET para su uso dentro del proceso de la base de datos. 29.10.1 Conceptos básicos de .NET

En el entorno .NET los programadores escriben el código de los programas en lenguajes de programación de alto nivel que implementan clases que definen su estructura (por ejemplo, los campos o las propiedades de las clases) y sus métodos. Algunos de esos métodos pueden ser funciones estáticas. La compilación del programa genera un archivo, denominado ensamblado, que contiene el código compilado en el lenguaje intermedio de Microsoft (Microsoft Intermediate Language, MSIL) y un manifiesto que contiene todas las referencias a los ensamblados dependientes. El manifiesto es parte integral de cada ensamblado y permite que se describa a sí mismo. El manifiesto del ensamblado contiene los metadatos del ensamblado, que describen todas las estructuras, campos, propiedades, clases, relaciones de herencia, funciones y métodos definidos en el programa. El manifiesto establece la identidad del ensamblado, especifica los archivos que conforman su implementación, especifica los tipos y recursos que lo constituyen, divide en elementos las dependencias del momento de la compilación respecto de otros ensamblados y especifica el conjunto de permisos necesarios para que el ensamblado se ejecute correctamente. Esta información se usa en el momento de la ejecución para resolver las referencias, hacer que se cumpla la directiva de vinculación de versiones y validar la integridad de los ensamblados cargados. El entorno .NET sopor-

www.detodoprogramacion.com


29.10

Programación de servidores en .NET

909

Motor de SQL Server

Proceso de SQL Server

CLR Alojamiento SQLCLR Capa del SO de SQL (memoria, hebras, sincronización

Windows

Figura 29.5

Integración de CLR con los servicios de sistema operativo de SQL Server.

ta un mecanismo marginal denominado atributos personalizados para anotar las clases, las propiedades, las funciones y los métodos con información adicional o con facetas que la aplicaciones puede desear capturar en los metadatos. Todos los compiladores .NET consumen estas anotaciones sin interpretarlas y las guardan en los metadatos del ensamblado. Todas esas anotaciones se pueden examinar del mismo modo que se examina cualquier otro metadato, mediante un conjunto común de APIs de reflexión. La expresión código gestionado hace referencia al MSIL ejecutado en CLR en lugar del ejecutado directamente por el sistema operativo. Las aplicaciones de código gestionado obtienen servicios en el momento de la ejecución de lenguajes comunes como la recogida automática de basura, la comprobación de tipos durante la ejecución y el soporte de seguridad. Estos servicios ayudan a ofrecer un comportamiento de las aplicaciones de código gestionado uniforme e independiente de las plataformas y de los lenguajes. Durante la ejecución un compilador sobre la marcha (JIT, just–in–time) traduce el MSIL a código nativo (por ejemplo, código de Intel X86). Durante esa traducción el código debe pasar un proceso de comprobación que examina el MSIL y los metadatos para averiguar si el código se puede considerar de tipos seguros. 29.10.2 CLR en SQL

SQL Server y CLR son dos motores de ejecución diferentes con modelos internos de hebras, programación y gestión de la memoria diferentes. SQL Server soporta un modelo de hebras cooperativo sin derecho preferente en el que las hebras del SGBD entregan voluntariamente la ejecución de manera periódica o cuando esperan por los bloqueos o en la cola de E/S, mientras que CLR soporta un modelo de hebras preventivo. Si el código del usuario que se ejecuta en el SGBD puede llamar directamente a las primitivas de multienhebramiento (subprocesamiento en DB2) del sistema operativo (SO), no se integra bien con el programador de tareas de SQL Server y puede degradar la capacidad de redimensionamiento del sistema. CLR no distingue entre la memoria virtual y la física, mientras que SQL Server gestiona directamente

la memoria física y se le exige que utilice la memoria física dentro de unos límites configurables. Los diferentes modelos de multienhebramiento, programación y gestión de la memoria suponen un reto de integración para los SGBDs que se redimensionan para soportar millares de sesiones de usuario concurrentes. SQL Server resuelve este reto pasando a ser el sistema operativo de CLR cuando se alberga en el proceso de SQL Server. CLR llama a las primitivas de bajo nivel implantadas por SQL Server para multienhebramiento, programación, sincronización y gestión de la memoria (véase la Figura 29.5). Este enfoque proporciona las ventajas de redimensionamiento y fiabilidad siguientes. Multienhebramiento, programación y sincronización comunes. CLR llama a las APIs de SQL Server para crear hebras, tanto para ejecutar el código del usuario como para su propio uso interno, como las hebras del recogedor de basura y del destructor de clases. Para sincronizar varios hebras, CLR llama a los objetos de sincronización de SQL Server. Esto permite que el programador de SQL Server programe otras tareas mientras una hebra espera en un objeto de sincronización. Por ejemplo, cuando CLR inicia la recogida de basura, todas sus hebras esperan a que acabe la recogida de basura. Dado que las hebras de CLR y los objetos de sincronización en los que esperan son conocidos por el programador de SQL Server, puede programar hebras que estén ejecutando otras tareas de la base de datos que no impliquen

www.detodoprogramacion.com


910

Capítulo 29

SQL Server de Microsoft

a CLR. Además, esto permite que SQL Server detecte los interbloqueos que implican a los bloqueos adoptados por los objetos de sincronización de CLR y a usar técnicas tradicionales para su eliminación. El programador de SQL Server tiene la posibilidad de detectar y de detener las hebras que no hayan aportado resultados durante un periodo de tiempo significativo. La posibilidad de vincular las hebras de CLR con las hebras de SQL Server implica que el programador de SQL Server pueda identificar las hebras fuera de control que se ejecutan en CLR y gestionar su prioridad, de modo que no consuman recursos significativos de la CPU y afecten, por tanto, al flujo del sistema. Esas hebras fuera de control se suspenden y se vuelven a poner en la cola. A los infractores reincidentes no se les permiten intervalos de tiempo que sean injustos para otros trabajadores que estén ejecutando instrucciones. Si un infractor toma cincuenta veces la cantidad permitida, es castigado durante cincuenta “rondas” antes de que se le vuelva a permitir ejecutar instrucciones, ya que el programador no puede decidir si un cálculo largo está fuera de control o es legítimo. Gestión de la memoria común. CLR llama a las primitivas de SQL Server para la asignación y la desasignación de memoria. Dado que la memoria usada por CLR cuenta para el uso total de memoria del sistema, SQL Server puede seguir dentro de los límites de memoria del sistema configurados y garantizar que CLR y SQL Server no compitan entre sí por memoria. Además, SQL Server puede rechazar las solicitudes de memoria de CLR mientras el sistema está restringido y pedir al CLR que reduzca su uso de la memoria cuando otras tareas la necesiten. 29.10.3 Contratos para la extensión

Todo el código gestionado por el usuario que se ejecuta en el proceso de SQL Server interactúa con los componentes del SGBD como extensión. Entre las extensiones actuales están las funciones escalares, las tabulares, los procedimientos, los disparadores, los tipos escalares y los agregados escalares. Para cada extensión hay un contrato mutuo que define las propiedades o servicios que el código de usuario debe implementar para actuar como tal extensión, y los servicios que la extensión puede esperar del SGBD cuando se llame al código gestionado. CLR de SQL aprovecha la clase y la información de los atributos personalizados ya guardada en los metadatos del ensamblado para hacer que se cumpla que el código de usuario implemente esos contratos de extensión. Todos los ensamblados de usuario se guardan en la base de datos. Todos los metadatos relacionales y de los ensamblados se procesan en el motor de SQL mediante un conjunto uniforme de interfaces y de estructuras de datos. Cuando se procesan las instrucciones del lenguaje de definición de datos que registran una función, tipo o agregado de extensión dado, el sistema garantiza que el código de usuario implemente el contrato correspondiente mediante el análisis de los metadatos de su ensamblado. Si el contrato se implementa, la instrucción del DDL tiene éxito; en caso contrario, falla. Los subapartados siguientes describen aspectos fundamentales de los contratos concretos que SQL Server hace cumplir actualmente. 29.10.3.1 Rutinas

Las funciones escalares, los procedimientos y los disparadores se clasifican genéricamente como rutinas. Las rutinas, implementadas como métodos de clase estática, pueden especificar las propiedades siguientes mediante los atributos personalizados. • IsPrecise. Si esta propiedad binaria es false, indica que el cuerpo de la rutina comprende cálculos imprecisos como las operaciones de coma flotante. Las expresiones que implican funciones imprecisas no se pueden indexar. • UserDataAccess. Si el valor de esta propiedad es read, la rutina lee las tablas de datos de usuario. En caso contrario, el valor de la propiedad es None, lo que indica que la rutina no tiene acceso a los datos. Las consultas que no tienen acceso a las tablas de usuario (directamente o de manera indirecta mediante las vistas y las funciones) no se considera que tengan acceso a los datos de usuario. • SystemDataAccess. Si el valor de esta propiedad es read, la rutina lee los catálogos del sistema o las tablas virtuales del sistema.

www.detodoprogramacion.com


29.10

Programación de servidores en .NET

911

• IsDeterministic. Si esta propiedad es true, se da por supuesto que la rutina produce el mismo resultado, dados valores de entrada, estado de la base de datos local y contexto de ejecución iguales. • IsSystemVerified. Esto indica si SQL Server puede asegurarse de las propiedades de determinismo y de precisión o hacerlas cumplir (por ejemplo, funciones predefinidas y de Transact-SQL) o son tal y como las especifique el usuario (por ejemplo, funciones de CLR). • HasExternalAccess. Si el valor de esta propiedad es true, la rutina tiene acceso a los recursos externos a SQL Server, como los archivos, la red, el acceso Web y el registro. 29.10.3.2 Funciones que devuelven tablas

Las clases que implementan funciones que se valoran como tablas deben implementar la interfaz IEnumerable para permitir la iteración sobre las filas devueltas por la función, un método para describir el esquema de la tabla devuelta (es decir, las columnas, los tipos), un método para describir las columnas que pueden ser claves únicas y un método para insertar filas en la tabla. 29.10.3.3 Tipos

Las clases que implementan tipos definidos por los usuarios se anotan con el atributo SQLUserDefinedType(), que especifica las propiedades siguientes: • Format. SQL Server soporta tres formatos de almacenamiento: nativo, definido por el usuario y serialización .NET. • MaxByteSize. Se trata del tamaño máximo de la representación binaria serializada de los ejemplares de los tipos en bytes. • IsFixedLength. Se trata de una propiedad booleana que especifica si los ejemplares del tipo tienen longitud fija o variable. • IsByteOrdered. Se trata de una propiedad booleana que indica si la representación binaria serializada de los ejemplares del tipo tiene ordenación binaria. Cuando esta propiedad es true, el sistema puede realizar directamente comparaciones con esta representación sin necesidad de hacer que los ejemplares de los tipos sean objetos. • Nullability. Todos los UDTs del sistema deben ser capaces de guardar el valor NULL mediante el soporte de la interfaz INullable que contiene el método booleano IsNull. • Type conversions. Todos los UDTs deben implementar las conversiones de tipo directas e inversas con las cadenas de caracteres mediante los métodos ToString y Parse. 29.10.3.4 Agregados

Además de soportar los contratos de los tipos, los agregados definidos por los usuarios deben implementar cuatro métodos exigidos por el motor de ejecución de consultas para inicializar el cálculo de los ejemplares agregados, para acumular valores de entrada en la función proporcionada por el agregado, para mezclar cálculos parciales del agregado y para recuperar el resultado final del agregado. Los agregados pueden declarar propiedades adicionales mediante los atributos personalizados en su definición de clase; esas propiedades las usa el optimizador de consultas para obtener planes alternativos para el cálculo del agregado. • IsInvariantToDuplicates. Si esta propiedad es true, el cálculo que entrega los datos al agregado puede modificarse descartando o introduciendo nuevas operaciones para la eliminación de duplicados. • IsInvariantToNulls. Si esta propiedad es true, se pueden descartar las filas NULL de la entrada en algunos casos, pero hay que tener cuidado para no descartar grupos enteros.

www.detodoprogramacion.com


912

Capítulo 29

SQL Server de Microsoft

• IsInvariantToOrder. Si esta propiedad es true, el procesador de consultas puede ignorar las cláusulas order by y explorar los planes que evitan tener que ordenar los datos.

29.11 Soporte de XML en SQL Server 2005

Los sistemas de bases de datos relacionales han adoptado XML de muchas maneras diferentes durante el último par de años. La primera generación del soporte de XML en los sistemas de bases de datos relacionales estaba relacionada sobre todo con la exportación de datos relacionales en forma de XML (“publicación XML”) y en importar datos relacionales en forma de marcas de XML de nuevo a una representación relacional (“fragmentación de XML”). La situación en que más se usan estos sistemas es el intercambio de información en contextos en los que XML se usa como “formato cable” y los esquemas relacional y de XML suelen estar predefinidos de manera independiente entre sí. Para abordar esta situación, SQL Server 2005 de Microsoft ofrece y extiende la amplia funcionalidad introducida por primera vez en SQL Server 2000, como el agregador de conjuntos de filas para edición for xml el proveedor de conjuntos de filas OpenXML y la tecnología de vistas de XML basada en los esquemas anotados. Véanse las notas bibliográficas para obtener referencias que ofrezcan más información sobre las características de XML en SQL Server 2000. La fragmentación de los datos XML en esquemas relacionales puede resultar bastante difícil o ineficiente para el almacenamiento de los datos semiestructurados cuya estructura puede variar con el tiempo y para almacenar documentos. Para soportar esas aplicaciones, SQL Server 2005 añade el soporte nativo de XML basado en el tipo de datos xml de SQL:2003. La Figura 29.6 ofrece un diagrama arquitectónico de alto nivel del soporte nativo de XML en las bases de datos de SQL Server. Consiste en la posibilidad de almacenar de manera nativa XML, restringir y tipificar los datos de XML almacenados con conjuntos de esquemas de XML y consultar y actualizar los datos de XML. Para proporcionar ejecuciones de consultas eficientes se proporcionan varios tipos de índices específicos de XML. Finalmente, el soporte nativo de XML también se integra con la “fragmentación” y la “publicación” directas e inversas de los datos relacionales.

Metadatos de SQL Server

XML

Analizador de XML

Esquemas de XML colección de esquemas XML

Validación y tipificación OpenXML /nodes() modify()

tipo de datos XML (XML binario)

value()

FOR XML con directiva TYPE

Índices de SQL Server

query()

Valor de SQL

ÍNDICE XML PRINCIPAL

Tabla de nodos Ejecución de XQuery y de actualizaciones

Figura 29.6

Conjuntos de filas relacionales

índice PATH índice PROP índice VALUE

Visión general de la arquitectura del soporte nativo de XML en SQL Server.

www.detodoprogramacion.com


29.11

Soporte de XML en SQL Server 2005

913

29.11.1 Almacenamiento y organización nativos de XML

El tipo de datos xml puede guardar documentos de XML y contener fragmentos de contenido (varios nodos de texto o de elementos en la parte superior) y se define en términos del modelo de datos XQuery 1.0/XPath 2.0. Este tipo de datos se puede usar para parámetros de procedimientos almacenados, para variables y como tipo de columna. Por ejemplo, la siguiente instrucción de SQL crea una tabla de valores en la que una de las columnas es del tipo XML: create table InformesViajes(id int, fechaviaje datetime, Informe xml) El sistema de bases de datos puede decidir guardar un ejemplar del tipo xml en gran variedad de formatos, como objeto binario o carácter de gran tamaño, descompuesto en tablas o en una mezcla de formatos. SQL Server 2005 guarda los datos del tipo xml en un formato binario interno como blob y proporciona mecanismos de indexado para la ejecución de consultas. El formato binario interno proporciona una recuperación y una reconstrucción eficientes del documento de XML original, además de algún ahorro de espacio (en promedio, un veinte por ciento). Los índices soportan un mecanismo eficiente de consulta que puede usar el motor y el optimizador de consultas relacionales; se ofrecen detalles más adelante, en el Apartado 29.11.4.

29.11.2 Validación y tipi cación de tipos de datos XML

SQL Server ofrece la posibilidad de restringir el tipo de datos de XML a un conjunto de esquemas de XML. SQL Server 2005 proporciona el concepto de metadatos de las base de datos denominado conjunto de esquemas de XML, que asocia un identificador de SQL a un conjunto de componentes de esquemas

de uno o varios espacios de nombres objetivos. Por ejemplo, la expresión create xml schema collection E1 as @e crea el conjunto de esquemas XML de SQL Server de nombre E1, que consiste en los esquemas de XML contenidos en la variable de SQL @e. Cada uno de estos conjuntos contiene toda la información necesaria para llevar a cabo la validación y tipificación y se guarda en los metadatos del esquema de la base de datos. SQL Server 2005 permite asociar un conjunto de esquemas con un tipo de datos de XML y especificar si el tipo sólo puede contener documentos (de manera predeterminada puede contener fragmentos de documentos). El ejemplo siguiente muestra la definición de una tabla que restringe los ejemplares de la columna XML Informe a un documento bien formado (es decir, sólo puede contener un único elemento de nivel superior) que sea válido de acuerdo con el conjunto de esquemas EsquemaInformes de la misma base de datos: create table InformesViajes(id int, fechaviaje datetime, Informe xml(document EsquemaInforme)) La omisión de la palabra clave document permitiría que el contenido guardara varios fragmentos. Los conjuntos de esquemas también se pueden usar para validar datos de XML previamente no tipificados durante la ejecución mediante coerción de tipos: cast (@x as xml(E1))

www.detodoprogramacion.com


914

Capítulo 29

SQL Server de Microsoft

29.11.3 Consultas y actualizaciones sobre el tipo de datos XML

SQL Server 2005 ofrece varias posibilidades de consultas y de modificación basada en XQuery sobre el tipo de datos XML. Estas posibilidades de consulta y de modificación se soportan mediante los métodos

definidos para el tipo de datosxml. Algunos de estos métodos se describen en el resto de este apartado. Cada método toma el valor literal de una cadena de caracteres como cadena de caracteres de la consulta y, potencialmente, otros argumentos. El tipo de datos XML (al que se le aplica el método) ofrece el elemento de contexto para las expresiones de ruta y rellena las definiciones de esquemas correspondientes al ámbito correspondiente con toda la información de tipos proporcionada por el conjunto de esquemas de XML asociado (si no se proporciona ningún conjunto, se da por supuesto que los datos de XML no tienen ningún tipo). La implementación de XQuery de SQL Server 2005 tiene tipos estáticos, por lo que soporta la detección temprana de los errores de escritura de las expresiones de ruta, de los errores de tipos y de la no coincidencia de cardinalidades, así como algunas optimizaciones adicionales. El método query toma expresiones de XQuery y devuelve ejemplares de tipos de datos de XML sin tipo (que luego se pueden dirigir a un conjunto de esquemas objetivo si hace falta tipificar los datos). En la terminología de la especificación de XQuery se ha definido el modo de creación como “strip”. El ejemplo siguiente muestra una expresión simple de XQuery que resume un elemento Cliente complejo de un documento de informe de viaje que contiene, entre otras informaciones, un nombre, un atributo ID y posibilidades de ventas que se contienen en las notas marcadas del informe de viaje real. El resumen muestra el nombre y la información sobre ventas de los elementos Cliente que tienen posibilidades de ventas. select Informe.query(’ declare namespace c = "urn:ejemplo/cliente"; for $cli in /c:doc/c:cliente where $cli/c:notas//c:posiblesventas return <id_cliente ="$cli/@id"> { $cli/c:nombre, $cli/c:notas//c:posiblesventas }</cliente>’) from InformesViajes La consulta XQuery anterior se ejecuta para el valor XML guardado en el atributo doc de cada fila de la tabla InformesViajes. Cada fila del resultado de la consulta de SQL contiene el resultado de ejecutar la consulta de XQuery con los datos de una fila como entrada. El método value toma una expresión de XQuery y el nombre de un tipo de SQL, extrae un solo valor atómico del resultado de la expresión de XQuery y envía su forma léxica al tipo de SQL especificado. Si la expresión de XQuery da lugar a un nodo, el valor tipificado del nodo se extrae de manera implícita como valor atómico que se envía al tipo de SQL (en la terminología de XQuery, el nodo se “atomiza”; el resultado se envía a SQL). Téngase en cuenta que el método value lleva a cabo una comprobación estática de tipos comprobando que se devuelve, como máximo, un valor. Dado que el tipo estático de la expresión de ruta suele poder inferir un tipo estático más amplio, aunque la semántica dinámica sólo devuelve un valor, se recomienda usar el predicado posicional para recuperar, como máximo, un valor. El ejemplo siguiente muestra una expresión sencilla de XQuery que cuenta los elementos de pistas de ventas de cada ejemplar del tipo de datos XML y lo devuelve como valor entero de SQL: select Informe.value( ’declare namespace c = "urn:ejemplo/cliente"; count(/c:doc/c:cliente//c:posiblesventas)’, ’int’) from InformesViajes El método exist toma una expresión de XQuery y devuelve un uno si la expresión genera un resultado no vacío y un cero en caso contrario. La expresión siguiente recupera todas las filas de la tabla InformesViajes, en la que el documento contiene, como mínimo, un cliente con una posibilidad de ventas:

www.detodoprogramacion.com


29.11

Soporte de XML en SQL Server 2005

915

select Informe from InformesViajes where 1 = Informe.exist(’declare namespace c = "urn:ejemplo/cliente"; /c:doc/c:cliente//c:posiblesventas’) Hasta ahora, las expresiones siempre se aplican de un ejemplar de tipo de datos XML a un valor resultado por fila relacional. A veces, no obstante, se desea dividir un ejemplar de XML en varios subárboles, de los que cada subárbol se halla en una fila propia, para posterior procesamiento relacional y de XQuery. Esta funcionalidad la aporta el método nodes, que toma una expresión de XQuery y genera una tabla que contiene filas con una sola columna, con una fila por cada nodo que la expresión devuelve. Cada fila contiene una referencia a uno de los nodos. Dado que el tipo resultante es un tipo de referencia que no existe en SQL Server fuera del contexto de cada consulta, hay que aplicar uno de los métodos de consulta para materializar el resultado. El método query se aplica como cualquier otro tipo de datos de XML, con la diferencia de que el elemento de contexto para las expresiones de ruta no se halla en el documento raíz del tipo de datos de XML, sino en el nodo al que se hace referencia. El ejemplo siguiente extrae para cada pedido de cliente de la columna de XML una fila que contiene la representación de XML del cliente, el nombre del cliente, el identificador del pedido y el identificador del documento que contiene al cliente: select N1.cliente.query(’.’) as Cliente, N1.cliente.value( ’declare namespace c = "urn:ejemplo/cliente"; c:nombre[1]’, ’nvarchar(20)’) as NombreCliente, N2."pedido".value(’@id’, ’int’) as IDPedido, N1.cliente.value(’../@id’, ’nvarchar(5)’) as IDDoc from InformesViajes cross apply InformesViajes.Informe.nodes( ’declare namespace c = "urn:ejemplo/cliente"; /c:doc/c:cliente’) as N1(cliente) cross apply N1.cliente.nodes( ’declare namespace c = "urn:ejemplo/cliente"; ./c:pedido’) as N2("pedido") Obsérvese que esto es parecido a la funcionalidad de OpenXML que proporcionan tanto SQL Server 2000 como SQL Server 2005, con la diferencia de que la expresión del método nodes está integrada en el procesamiento de XQuery. Para tener acceso a los datos de SQL del interior de las expresiones de XQuery, SQL Server 2005 proporciona dos funciones denominadas sql:variable($variable as xs:string) y sql:column($columna as xs:string). Cada una de estas funciones toma el valor literal de una cadena de caracteres constante para hacer referencia a la variable de SQL o al valor de la columna correlacionada. Finalmente, el método modify proporciona un mecanismo para modificar el valor de XML en el nivel de subárboles. SQL Server 2005 permite insertar subárboles nuevos en ubicaciones concretas de cada árbol, modificar el valor de un elemento de un atributo y borrar subárboles. El ejemplo siguiente borra todos los elementos posiblesventas de los años anteriores al año proporcionado por una variable o por un parámetro de SQL de nombre @año: update InformesViajes set Informe.modify( ’declare namespace c = "urn:ejemplo/cliente"; delete /c:doc/c:cliente//c:posiblesventas[@año < sql:variable("@año")]’) 29.11.4 Ejecución de expresiones XQuery

Como ya se ha mencionado antes, los datos XML se guardan en una representación binaria interna. Sin embargo, para poder ejecutar las expresiones de XQuery, el tipo de datos XML se transforma internamente en una tabla denominada de nodos. La tabla de nodos interna usa básicamente una fila para

www.detodoprogramacion.com


916

Capítulo 29

SQL Server de Microsoft

representar cada nodo. Cada nodo recibe un identificador OrdPath como identificador de nodo (los identificadores OrdPath son esquemas numéricos decimales Dewey modificados; véanse las notas bibliográficas para obtener referencias de más información sobre OrdPath). Cada nodo contiene también información de las claves para volver a apuntar a la fila de SQL original a la que pertenece el nodo, información sobre el nombre y el tipo (en forma simbólica), los valores, etc. Dado que OrdPath codifica tanto el orden de los documentos como la información de las jerarquías, la tabla de nodos se agrupa en términos de la información de las claves y de OrdPath, de modo que se pueda conseguir una expresión de ruta o la recomposición de un subárbol con la mera exploración de una tabla. Todas las expresiones de XQuery y de actualización se traducen luego en un árbol de operadores algebraicos con la tabla de nodos interna; el árbol usa los operadores relacionales habituales y algunos operadores diseñados de manera específica para la algebrización de XQuery. El árbol resultante se injerta en el árbol algebraico de la expresión relacional de modo que, al final, el motor de ejecución de consultas recibe un solo árbol de ejecución que puede optimizar y ejecutar. Para evitar las costosas transformaciones en el momento de la ejecución los usuarios pueden materializar anticipadamente la tabla de nodos usando el índice principal de XML. SQL Server 2005, además, proporciona tres índices secundarios de XML, de modo que la ejecución de las consultas pueda aprovecharse más aún de las estructuras de índices: • El índice path (ruta) ofrece soporte para los tipos sencillos de expresiones de ruta. • El índice properties (propiedades) ofrece soporte para la situación frecuente de las comparaciones entre valores de las propiedades. • El índice value (valor) es idóneo si la consulta usa comodines en las comparaciones. Véanse las notas bibliográficas para hallar referencias a más información sobre el indexado de XML y el procesado de consultas de XML en SQL Server 2005.

29.12 Service Broker de SQLServer

Service Broker ayuda a los desarrolladores a crear aplicaciones distribuidas de acoplamiento laxo al proporcionar soporte para la mensajería encolada y de confianza en SQL Server. Muchas aplicaciones de bases de datos usan el procesamiento asíncrono para mejorar la posibilidad de redimensionamiento y los tiempos de respuesta de las sesiones interactivas. Un enfoque habitual del procesamiento asíncrono es el uso de tablas de trabajos. En lugar de llevar a cabo todo el trabajo de un proceso corporativo en una sola transacción de la base de datos, la aplicación realiza una modificación que indica que hay presente trabajo destacado y luego inserta un registro del trabajo que hay que llevar a cabo en una tabla de trabajos. Cuando los recursos disponibles lo permiten, la aplicaciones procesa la tabla de trabajos y completa el proceso corporativo. Service Broker forma parte del servidor de bases de datos que soporta directamente este enfoque del desarrollo de aplicaciones. El lenguaje Transact-SQL incluye instrucciones de LDD y de LMD para Service Broker. Las tecnologías anteriores de encolado de mensajes se concentraban en cada uno de los mensajes. Con Service Broker la unidad básica de comunicación es la conversación —un flujo de mensajes persistente, digno de confianza, de tipo dúplex completo. SQL Server garantiza que los mensajes de cada conversación se entregan a la aplicación exactamente una vez y por su orden. Cada conversación forma parte de un grupo de conversaciones. Las conversaciones relacionadas se pueden asociar al mismo grupo de conversaciones. Las conversaciones tienen lugar entre dos servicios. Cada servicio es un punto final con nombre de una conversación. Las conversaciones y los mensajes tienen tipos fuertes. Cada mensaje tiene un tipo concreto. SQL Server puede, opcionalmente, validar que los mensajes constituyen XML bien formado, que los mensajes están vacíos o que un mensaje dado está conforme con un esquema de XML. Un contrato define los tipos de mensaje admisibles para cada conversación y los participantes en esa conversación que pueden enviar mensajes de ese tipo. SQL Server ofrece un contrato y un tipo de mensajes predeterminados para las aplicaciones que sólo necesitan un flujo digno de confianza.

www.detodoprogramacion.com


29.12

Service Broker de SQLServer

917

SQL Server guarda los mensajes en tablas internas. Estas tablas no son accesibles directamente; en vez de esto, SQL Server muestra las colas como vistas de esas tablas internas. Las aplicaciones reciben mensajes de las colas. La operación receive (recibir) devuelve uno o varios mensajes del mismo grupo de conversaciones. Al controlar el acceso a la tabla subyacente, SQL Server puede hacer que se cumplan de manera eficiente la ordenación de los mensajes, la correlación de los mensajes relacionados y los bloqueos. Como las colas son tablas internas, las colas no necesitan ningún tratamiento especial para las copias de seguridad, las restauraciones, los relevos ni las copias exactas de las bases de datos. Tanto las tablas de las aplicaciones como los mensajes encolados asociados se incluyen en las copias de seguridad, se restauran y se relevan con la base de datos. Las conversaciones de Broker que se producen en las bases de datos con copias exactas continúan cuando parten al completarse el relevo de la copia exacta —aunque la conversación se produjera entre dos servicios ubicados en bases de datos diferentes. La granularidad de los bloqueos de las operaciones de Service Broker es el grupo de conversaciones, en vez de una conversación concreta o los diferentes mensajes. Al hacer que se cumplan los bloqueos de los grupos de conversación, Service Broker ayuda de manera automática a que las aplicaciones eviten problemas de concurrencia al procesar los mensajes. Cuando una cola contiene varias conversaciones, SQL Server garantiza que sólo un lector de colas pueda procesar los mensajes que pertenecen a un grupo de conversación dado a la vez. Esto elimina la necesidad de que las propias aplicaciones incluyan lógica para evitar los interbloqueos—una fuente de errores habitual en muchas aplicaciones de mensajería. Otro efecto lateral positivo de esta semántica de bloqueos es que las aplicaciones pueden decidir usar el grupo de conversaciones como clave para guardar y recuperar el estado de las aplicaciones. Estas ventajas del modelo de programación no son más que dos ejemplos de las ventajas que se obtienen de la decisión de formalizar la conversación como primitiva de la comunicación en lugar de la primitiva de los mensajes atómicos usada en los sistemas de encolado de mensajes tradicionales. SQL Server puede activar de manera automática los procedimientos almacenados cuando una cola contiene mensajes que hay que procesar. Para adecuar el número de procesos almacenados en ejecución al tráfico entrante, la lógica de activación supervisa la cola para ver si hay trabajo útil para otro lector de colas. SQL Server considera tanto la velocidad a la que los lectores existentes reciben los mensajes como el número de grupos de conversaciones disponibles para decidir si debe iniciar otro lector de colas. El procedimiento almacenado que se debe activar, el contexto de seguridad del procedimiento almacenado y el número máximo de ejemplares que se pueden iniciar se configuran para una cola dada. SQL Server también muestra un evento que pueden usar las aplicaciones externas para iniciar los lectores de colas. Como extensión lógica de la mensajería asíncrona dentro del ejemplar, Service Broker también ofrece mensajería digna de confianza entre ejemplares de SQL Server para permitir que los desarrolladores creen aplicaciones distribuidas con facilidad. Las conversaciones pueden tener lugar dentro de un solo ejemplar de SQL Server o entre dos ejemplares de SQL Server. Las conversaciones locales y las remotas usan el mismo modelo de programación. La seguridad y el encaminamiento se configuran de manera declarativa, sin necesidad de modificaciones de los lectores de colas. SQL Server usa rutas para asignar un nombre de servicio a la dirección de red del otro participante en la conversación. SQL Server también puede llevar a cabo entregas de mensajes y equilibrios de carga sencillos para las conversaciones. SQL Server ofrece entregas dignas de confianza, sólo una vez y en su orden, independientemente del número de ejemplares por los que tengan que viajar los mensajes. Las conversaciones que abarcan varios ejemplares de SQL Server se pueden proteger tanto en el nivel de la red (de punto a punto) como en el nivel de la conversación (de extremo a extremo). Cuando se usa la seguridad de extremo a extremo, el contenido de los mensajes permanece cifrado hasta que llega a su destino final, mientras que las cabeceras están disponibles para cada ejemplar de SQL Server por el que viaje cada mensaje. Los permisos estándar de SQL Server se aplican dentro de cada ejemplar. El cifrado se produce cuando los mensajes dejan un ejemplar. SQL Server usa un protocolo binario para el envío de mensajes entre ejemplares. El protocolo fragmenta los mensajes de gran tamaño y permite que se intercalen los fragmentos de varios mensajes. La fragmentación permite que SQL Server transmita rápidamente los mensajes más pequeños, aun en el caso de que se esté transmitiendo un mensaje de gran tamaño. El protocolo binario no usa las transacciones distribuidas ni el compromiso de dos fases. En vez de eso, exige que un receptor reconozca los fragmentos de los mensajes. SQL Server se limita a volver a intentar enviar periódicamente los fragmentos de los mensajes hasta que el receptor los reconoce. Los reconocimientos se incluyen muy frecuentemente como

www.detodoprogramacion.com


918

Capítulo 29

SQL Server de Microsoft

parte de la cabecera de los mensajes devueltos, aunque se utilicen mensajes de vuelta exclusivos si no se dispone de ningún otro. 29.13 Almacenes de datos e inteligencia de negocio

El componente de almacenamiento de datos e inteligencia de negocio de SQL Server contiene tres componentes: • Los servicios de integración de SQL Server (SQL Server Integration Services, SSIS), antes conocidos como Servicios de transformación de datos (Data Transformation Services, DTS), que ofrecen los medios para integrar datos de varios orígenes, llevan a cabo transformaciones relacionadas con la limpieza de los datos y su transformación a un formato común y la carga de los datos en el sistema de bases de datos. • Los servicios de análisis de SQL Server (SQL Server Analysis Services, SSAS), que proporcionan las capacidades OLAP y de minería de datos. • Los servicios de informes de SLQ Server (SQL Server Reporting Services, SSRS). Los servicios de integración, los de análisis y los de informes se implementan en servidores diferentes y se pueden instalar de manera independiente en la misma máquina o en máquinas diferentes. Pueden conectar con gran variedad de orígenes de datos, como los archivos planos, las hojas de cálculo o gran variedad de sistemas de bases de datos relacionales, mediante conectores nativos, OLE-DB o controladores ODBC. En conjunto ofrecen una solución integrada para la extracción, transformación y carga de los datos, el modelado y la adición de capacidad analítica posteriores a los datos y, finalmente, la creación y distribución de informes de los datos. Los diversos componentes del servidor de análisis pueden integrarse entre sí y aprovechar las capacidades de los demás. A continuación se muestran unas cuantas situaciones que aprovechan diferentes combinaciones de componentes: • Creación de un paquete SSIS que limpie los datos, usando patrones generados por la minería de datos de SSAS. • El uso de SSIS para cargar datos en un cubo de SSAS, su procesamiento y la ejecución de informes relativos al cubo de SSAS. • Creación de un informe de SSRS para publicar los hallazgos de un modelo de minería o los datos contenidos en un componente OLAP de SSAS. Los apartados siguientes aportan una visión general de las posibilidades y de la arquitectura de estos componentes de los servidores. 29.13.1 SQL Server Integration Services

SQL Server 2005 Integration Services (SSIS) de Microsoft es una solución corporativa para la transformación y la integración de datos que se puede usar para extraer, transformar, agregar y consolidar datos de diferentes orígenes y trasladarlos a uno o a varios destinos. Se puede usar SSIS para llevar a cabo las tareas siguientes:

• Mezclar datos de almacenes de datos heterogéneos • Refrescar los datos de los almacenes y puestos de datos. • Limpiar los datos antes de cargarlos en sus destinos. • Realizar cargas masivas de datos en bases de datos de procesamiento de transacciones en línea (Online Transaction Processing, OLTP) y de procesamiento analítico en línea (Online Analytical Processing, OLAP). • Enviar notificaciones.

www.detodoprogramacion.com


29.13

Figura 29.7

Almacenes de datos e inteligencia de negocio

919

Carga de datos usando búsquedas difusas.

• Incluir inteligencia de negocio en el proceso de transformación de los datos. • Automatizar las funciones administrativas. SSIS ofrece un conjunto completo de servicios, herramientas gráficas, objetos programables y APIs para estas tareas. Todo ello ofrece la posibilidad de crear soluciones de transformación de los datos de gran tamaño, robustas y complejas sin necesidad de programación personalizada. No obstante, se dispone de APIs y de objetos programables cuando son necesarios para crear elementos personalizados o para integrar las posibilidades de transformación de los datos en aplicaciones personalizadas. El motor de flujo de datos de SSIS ofrece las memorias intermedias ubicadas en la memoria que trasladan los datos desde su origen hasta su destino y llama a los adaptadores de orígenes que extraen los datos de los archivos y de las bases de datos relacionales. El motor también proporciona las transformaciones que modifican los datos y los adaptadores de destinos que cargan los datos en los almacenes de datos. La eliminación de duplicados basada en la coincidencia difusa (aproximada) es un ejemplo de transformación proporcionada por SSIS. Los usuarios pueden programar sus propias transformaciones si hace falta. La Figura 29.7 muestra un ejemplo de combinación de varias transformaciones para la limpieza y carga de información sobre ventas de libros; los títulos de los libros de los datos de venta se comparan con la base de datos de publicaciones y, en caso de que no coincidan, se lleva a cabo una búsqueda difusa para manejar los títulos con errores sin importancia (como los de escritura). La información sobre la confianza y la correlación de los datos se guarda con los datos limpios. 29.13.2 SQL Server Analysis Services

El componente de servicios de análisis proporciona la funcionalidad de procesamiento analítico en línea (On– Line Analytical Processing, OLAP) y de minería de datos para las aplicaciones de inteligencia de

www.detodoprogramacion.com


920

Capítulo 29

SQL Server de Microsoft

negocio. Los servicios de análisis soportan una arquitectura de cliente reducida. El motor de cálculo se halla en el servidor, por lo que las consultas se resuelven allí, lo que evita la necesidad de transferir grandes cantidades de datos entre el cliente y el servidor. 29.13.2.1 SQL Server Analysis Services: OLAP

Los servicios de análisis (Analysis Services) de SQL Server 2005 introducen un modelo dimensional unificado (Unified Dimensional Model, UDM) que salva el hueco entre los informes relacionales tradicionales y el análisis OLAP ad hoc. El papel del modelo dimensional unificado es ofrecer un puente entre el usuario y los orígenes de datos. Los UDMs se crean sobre uno o varios orígenes físicos de datos y luego el usuario final formula consultas al UDM, usando gran variedad de herramientas de cliente, como Microsoft Excel. Además de ser una capa de modelado dimensional de los esquemas DataSource, el UDM proporciona un rico entorno para la definición de lógica, reglas y definiciones semánticas corporativas potentes pero exhaustivas. Los usuarios pueden examinar y generar informes de los datos del UDM en su idioma nativo (por ejemplo, francés o hindi) mediante la definición de la traducción al lenguaje local del catálogo de metadatos y de los datos dimensionales. El servidor de análisis define dimensiones temporales complejas (fiscal, informes, fabricación, etc.) y permite la definición de lógica corporativa multidimensional potente (crecimiento interanual, en el año en curso) mediante el lenguaje de expresiones multidimensionales (MDX). El UDM permite que los usuarios definan perspectivas orientadas al negocio, cada una de las cuales sólo presenta el subconjunto concreto del modelo (medidas, dimensiones, atributos, reglas corporativas, etc.) que es relevante para un grupo determinado de usuarios. Las empresas suelen definir indicadores de rendimiento cruciales (key performance indicators, KPIs), que son métricas importantes que se usan para medir la prosperidad del negocio. Ejemplos de esos KPIs son las ventas, los ingresos por empleado y la tasa de retención de los clientes. El UDM permite definir esos KPIs, lo que permite una agrupación y presentación de los datos mucho más comprensibles. 29.13.2.2 SQL Server Analysis Services: minería de datos

SQL Server 2005 proporciona gran variedad de técnicas de minería, con una rica interfaz gráfica para ver

los resultados de la minería. Algunos de los algoritmos soportados son: • Las reglas de asociación (útiles para las aplicaciones de ventas cruzadas). • Las técnicas de clasificación y predicción, como los árboles de decisión, los árboles de regresión, las redes neuronales y la lógica de Bayes ingenua. • La predicción mediante series temporales. • Las técnicas de agrupación como la maximización de esperanzas y las medias k (acopladas con técnicas de agrupación de secuencias). SQL Server También soporta las Extensiones de minería de datos (Data–Mining Extensions, DMX) de SQL. DMX es el lenguaje usado para interactuar con los modelos de minería de datos, igual que SQL se usa para interactuar con las tablas y con las vistas. Con DMX se pueden crear, entrenar y almacenar modelos

en bases de datos de los servicios de análisis. El modelo se puede examinar luego para buscar patrones o, mediante una sintaxis especial de reunión de predicciones (prediction join), aplicada a los datos nuevos, llevar a cabo predicciones. El lenguaje DMX soporta funciones y estructuras para determinar con facilidad las clases predichas, junto con su confianza, predecir una lista de elementos asociados, como en los motores de recomendaciones, o, incluso, devolver información y hechos que apoyen las predicciones. La minería de datos en SQL Server 2005 se puede usar con datos guardados en bases de datos relacionales o en orígenes de datos multidimensionales. Se soportan también otros orígenes de datos mediante tareas y transformaciones especializadas, lo que permite la minería de datos directamente en el cauce de datos operativo de los servicios de integración. Los resultados de la minería de datos se pueden exponer en controles gráficos, dimensiones especiales de minería de datos de los cubos OLAP o, simplemente, en los informes de los servicios de informes.

www.detodoprogramacion.com


Notas bibliográficas

921

29.13.3 SQL Server Reporting Services

Los servicios de informes (Reporting Services) son una nueva plataforma de informes basada en servidor que se puede usar para crear y gestionar informes tabulares, matriciales, gráficos y de formato libre que contengan datos de orígenes de datos relacionales y multidimensionales. Los informes creados se pueden ver y gestionar mediante conexiones basadas en Web. Los informes matriciales pueden resumir datos de revisiones de alto nivel, mientras que ofrecen detalles de apoyo en los informes de minería. Los informes parametrizados se pueden usar para filtrar datos en términos de los valores que se proporcionen en el momento de la ejecución. Los usuarios pueden escoger entre gran variedad de formatos de vistas para presentar los informes sobre la marcha en los formatos preferidos para el tratamiento de datos o para la impresión. También se dispone de una API para extender o integrar capacidades de elaboración de informes en soluciones personalizadas. Los informes basados en los servidores ofrecen una manera de centralizar el almacenamiento y la gestión de los informes, definir políticas y proteger el acceso a los informes y a las carpetas, controlar la manera en que se procesan y distribuyen los informes y normalizar el modo en que se usan los informes en la empresa. Notas bibliográ cas

En www.microsoft.com/Downloads/Release.asp?ReleaseID=25503 se dispone de información detallada sobre el uso de sistemas certificados C2 con SQL Server. El entorno de optimización de SQL Server se basa en el prototipo de optimizador Cascades, que propuso Graefe [1995]. Simmen et al. [1996] estudian el esquema para la reducción de las columnas de agrupación. Galindo-Legaria y Joshi [2001] presentan la gran variedad de estrategias de ejecución que SQL Server considera durante la optimización basada en costes. Chaudhuri et al. [1999] estudian información adicional sobre los aspectos de ajuste automático de SQL Server. Chaudhuri y Shim [1994] y Yan y Larson [1995] estudian la agregación parcial. Chatziantoniou y Ross [1997] y Galindo-Legaria y Joshi [2001] propusieron la alternativa usada por SQL Server para las consultas de SQL que necesitan una autorreunión. Según este esquema, el optimizador detecta el patrón y considera la ejecución segmento por segmento. Pellenkoft et al. [1997] estudian el esquema de optimización para la generación del espacio completo de búsqueda mediante un conjunto de transformaciones que son completas, locales y no redundantes. Graefe et al. [1998] ofrecen la discusión relativa a las operaciones de asociación que soportan la agregación y la reunión básicas, con varias optimizaciones, extensiones y ajustes dinámicos del sesgo de los datos. Graefe et al. [1998] presentan la idea de reunir los índices con el único propósito de ensamblar una fila con el conjunto de columnas necesario para la consulta. Arguyen que esto a veces resulta más rápido que explorar la tabla base. Blakeley [1996] y Blakeley y Pizzo [2001] estudian la comunicación con el motor de almacenamiento mediante OLE-DB. Blakeley et al. [2005] detallan la implementación de las capacidades de consulta distribuida y heterogénea de SQL Server. Acheson et al. [2004] proporcionan detalles sobre la integración de CLR de .NET dentro del proceso de SQL Server. La norma SQL:2003 se define en SQL/XML [2004]. Rys [2001] proporciona más detalles sobre la funcionalidad XML de SQL Server 2000 XML. Rys [2004] ofrece una visión general de las extensiones de la agregación for xml. Para obtener más información sobre las capacidades XML que se pueden usar en el lado del cliente o dentro de CLR, consúltese la colección de libros blancos de MSDN: XML Developer Center (Centro de desarrollo XML de MSDN). El modelo de datos XQuery 1.0/XPath 2.0 se define en Walsh et al. [2004]. Rys [2003] proporciona una visión general de las técnicas de implementación de XQuery en el contexto de las bases de datos relacionales. El esquema de numeración OrdPath se describe en O’Neil et al. [2004]; Pal et al. [2004] y Baras et al. [2005] ofrecen más información sobre el indexado de XML, la algebrización de XQuery y la optimización en SQL Server 2005.

www.detodoprogramacion.com


www.detodoprogramacion.com


Bibliografía

[Abiteboul et al. 1995] S. Abiteboul, R. Hull y V. Vianu, Foundations of Databases, Addison Wesley (1995). [Abiteboul et al. 2003] S. Abiteboul, R. Agrawal, P. A. Bernstein, M. J. Carey et al. “The Lowell Database Research Self Assessment”. CoRR cs.DB/0310006 (2003). [Acharya et al. 1995] S. Acharya, R. Alonso, M. Franklin y S. Zdonik, “Broadcast Disks: Data Management for Asymmetric Communication Environments”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 19 – 210. También aparece en Imielinski y Korth [1996], Capítulo 12. [Acheson et al. 2004] A. Acheson, M. Bendixen, J. A. Blakeley, I. P. Carlin, E. Ersan, J. Fang, X. Jiang, C. Kleinerman, B. Rathakrishnan, G. Schaller, B. Sezgin, R. Venkatesh y H. Zhang, “Hosting the .NET Runtime in Microsoft SQL Server”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004), páginas 860–865. [Adali et al. 1996] S. Adali, K. S. Candan, Y. Papakonstantinou y V. S. Subrahmanian, “Query Caching and Optimization in Distributed Mediator Systems”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996), páginas 137–148. [Agarwal et al. 1996] S. Agarwal, R. Agrawal, P. M. Deshpande, A. Gupta, J. F. Naughton, R. Ramakrishnan y S. Sarawagi, “On the Computation of Multidimensional Attributes”, Proc. of the International Conf. on Very Large Databases, Bombay, India (1996), páginas 506–521. [Agrawal et al. 1992] R. Agrawal, S. P. Ghosh, T. Imielinski, B. R. Iyer y A. N. Swami, “An Interval Classifier for Database Mining Applications”, Proc. of the International Conf. on Very Large Databases (1992), páginas 560–573. [Agrawal et al. 1993a] R. Agrawal, T. Imielinski y A. Swami, “Mining Association Rules between Sets of Items in Large Databases”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993).

[Agrawal et al. 1993b] R. Agrawal, T. Imielinski y A. N. Swami, “Database Mining: A Performance Perspective”, IEEE Transactions on Knowledge and Data Engineering, volumen 5, número 6 (1993), páginas 914–925. [Agrawal et al. 2000] S. Agrawal, S. Chaudhuri y V. R. Narasayya, “Automated Selection of Materialized Views and Indexes in SQL Databases”, Proc. of the International Conf. on Very Large Databases (2000), páginas 496–505. [Agrawal et al. 2002] S. Agrawal, S. Chaudhuri y G. Das, “DBXplorer: A System for Keyword-Based Search over Relational Databases”, Proc. of the International Conf. on Data Engineering (2002). [Agrawal et al. 2004] S. Agrawal, S. Chaudhuri, L. Kollar, A. Marathe, V. Narasayya y M. Syamala, “Database Tuning Advisor for Microsoft SQL Server 2005”, Proc. of the International Conf. on Very Large Databases (2004). [Agrawal y Srikant 1994] R. Agrawal y R. Srikant, “Fast Algorithms for Mining Association Rules in Large Databases”, Proc. of the International Conf. on Very Large Databases (1994), páginas 487–499. [Aho et al. 1979a] A. V. Aho, C. Beeri y J. D. Ullman, “The Theory of Joins in Relational Databases”, ACM Transactions on Database Systems, volumen 4, número 3 (1979), páginas 297–314. [Aho et al. 1979b] V. Aho, Y. Sagiv y J. D. Ullman, “Equivalences among Relational Expressions”, SIAM Journal of Computing, volumen 8, número 2 (1979), páginas 218–246. [Aho et al. 1986] A. V. Aho, R. Sethi y J. D. Ullman, Compilers: Principles, Techniques, and Tools, Addison Wesley (1986). [Ailamaki et al. 2001] A. Ailamaki, D. J. DeWitt, M. D. Hill y M. Skounakis, “Weaving Relations for Cache Performance”, Proc. of the International Conf. on Very Large Databases (2001), páginas 169–180. 923

www.detodoprogramacion.com


924

Bibliografía

[Alonso y Korth 1993] R. Alonso y H. F. Korth, “Database System Issues in Nomadic Computing”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993), páginas 388–392. [Amer-Yahia et al. 2004] S. Amer-Yahia, C. Botev y J. Shanmugasundaram, “TeXQuery: A Full-Text Search Extension to XQuery”, Proc. of the International World Wide Web Conf. (2004). [Anderson et al. 1992] D. P. Anderson, Y. Osawa y R. Govindan, “A File System for Continuous Media”, ACM Transactions on Database Systems, volumen 10, número 4 (1992), páginas 311–337. [Anderson et al. 1998] T. Anderson, Y. Breitbart, H. F. Korth y A. Wool, “Replication, Consistency and Practicality: Are These Mutually Exclusive?”, Proc. of the ACM SIGMOD Conf. on Management of Data, Seattle, WA (1998). [ANSI 1986] American National Standard for Information Systems: Database Language SQL. American National Standards Institute. FDT, ANSI X3,135–1986 (1986). [ANSI 1989] Database Language SQL with Integrity Enhancement, ANSI X3, 135–1989. American National Standards Institute, New York. Also availabe as ISO/IEC Document 9075:1989 (1989). [ANSI 1992] Database Language SQL, ANSI X3,135–1992. American National Standards Institute, New York. Also available as ISO/IEC Document 9075:1992 (1992). [Antoshenkov 1995] G. Antoshenkov, “Byte-aligned Bitmap Compression (poster abstract)”, IEEE Data Compression Conf. (1995). [Appelt y Israel 1999] D. E. Appelt y D. J. Israel, “Introduction to Information Extraction Technology”, IJCAI (1999). Tutorial presented at IJCAI-99, available at http://www.ai.sri.com/ãppelt/ie-tutorial/IJCAI99.pdf. [Apt y Pugin 1987] K. R. Apt y J. M. Pugin, “Maintenance of Stratified Database Viewed as a Belief Revision System”, Proc. of the ACM Symposium on Principles of Database Systems (1987), páginas 136–145. [Armstrong 1974] W. W. Armstrong, “Dependency Structures of Data Base Relationships”, Proc. of the 1974 IFIP Congress (1974), páginas 580–583. [Astrahan et al. 1976] M. M. Astrahan, M. W. Blasgen, D. D. Chamberlin, K. P. Eswaran, J. N. Gray, P. P. Griffiths, W. F. King, R. A. Lorie, P. R. McJones, J. W. Mehl, G. R. Putzolu, I. L. Traiger, B. W. Wade y V. Watson, “System R, A Relational Approach to Data Base Management”, ACM Transactions on Database Systems, volumen 1, número 2 (1976), páginas 97– 137. [Atreya et al. 2002] M. Atreya, B. Hammond, S. Paine, P. Starrett y S. Wu, Digital Signatures, RSA Press (2002).

[Atzeni y Antonellis 1993] P. Atzeni y V. D. Antonellis, Relational Database Theory, Benjamin Cummings, Menlo Park (1993). [Baeza-Yates y Ribeiro-Neto 1999] R. Baeza-Yates y B. RibeiroNeto, Modern Information Retrieval, Addison Wesley (1999). [Bancilhon et al. 1989] F. Bancilhon, S. Cluet y C. Delobel, “A Query Language for the O2 Object-Oriented Database”, Proc. of the Second Workshop on Database Programming Languages (1989). [Bancilhon y Buneman 1990] F. Bancilhon y P. Buneman, Advances in Database Programming Languages, ACM Press, New York (1990). [Banerjee et al. 2000] S. Banerjee, V. Krishnamurthy, M. Krishnaprasad y R. Murthy, “Oracle 8i - The XML Enabled Data Management System”, Proc. of the International Conf. on Data Engineering (2000), páginas 561–568. [Baras et al. 2005] A. Baras, D. Churin, I. Cseri, T. Grabs, E. Kogan, S. Pal, M. Rys y O. Seeliger. “Implementing XQuery in a Relational Database System”. to be published (2005). [Barbará y Imielinski 1994] D. Barbará y T. Imielinski, “Sleepers and Workaholics: Caching Strategies in Mobile Environments”, Proc. of the ACM SIGMOD Conf. on Management of Data (1994), páginas 1–12. [Baru et al. 1995] C. Baru et al., “DB2 Parallel Edition”, IBM Systems Journal, volumen 34, número 2 (1995), páginas 292– 322. [Bassiouni 1988] M. Bassiouni, “Single-site and Distributed Optimistic Protocols for Concurrency Control”, IEEE Transactions on Software Engineering, volumen SE-14, número 8 (1988), páginas 1071–1080. [Batini et al. 1992] C. Batini, S. Ceri y S. Navathe, Database Design: An Entity-Relationship Approach, Benjamin Cummings, Redwood City (1992). [Bayer 1972] R. Bayer, “Symmetric Binary B-trees: Data Structure and Maintenance Algorithms”, Acta Informatica, volumen 1, número 4 (1972), páginas 290–306. [Bayer et al. 1978] R. Bayer, R. M. Graham y G. Seegmuller, editores, Operating Systems: An Advanced Course, Springer Verlag (1978). [Bayer et al. 1980] R. Bayer, H. Heller y A. Reiser, “Parallelism and Recovery in Database Systems”, ACM Transactions on Database Systems, volumen 5, número 2 (1980), páginas 139–156. [Bayer y McCreight 1972] R. Bayer y E. M. McCreight, “Organization and Maintenance of Large Ordered Indices”, Acta Informatica, volumen 1, número 3 (1972), páginas 173–189. [Bayer y Schkolnick 1977] R. Bayer y M. Schkolnick, “Concurrency of Operating on B-trees”, Acta Informatica, volumen 9, número 1 (1977), páginas 1–21.

www.detodoprogramacion.com


Bibliografía

[Bayer y Unterauer 1977] R. Bayer y K. Unterauer, “Prefix Btrees”, ACM Transactions on Database Systems, volumen 2, número 1 (1977), páginas 11–26. [Beckmann et al. 1990] N. Beckmann, H. P. Kriegel, R. S¨chneider y B. Seeger, “The R∗ -tree: An Efficient and Robust Access Method for Points and Rectangles”, Proc. of the ACM SIGMOD Conf. on Management of Data (1990), páginas 322–331. [Beeri et al. 1977] C. Beeri, R. Fagin y J. H. Howard, “A Complete Axiomatization for Functional and Multivalued Dependencies”, Proc. of the ACM SIGMOD Conf. on Management of Data (1977), páginas 47–61. [Bello et al. 1998] R. G. Bello, K. Dias, A. Downing, J. F. Jr., W. D. Norcott, H. Sun, A. Witkowski y M. Ziauddin, “Materialized Views in Oracle”, Proc. of the International Conf. on Very Large Databases (1998), páginas 659–664. [Bentley 1975] J. L. Bentley, “Multidimensional Binary Search Trees Used for Associative Searching”, Communications of the ACM, volumen 18, número 9 (1975), páginas 509–517. [Berenson et al. 1995] H. Berenson, P. Bernstein, J. Gray, J. Melton, E. O’Neil y P. O’Neil, “A Critique of ANSI SQL Isolation Levels”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 1–10. [Bernstein et al. 1983] P. A. Bernstein, N. Goodman y M. Y. Lai, “Analyzing Concurrency Control when User and System Operations Differ”, IEEE Transactions on Software Engineering, volumen SE-9, número 3 (1983), páginas 233–239. [Bernstein et al. 1987] A. Bernstein, V. Hadzilacos y N. Goodman, Concurrency Control and Recovery in Database Systems, Addison Wesley (1987). [Bernstein et al. 1998] P. Bernstein, M. Brodie, S. Ceri, D. DeWitt, M. Franklin, H. Garcia-Molina, J. Gray, J. Held, J. Hellerstein, H. V. Jagadish, M. Lesk, D. Maier, J. Naughton, H. Pirahesh, M. Stonebraker y J. Ullman, “The Asilomar Report on Database Research”, ACM SIGMOD Record, volumen 27, número 4 (1998). [Bernstein y Goodman 1980] P. A. Bernstein y N. Goodman, “Timestamp-based Algorithms for Concurrency Control in Distributed Database Systems”, Proc. of the International Conf. on Very Large Databases (1980), páginas 285–300.

925

[Bernstein y Newcomer 1997] P. A. Bernstein y E. Newcomer, Principles of Transaction Processing, Morgan Kaufmann (1997). [Berson et al. 1995] S. Berson, L. Golubchik y R. R. Muntz, “Fault Tolerant Design of Multimedia Servers”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 364–375. [Bhalotia et al. 2002] G. Bhalotia, A. Hulgeri, C. Nakhe, S. Chakrabarti y S. Sudarshan, “Keyword Searching and Browsing in Databases using BANKS”, Proc. of the International Conf. on Data Engineering (2002). [Bharat y Henzinger 1998] K. Bharat y M. R. Henzinger, “Improved Algorithms for Topic Distillation in a Hyperlinked Environment”, Proc. of the ACM SIGIR Conf. on Research and Development in Information Retrieval (1998), páginas 104–111. [Bhattacharjee et al. 2003] B. Bhattacharjee, S. Padmanabhan, T. Malkemus, T. Lai, L. Cranston y M. Huras, “Efficient Query Processing for Multi-Dimensionally Clustered Tables in DB2”, Proc. of the International Conf. on Very Large Databases (2003), páginas 963–974. [Biliris y Orenstein 1994] A. Biliris y J. Orenstein. “Object Storage Management Architectures”, In Dogac et al. [1994], páginas 185–200 (1994). [Biskup et al. 1979] J. Biskup, U. Dayal y P. A. Bernstein, “Synthesizing Independent Database Schemas”, Proc. of the ACM SIGMOD Conf. on Management of Data (1979), páginas 143– 152. [Bitton et al. 1983] D. Bitton, D. J. DeWitt y C. Turbyfill, “Benchmarking Database Systems: A Systematic Approach”, Proc. of the International Conf. on Very Large Databases (1983). [Bitton y Gray 1988] D. Bitton y J. N. Gray, “Disk Shadowing”, Proc. of the International Conf. on Very Large Databases (1988), páginas 331–338. [Bjork 1973] L. A. Bjork, “Recovery Scenario for a DB/DC System”, Proc. of the ACM Annual Conf. (1973), páginas 142–146. [Blakeley 1996] J. A. Blakeley, “Data Access for the Masses through OLE DB”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996), páginas 161–172. [Blakeley et al. 1986] J. A. Blakeley, P. Larson y F. W. Tompa, “Efficiently Updating Materialized Views”, Proc. of the ACM SIGMOD Conf. on Management of Data (1986), páginas 61–71.

[Bernstein y Goodman 1981] P. A. Bernstein y N. Goodman, “Concurrency Control in Distributed Database Systems”, ACM Computing Survey, volumen 13, número 2 (1981), páginas 185–221.

[Blakeley et al. 1989] J. Blakeley, N. Coburn y P. Larson, “Updating Derived Relations: Detecting Irrelevant and Autonomously Computable Updates”, ACM Transactions on Database Systems, volumen 14, número 3 (1989), páginas 369–400.

[Bernstein y Goodman 1982] P. A. Bernstein y N. Goodman, “A Sophisticate’s Introduction to Distributed Database Concurrency Control”, Proc. of the International Conf. on Very Large Databases (1982), páginas 62–76.

[Blakeley et al. 2005] J. A. Blakeley, C. Cunningham, N. Ellis, B. Rathakrishnan y M.-C. Wu, “Distributed/Heterogeneous Query Processing in Microsoft SQL Server”, Proc. of the International Conf. on Data Engineering (2005).

www.detodoprogramacion.com


926

Bibliografía

[Blakeley y Pizzo 2001] J. A. Blakeley y M. Pizzo, “Enabling Component Databases with OLE DB”, K. R. Dittrich y A. Geppert, editores, Component Database Systems, Morgan Kaufmann Publishers (2001), páginas 139–173. [Blasgen y Eswaran 1976] M. W. Blasgen y K. P. Eswaran, “On the Evaluation of Queries in a Relational Database System”, IBM Systems Journal, volumen 16, (1976), páginas 363–377. [Boral et al. 1990] H. Boral, W. Alexander, L. Clay, G. Copeland, S. Danforth, M. Franklin, B. Hart, M. Smith y P. Valduriez, “Prototyping Bubba, a Highly Parallel Database System”, IEEE Transactions on Knowledge and Data Engineering, volumen 2, número 1 (1990). [Boyce et al. 1975] R. Boyce, D. D. Chamberlin, W. F. King y M. Hammer, “Specifying Queries as Relational Expressions”, Communications of the ACM, volumen 18, número 11 (1975), páginas 621–628. [Breese et al. 1998] J. Breese, D. Heckerman y C. Kadie, “Empirical Analysis of Predictive Algorithms for Collaborative Filtering”, Procs. Conf. on Uncertainty in Artificial Intelligence, Morgan Kaufmann (1998). [Breitbart et al. 1999a] Y. Breitbart, R. Komondoor, R. Rastogi, S. Seshadri y A. Silberschatz, “Update Propagation Protocols For Replicated Databases”, Proc. of the ACM SIGMOD Conf. on Management of Data (1999), páginas 97–108. [Breitbart et al. 1999b] Y. Breitbart, H. Korth, A. Silberschatz y S. Sudarshan, “Distributed Databases”, In Encyclopedia of Electrical and Electronics Engineering, John Wiley and Sons (1999). [Brin y Page 1998] S. Brin y L. Page, “The Anatomy of a LargeScale Hypertextual Web Search Engine”, Proc. of the International World Wide Web Conf. (1998). [Brinkhoff et al. 1993] T. Brinkhoff, H.-P. Kriegel y B. Seeger, “Efficient Processing of Spatial Joins Using R-trees”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993), páginas 237–246. [Bruno et al. 2002] N. Bruno, S. Chaudhuri y L. Gravano, “Topk Selection Queries Over Relational Databases: Mapping Strategies and Performance Evaluation”, ACM Transactions on Database Systems, volumen 27, número 2 (2002), páginas 153–187. [Buckley y Silberschatz 1983] G. Buckley y A. Silberschatz, “Obtaining Progressive Protocols for a Simple Multiversion Database Model”, Proc. of the International Conf. on Very Large Databases (1983), páginas 74–81. [Buckley y Silberschatz 1984] G. Buckley y A. Silberschatz, “Concurrency Control in Graph Protocols by Using Edge Locks”, Proc. of the ACM SIGMOD Conf. on Management of Data (1984), páginas 45–50.

[Buckley y Silberschatz 1985] G. Buckley y A. Silberschatz, “Beyond Two-Phase Locking”, Journal of the ACM, volumen 32, número 2 (1985), páginas 314–326. [Bulmer 1979] M. G. Bulmer, Principles of Statistics, Dover Publications (1979). [Burkhard 1976] W. A. Burkhard, “Hashing and Trie Algorithms for Partial Match Retrieval”, ACM Transactions on Database Systems, volumen 1, número 2 (1976), páginas 175–187. [Burkhard 1979] W. A. Burkhard, “Partial-match Hash Coding: Benefits of Redundancy”, ACM Transactions on Database Systems, volumen 4, número 2 (1979), páginas 228–239. [Cannan y Otten 1993] S. Cannan y G. Otten, SQL—The Standard Handbook, McGraw-Hill (1993). [Carey 1983] M. J. Carey, “Granularity Hierarchies in Concurrency Control”, Proc. of the ACM SIGMOD Conf. on Management of Data (1983), páginas 156–165. [Carey et al. 1991] M. Carey, M. Franklin, M. Livny y E. Shekita, “Data Caching Tradeoffs in Client-Server DBMS Architectures”, Proc. of the ACM SIGMOD Conf. on Management of Data (1991). [Carey et al. 1993] M. J. Carey, D. DeWitt y J. Naughton, “The OO7 Benchmark”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993). [Carey et al. 1999] M. J. Carey, D. D. Chamberlin, S. Narayanan, B. Vance, D. Doole, S. Rielau, R. Swagerman y N. Mattos, “O-O, What Have They Done to DB2?”, Proc. of the International Conf. on Very Large Databases (1999), páginas 542–553. [Carey y Kossmann 1998] M. J. Carey y D. Kossmann, “Reducing the Braking Distance of an SQL Query Engine”, Proc. of the International Conf. on Very Large Databases (1998), páginas 158–169. [Cattell 2000] R. Cattell, editor, The Object Database Standard: ODMG 3.0, Morgan Kaufmann (2000). [Cattell y Skeen 1992] R. Cattell y J. Skeen, “Object Operations Benchmark”, ACM Transactions on Database Systems, volumen 17, número 1 (1992). [Ceri y Owicki 1983] S. Ceri y S. Owicki, “On the Use of Optimistic Methods for Concurrency Control in Distributed Databases”, Proc. of the Sixth Berkeley Workshop on Distributed Data Management and Computer Networks (1983). [Ceri y Pelagatti 1984] S. Ceri y G. Pelagatti, Distributed Databases: Principles and Systems, McGraw-Hill (1984). [Chakrabarti 1999] S. Chakrabarti, “Recent Results in Automatic Web Resource Discovery”, ACM Computing Surveys, volumen 31, número 4 (1999).

www.detodoprogramacion.com


Bibliografía

[Chakrabarti 2000] S. Chakrabarti, “Data Mining for Hypertext: A Tutorial Survey”, SIGKDD Explorations, volumen 1, número 2 (2000), páginas 1–11. [Chakrabarti 2002] S. Chakrabarti, Mining the Web: Discovering Knowledge from HyperText Data, Morgan Kaufmann (2002). [Chakrabarti et al. 1998] S. Chakrabarti, S. Sarawagi y B. Dom, “Mining Surprising Patterns Using Temporal Description Length”, Proc. of the International Conf. on Very Large Databases (1998), páginas 606–617. [Chakrabarti et al. 1999] S. Chakrabarti, M. van den Berg y B. Dom, “Focused Crawling: A New Approach to Topic Specific Web Resource Discovery”, Proc. of the International World Wide Web Conf. (1999). [Chakravarthy et al. 1990] U. S. Chakravarthy, J. Grant y J. Minker, “Logic-Based Approach to Semantic Query Optimization”, ACM Transactions on Database Systems, volumen 15, número 2 (1990), páginas 162–207. [Chamberlin 1996] D. Chamberlin, Using the New DB2: IBM’s Object-Relational Database System, Morgan Kaufmann (1996). [Chamberlin 1998] D. D. Chamberlin, A Complete Guide to DB2 Universal Database, Morgan Kaufmann (1998). [Chamberlin et al. 1976] D. D. Chamberlin, M. M. Astrahan, K. P. Eswaran, P. P. Griffiths, R. A. Lorie, J. W. Mehl, P. Reisner y B. W. Wade, “SEQUEL 2: A Unified Approach to Data Definition, Manipulation, and Control”, IBM Journal of Research and Development, volumen 20, número 6 (1976), páginas 560– 575. [Chamberlin et al. 1981] D. D. Chamberlin, M. M. Astrahan, M. W. Blasgen, J. N. Gray, W. F. King, B. G. Lindsay, R. A. Lorie, J. W. Mehl, T. G. Price, P. G. Selinger, M. Schkolnick, D. R. Slutz, I. L. Traiger, B. W. Wade y R. A. Yost, “A History and Evaluation of System R”, Communications of the ACM, volumen 24, número 10 (1981), páginas 632–646. [Chamberlin et al. 2000] D. D. Chamberlin, J. Robie y D. Florescu, “Quilt: An XML Query Language for Heterogeneous Data Sources”, Proc. of the International Workshop on the Web and Databases (WebDB) (2000), páginas 53–62. [Chamberlin y Boyce 1974] D. D. Chamberlin y R. F. Boyce, “SEQUEL: A Structured English Query Language”, ACM SIGMOD Workshop on Data Description, Access, and Control (1974), páginas 249–264. [Chan y Ioannidis 1998] C.-Y. Chan y Y. E. Ioannidis, “Bitmap Index Design and Evaluation”, Proc. of the ACM SIGMOD Conf. on Management of Data (1998). [Chan y Ioannidis 1999] C.-Y. Chan y Y. E. Ioannidis, “An Efficient Bitmap Encoding Scheme for Selection Queries”, Proc. of the ACM SIGMOD Conf. on Management of Data (1999).

927

[Chandra y Harel 1982] A. K. Chandra y D. Harel, “Structure and Complexity of Relational Queries”, Journal of Computer and System Sciences, volumen 15, número 10 (1982), páginas 99–128. [Chandrasekaran et al. 2003] S. Chandrasekaran, O. Cooper, A. Deshpande, M. J. Franklin, J. M. Hellerstein, W. Hong, S. Krishnamurthy, S. Madden, V. Raman, F. Reiss y M. A. Shah, “TelegraphCQ: Continuous Dataflow Processing for an Uncertain World”, Proc. First Biennial Conference on Innovative Data Systems Research (2003). [Chandy et al. 1975] K. M. Chandy, J. C. Browne, C. W. Dissley y W. R. Uhrig, “Analytic Models for Rollback and Recovery Strategies in Database Systems”, IEEE Transactions on Software Engineering, volumen SE-1, número 1 (1975), páginas 100– 110. [Chatziantoniou y Ross 1997] D. Chatziantoniou y K. A. Ross, “Groupwise Processing of Relational Queries”, Proc. of the International Conf. on Very Large Databases (1997), páginas 476– 485. [Chaudhuri et al. 1995] S. Chaudhuri, R. Krishnamurthy, S. Potamianos y K. Shim, “Optimizing Queries with Materialized Views”, Proc. of the International Conf. on Data Engineering, Taipei, Taiwan (1995). [Chaudhuri et al. 1999] S. Chaudhuri, E. Christensen, G. Graefe, V. Narasayya y M. Zwilling, “"Self Tuning Technology in Microsoft SQL Server”, IEEE Data Engineering Bulletin, volumen 22, número 2 (1999). [Chaudhuri et al. 2003] S. Chaudhuri, K. Ganjam, V. Ganti y R. Motwani, “Robust and Efficient Fuzzy Match for Online Data Cleaning”, Proc. of the ACM SIGMOD Conf. on Management of Data (2003). [Chaudhuri y Narasayya 1997] S. Chaudhuri y V. Narasayya, “An Efficient Cost-Driven Index Selection Tool for Microsoft SQL Server”, Proc. of the International Conf. on Very Large Databases (1997). [Chaudhuri y Shim 1994] S. Chaudhuri y K. Shim, “Including Group-By in Query Optimization”, Proc. of the International Conf. on Very Large Databases (1994). [Chen 1976] P. P. Chen, “The Entity-Relationship Model: Toward a Unified View of Data”, ACM Transactions on Database Systems, volumen 1, número 1 (1976), páginas 9–36. [Chen et al. 1994] P. M. Chen, E. K. Lee, G. A. Gibson, R. H. Katz y D. A. Patterson, “RAID: High-Performance, Reliable Secondary Storage”, ACM Computing Survey, volumen 26, número 2 (1994). [Chen y Patterson 1990] P. Chen y D. Patterson, “Maximizing Performance in a Striped Disk Array”, Proc. of the Seventeenth Annual International Symposium on Computer Architecture (1990).

www.detodoprogramacion.com


928

Bibliografía

[Chomicki 1995] J. Chomicki, “Efficient Checking of Temporal Integrity Constraints Using Bounded History Encoding”, ACM Transactions on Database Systems, volumen 20, número 2 (1995), páginas 149–186. [Chou y Dewitt 1985] H. T. Chou y D. J. Dewitt, “An Evaluation of Buffer Management Strategies for Relational Database Systems”, Proc. of the International Conf. on Very Large Databases (1985), páginas 127–141. [Cochrane et al. 1996] R. Cochrane, H. Pirahesh y N. M. Mattos, “Integrating Triggers and Declarative Constraints in SQL Database Sytems”, Proc. of the International Conf. on Very Large Databases (1996). [Codd 1970] E. F. Codd, “A Relational Model for Large Shared Data Banks”, Communications of the ACM, volumen 13, número 6 (1970), páginas 377–387. [Codd 1972] E. F. Codd. “Further Normalization of the Data Base Relational Model”, In Rustin [1972], páginas 33–64 (1972). [Codd 1979] E. F. Codd, “Extending the Database Relational Model to Capture More Meaning”, ACM Transactions on Database Systems, volumen 4, número 4 (1979), páginas 397–434. [Codd 1982] E. F. Codd, “The 1981 ACM Turing Award Lecture: Relational Database: A Practical Foundation for Productivity”, Communications of the ACM, volumen 25, número 2 (1982), páginas 109–117.

[Dageville y Zait 2002] B. Dageville y M. Zait, “SQL Memory Management in Oracle 9i”, Proc. of the International Conf. on Very Large Databases (2002), páginas 962–973. [Dalvi et al. 2001] N. N. Dalvi, S. K. Sanghai, P. Roy y S. Sudarshan, “Pipelining in Multi-Query Optimization”, Proc. of the ACM Symposium on Principles of Database Systems (2001). [Daniels et al. 1982] D. Daniels, P. G. Selinger, L. M. Haas, B. G. Lindsay, C. Mohan, A. Walker y P. F. Wilms. “An Introduction to Distributed Query Compilation in R*”, In Schneider [1982] (1982). [Dar et al. 1996] S. Dar, H. V. Jagadish, A. Levy y D. Srivastava’, “Answering Queries with Aggregation Using Views”, Proc. of the International Conf. on Very Large Databases (1996). [Dashti et al. 2003] A. Dashti, S. H. Kim, C. Shahabi y R. Zimmermann, Streaming Media Server Design, Prentice Hall (2003). [Date 1986] C. J. Date, Relational Databases: selected Writings, Addison Wesley (1986). [Date 1989] C. Date, A Guide to DB2, Addison Wesley (1989). [Date 1990] C. J. Date, Relational Database Writings, 1985-1989, Addison Wesley (1990). [Date 1993a] C. J. Date, “How SQL Missed the Boat”, Database Programming and Design, volumen 6, número 9 (1993).

[Codd 1990] E. F. Codd, The Relational Model for Database Management: Version 2, Addison Wesley (1990).

[Date 1993b] C. J. Date, “The Outer Join”, IOCOD-2, John Wiley and Sons (1993), páginas 76–106.

[Comer 1979] D. Comer, “The Ubiquitous B-tree”, ACM Computing Survey, volumen 11, número 2 (1979), páginas 121–137.

[Date 2003] C. J. Date, An Introduction to Database Systems, 8th edición, Addison Wesley (2003).

[Comer y Droms 2003] D. E. Comer y R. E. Droms, Computer Networks and Internets, 4a edición, Prentice Hall (2003).

[Date y Darwen 1997] C. J. Date y G. Darwen, A Guide to the SQL Standard, 4a edición, Addison Wesley (1997).

[Cook 1996] M. A. Cook, Building Enterprise Information Architecture: Reengineering Information Systems, Prentice Hall (1996). [Cook et al. 1999] J. Cook, R. Harbus y T. Shirai, The DB2 Universal Database V6.1 Certification Guide: For UNIX, Windows, and OS/2, Prentice Hall (1999). [Cormen et al. 1990] T. Cormen, C. Leiserson y R. Rivest, Introduction to Algorithms, MIT Press (1990).

[Davies 1973] C. T. Davies, “Recovery Semantics for a DB/DC System”, ACM Annual Conference (1973), páginas 136–141. [Davis et al. 1983] C. Davis, S. Jajodia, P. A. Ng y R. Yeh, editores, Entity-Relationship Approach to Software Engineering, North Holland (1983). [Davison y Graefe 1994] D. L. Davison y G. Graefe, “MemoryContention Responsive Hash Joins”, Proc. of the International Conf. on Very Large Databases (1994).

[Cruanes et al. 2004] T. Cruanes, B. Dageville y B. Ghosh, “Parallel SQL Execution in Oracle 10g”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004), páginas 850–854.

[Dayal 1987] U. Dayal, “Of Nests and Trees: A Unified Approach to Processing Queries that Contain Nested Subqueries, Aggregates and Quantifiers”, Proc. of the International Conf. on Very Large Databases (1987), páginas 197–208.

[Dageville et al. 2004] B. Dageville, D. Das, K. Dias, K. Yagoub, M. Zait y M. Ziauddin, “Automatic SQL Tuning in Oracle 10g”, Proc. of the International Conf. on Very Large Databases (2004), páginas 1098–1109.

[Dayal et al. 1982] U. Dayal, N. Goodman y R. H. Katz, “An Extended Relational Algebra with Control over Duplicate Elimination”, Proc. of the ACM Symposium on Principles of Database Systems (1982).

www.detodoprogramacion.com


Bibliografía

[DB2 Online documentation ] DB2 Online documentation. http://www.software.ibm.com/db2/pubs. [Deshpande y Larson 1992] V. Deshpande y P. A. Larson, “The Design and Implementation of a Parallel Join Algorithm for Nested Relations on Shared-Memory Multiprocessors”, Proc. of the International Conf. on Data Engineering (1992). [Deutsch et al. 1999] A. Deutsch, M. Fernandez, D. Florescu, A. Levy y D. Suciu, “A Query Language for XML”, Proc. of the International World Wide Web Conf. (1999). (XMLQL also submitted to the World Wide Web Consortium http://www.w3.org/TR/1998/NOTE-xml-ql-19980819). [DeWitt 1990] D. DeWitt, “The Gamma Database Machine Project”, IEEE Transactions on Knowledge and Data Engineering, volumen 2, número 1 (1990). [DeWitt et al. 1986] D. DeWitt, R. Gerber, G. Graefe, M. Heytens, K. Kumar y M. Muralikrishna, “A High Performance Dataflow Database Machine”, Proc. of the International Conf. on Very Large Databases (1986). [DeWitt et al. 1992] D. DeWitt, J. Naughton, D. Schneider y S. Seshadri, “Practical Skew Handling in Parallel Joins”, Proc. of the International Conf. on Very Large Databases (1992). [DeWitt y Gray 1992] D. DeWitt y J. Gray, “Parallel Database Systems: The Future of High Performance Database Systems”, Communications of the ACM, volumen 35, número 6 (1992), páginas 85–98. [Dias et al. 1989] D. Dias, B. Iyer, J. Robinson y P. Yu, “Integrated Concurrency-Coherency Controls for Multisystem Data Sharing”, Software Engineering, volumen 15, número 4 (1989), páginas 437–448. [Dogac et al. 1994] A. Dogac, M. T. Ozsu, A. Biliris y T. Selis, Advances in Object-Oriented Database Systems, volumen 130, Springer Verlag, Computer and Systems Sciences, NATO ASI Series F (1994). [Donahoo y Speegle 2005] M. J. Donahoo y G. D. Speegle, SQL: Practical Guide for Developers, Morgan Kaufmann (2005). [Douglas y Douglas 2003] K. Douglas y S. Douglas, PostgreSQL, Sam’s Publishing (2003). [Dubois y Thakkar 1992] M. Dubois y S. Thakkar, editores, Scalable Shared Memory Multiprocessors, Kluwer Academic Publishers (1992). [Duncan 1990] R. Duncan, “A Survey of Parallel Computer Architectures”, IEEE Computer, volumen 23, número 2 (1990), páginas 5–16. [Eisenberg et al. 2004] A. Eisenberg, J. Melton, K. G. Kulkarni, J.-E. Michels y F. Zemke, “SQL:2003 Has Been Published”, ACM SIGMOD Record, volumen 33, número 1 (2004), páginas 119–126.

929

[Eisenberg y Melton 1999] A. Eisenberg y J. Melton, “SQL:1999, formerly known as SQL3”, ACM SIGMOD Record, volumen 28, número 1 (1999). [Eisenberg y Melton 2004a] A. Eisenberg y J. Melton, “Advancements in SQL/XML”, ACM SIGMOD Record, volumen 33, número 3 (2004), páginas 79–86. [Eisenberg y Melton 2004b] A. Eisenberg y J. Melton, “An Early Look at XQuery API for Java (XQJ)”, ACM SIGMOD Record, volumen 33, número 2 (2004), páginas 105–111. [Ellis 1987] C. S. Ellis, “Concurrency in Linear Hashing”, ACM Transactions on Database Systems, volumen 12, número 2 (1987), páginas 195–217. [Elmasri y Navathe 2003] R. Elmasri y S. B. Navathe, Fundamentals of Database Systems, 4a edición, Addison Wesley (2003). [Eppinger et al. 1991] J. L. Eppinger, L. B. Mummert y A. Z. Spector, Camelot and Avalon: A Distributed Transaction Facility, Morgan Kaufmann (1991). [Epstein et al. 1978] R. Epstein, M. R. Stonebraker y E. Wong, “Distributed Query Processing in a Relational Database System”, Proc. of the ACM SIGMOD Conf. on Management of Data (1978), páginas 169–180. [Epstein y Stonebraker 1980] R. Epstein y M. R. Stonebraker, “Analysis of Distributed Database Processing Strategies”, Proc. of the International Conf. on Very Large Databases (1980), páginas 92–110. [Escobar-Molano et al. 1993] M. Escobar-Molano, R. Hull y D. Jacobs, “Safety and Translation of Calculus Queries with Scalar Functions”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993), páginas 253–264. [Eswaran et al. 1976] K. P. Eswaran, J. N. Gray, R. A. Lorie y I. L. Traiger, “The Notions of Consistency and Predicate Locks in a Database System”, Communications of the ACM, volumen 19, número 11 (1976), páginas 624–633. [Fagin 1977] R. Fagin, “Multivalued Dependencies and a New Normal Form for Relational Databases”, ACM Transactions on Database Systems, volumen 2, número 3 (1977), páginas 262– 278. [Fagin 1979] R. Fagin, “Normal Forms and Relational Database Operators”, Proc. of the ACM SIGMOD Conf. on Management of Data (1979). [Fagin 1981] R. Fagin, “A Normal Form for Relational Databases That Is Based on Domains and Keys”, ACM Transactions on Database Systems, volumen 6, número 3 (1981), páginas 387–415. [Fagin et al. 1979] R. Fagin, J. Nievergelt, N. Pippenger y H. R. Strong, “Extendible Hashing — A Fast Access Method for

www.detodoprogramacion.com


930

Bibliografía

Dynamic Files”, ACM Transactions on Database Systems, volumen 4, número 3 (1979), páginas 315–344.

SIGMOD Conf. on Management of Data (1995), páginas 352– 363.

[Faloutsos y Lin 1995] C. Faloutsos y K.-I. Lin, “Fast Map: A Fast Algorithm for Indexing, Data-Mining and Visualization of Traditional and Multimedia Datasets”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 163– 174.

[Funderburk et al. 2002a] J. E. Funderburk, G. Kiernan, J. Shanmugasundaram, E. Shekita y C. Wei, “XTABLES: Bridging Relational Technology and XML”, IBM Systems Journal, volumen 41, número 4 (2002), páginas 616–641.

[Fayyad et al. 1995] U. Fayyad, G. Piatetsky-Shapiro, P. Smyth y R. Uthurusamy, Advances in Knowledge Discovery and Data Mining, MIT Press (1995).

[Funderburk et al. 2002b] J. E. Funderburk, S. Malaika y B. Reinwald, “XML Programming with SQL/XML and XQuery”, IBM Systems Journal, volumen 41, número 4 (2002), páginas 642–665.

[Fekete et al. 1990] A. Fekete, N. Lynch, M. Merritt y W. Weihl, “Commutativity-Based Locking for Nested Transactions”, Journal of Computer and System Science (1990), páginas 65–156. [Fekete et al. 2005] A. Fekete, D. Liarokapis, E. O’Neil, P. O’Neil y D. Shasha, “Making Snapshot Isolation Serializable”, ACM Transactions on Database Systems, volumen 30, número 2 (2005). [Finkel y Bentley 1974] R. A. Finkel y J. L. Bentley, “Quad Trees: A Data Structure for Retrieval on Composite Keys”, Acta Informatica, volumen 4, (1974), páginas 1–9. [Finkelstein 1982] S. Finkelstein, “Common Expression Analysis in Database Applications”, Proc. of the ACM SIGMOD Conf. on Management of Data (1982), páginas 235–245. [Fischer 2001] L. Fischer, editor, Workflow Handbook 2001, Future Strategies (2001). [Fischer 2004] L. Fischer, editor, The Workflow Handbook 2004, Future Strategies Inc. (2004). [Florescu et al. 2000] D. Florescu, D. Kossmann y I. Monalescu, “Integrating Keyword Search into XML Query Processing”, Proc. of the International World Wide Web Conf. (2000), páginas 119–135. También aparece en una edición especial de Computer Networks. [Florescu y Kossmann 1999] D. Florescu y D. Kossmann, “Storing and Querying XML Data Using an RDBMS”, IEEE Data Engineering Bulletin (Special Issue on XML) (1999), páginas 27– 35. [Franklin et al. 1992] M. J. Franklin, M. J. Zwilling, C. K. Tan, M. J. Carey y D. J. DeWitt, “Crash Recovery in Client-Server EXODUS”, Proc. of the ACM SIGMOD Conf. on Management of Data (1992), páginas 165–174. [Franklin et al. 1993] M. J. Franklin, M. Carey y M. Livny, “Local Disk Caching for Client-Server Database Systems”, Proc. of the International Conf. on Very Large Databases (1993). [Fredkin 1960] E. Fredkin, “Trie Memory”, Communications of the ACM, volumen 4, número 2 (1960), páginas 490–499. [Freedman y DeWitt 1995] C. S. Freedman y D. J. DeWitt, “The SPIFFI Scalable Video-on-Demand Server”, Proc. of the ACM

[Fushimi et al. 1986] S. Fushimi, M. Kitsuregawa y H. Tanaka, “An Overview of the Systems Software of a Parallel Relational Database Machine: GRACE”, Proc. of the International Conf. on Very Large Databases (1986). [Galindo-Legaria 1994] C. Galindo-Legaria, “Outerjoins as Disjunctions”, Proc. of the ACM SIGMOD Conf. on Management of Data (1994). [Galindo-Legaria et al. 2004] C. Galindo-Legaria, S. Stefani y F. Waas, “Query Processing for SQL Updates”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004), páginas 844–849. [Galindo-Legaria y Joshi 2001] C. A. Galindo-Legaria y M. M. Joshi, “Orthogonal Optimization of Subqueries and Aggregation”, Proc. of the ACM SIGMOD Conf. on Management of Data (2001). [Galindo-Legaria y Rosenthal 1992] C. Galindo-Legaria y A. Rosenthal, “How to Extend a Conventional Optimizer to Handle One- and Two-Sided Outerjoin”, Proc. of the International Conf. on Data Engineering (1992), páginas 402–409. [Ganguly 1998] S. Ganguly, “Design and Analysis of Parametric Query Optimization Algorithms”, Proc. of the International Conf. on Very Large Databases, New York City, New York (1998). [Ganguly et al. 1992] S. Ganguly, W. Hasan y R. Krishnamurthy, “Query Optimization for Parallel Execution”, Proc. of the ACM SIGMOD Conf. on Management of Data (1992). [Ganguly et al. 1996] S. Ganguly, P. Gibbons, Y. Matias y A. Silberschatz, “A Sampling Algorithm for Estimating Join Size”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996). [Ganski y Wong 1987] R. A. Ganski y H. K. T. Wong, “Optimization of Nested SQL Queries Revisited”, Proc. of the ACM SIGMOD Conf. on Management of Data (1987). [Garcia-Molina 1982] H. Garcia-Molina, “Elections in Distributed Computing Systems”, IEEE Transactions on Computers, volumen C-31, número 1 (1982), páginas 48–59.

www.detodoprogramacion.com


Bibliografía

[Garcia-Molina et al. 2001] H. Garcia-Molina, J. D. Ullman y J. D. Widom, Database Systems: The Complete Book, Prentice Hall (2001). [Garcia-Molina y Salem 1987] H. Garcia-Molina y K. Salem, “Sagas”, Proc. of the ACM SIGMOD Conf. on Management of Data (1987), páginas 249–259. [Garcia-Molina y Salem 1992] H. Garcia-Molina y K. Salem, “Main Memory Database Systems: An Overview”, IEEE Transactions on Knowledge and Data Engineering, volumen 4, número 6 (1992), páginas 509–516.

931

Base”, Proc. of the International Conf. on Very Large Databases (1975), páginas 428–451. [Gray et al. 1976] J. Gray, R. A. Lorie, G. R. Putzolu y I. L. Traiger, Granularity of Locks and Degrees of Consistency in a Shared Data Base, Nijssen (1976). [Gray et al. 1981] J. Gray, P. R. McJones y M. Blasgen, “The Recovery Manager of the System R Database Manager”, ACM Computing Survey, volumen 13, número 2 (1981), páginas 223–242.

[Gawlick 1998] D. Gawlick, “Messaging/Queuing in Oracle8”, Proc. of the International Conf. on Data Engineering (1998), páginas 66–68.

[Gray et al. 1990] J. Gray, B. Horst y M. Walker, “Parity Striping of Disc Arrays: Low-Cost Reliable Storage with Acceptable Throughput”, Proc. of the International Conf. on Very Large Databases (1990), páginas 148–161.

[Georgakopoulos et al. 1994] D. Georgakopoulos, M. Rusinkiewicz y A. Seth, “Using Tickets to Enforce the Serializability of Multidatabase Transactions”, IEEE Transactions on Knowledge and Data Engineering, volumen 6, número 1 (1994), páginas 166–180.

[Gray et al. 1995] J. Gray, A. Bosworth, A. Layman y H. Pirahesh, “Data Cube: A Relational Aggregation Operator Generalizing Group-By, Cross-Tab and Sub-Totals”, informe técnico, Microsoft Research (1995).

[Gifford 1979] D. K. Gifford, “Weighted Voting for Replicated Data”, Proc. the ACM SIGOPS Symposium on Operating Systems Principles (1979), páginas 150–162.

[Gray et al. 1996] J. Gray, P. Helland y P. O’Neil, “The Dangers of Replication and a Solution”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996), páginas 173–182.

[Graefe 1990] G. Graefe, “Encapsulation of Parallelism in the Volcano Query Processing System”, Proc. of the ACM SIGMOD Conf. on Management of Data (1990), páginas 102–111.

[Gray et al. 1997] J. Gray, S. Chaudhuri, A. Bosworth, A. Layman, D. Reichart, M. Venkatrao, F. Pellow y H. Pirahesh, “Data Cube: A Relational Aggregation Operator Generalizing Group-by, Cross-Tab, and Sub Totals”, Data Mining and Knowledge Discovery, volumen 1, número 1 (1997), páginas 29–53.

[Graefe 1993] G. Graefe, “Query Evaluation Techniques for Large Databases”, ACM Computing Survey, volumen 25, número 2 (1993), páginas 73–170. [Graefe 1995] G. Graefe, “The Cascades Framework for Query Optimization”, Data Engineering Bulletin, volumen 18, número 3 (1995), páginas 19–29. [Graefe et al. 1998] G. Graefe, R. Bunker y S. Cooper, “Hash Joins and Hash Teams in Microsoft SQL Server”, Proc. of the International Conf. on Very Large Databases (1998), páginas 86–97. [Graefe y McKenna 1993] G. Graefe y W. McKenna, “The Volcano Optimizer Generator”, Proc. of the International Conf. on Data Engineering (1993), páginas 209–218. [Gray 1978] J. Gray. “Notes on Data Base Operating System”, In Bayer et al. [1978], páginas 393–481 (1978). [Gray 1981] J. Gray, “The Transaction Concept: Virtues and Limitations”, Proc. of the International Conf. on Very Large Databases (1981), páginas 144–154. [Gray 1991] J. Gray, The Benchmark Handbook for Database and Transaction Processing Systems, 2a edición, Morgan Kaufmann (1991). [Gray et al. 1975] J. Gray, R. A. Lorie y G. R. Putzolu, “Granularity of Locks and Degrees of Consistency in a Shared Data

[Gray y Edwards 1995] J. Gray y J. Edwards, “Scale Up with TP Monitors”, Byte, volumen 20, número 4 (1995), páginas 123– 130. [Gray y Graefe 1997] J. Gray y G. Graefe, “The Five-Minute Rule Ten Years Later, and Other Computer Storage Rules of Thumb”, SIGMOD Record, volumen 26, número 4 (1997), páginas 63–68. [Gray y Putzolu 1987] J. Gray y G. R. Putzolu, “The 5 Minute Rule for Trading Memory for Disk Accesses and the 10 Byte Rule for Trading Memory for CPU Time”, Proc. of the ACM SIGMOD Conf. on Management of Data (1987), páginas 395– 398. [Gray y Reuter 1993] J. Gray y A. Reuter, Transaction Processing: Concepts and Techniques, Morgan Kaufmann (1993). [Gregersen y Jensen 1999] H. Gregersen y C. S. Jensen, “Temporal Entity-Relationship Models-A Survey”, IEEE Transactions on Knowledge and Data Engineering, volumen 11, número 3 (1999), páginas 464–497. [Griffin y Libkin 1995] T. Griffin y L. Libkin, “Incremental Maintenance of Views with Duplicates”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995).

www.detodoprogramacion.com


932

Bibliografía

[Grossman y Frieder 2004] D. A. Grossman y O. Frieder, Information Retrieval: Algorithms and Heuristics, 2a edición, Springer Verlag (2004).

[Haritsa et al. 1990] J. Haritsa, M. Carey y M. Livny, “On Being Optimistic about Real-Time Constraints”, Proc. of the ACM SIGMOD Conf. on Management of Data (1990).

[Guo et al. 2003] L. Guo, F. Shao, C. Botev y J. Shanmugasundaram, “XRANK: Ranked Keyword Search over XML Documents”, Proc. of the ACM SIGMOD Conf. on Management of Data (2003).

[Harizopoulos y Ailamaki 2004] S. Harizopoulos y A. Ailamaki, “STEPS towards Cache-resident Transaction Processing”, Proc. of the International Conf. on Very Large Databases (2004), páginas 660–671.

[Gupta 1997] H. Gupta, “Selection of Views to Materialize in a Data Warehouse”, Proc. of the International Conf. on Database Theory (1997).

[Hellerstein et al. 1995] J. M. Hellerstein, J. F. Naughton y A. Pfeffer, “Generalized Search Trees for Database Systems”, Proc. of the International Conf. on Very Large Databases (1995), páginas 562–573.

[Gupta y Mumick 1995] A. Gupta y I. S. Mumick, “Maintenance of Materialized Views: Problems, Techniques and Applications”, IEEE Data Engineering Bulletin, volumen 18, número 2 (1995).

[Hellerstein y Stonebraker 2005] J. M. Hellerstein y M. Stonebraker, editores, Readings in Database Systems, 4a edición, Morgan Kaufmann (2005).

[Guttman 1984] A. Guttman, “R-Trees: A Dynamic Index Structure for Spatial Searching”, Proc. of the ACM SIGMOD Conf. on Management of Data (1984), páginas 47–57.

[Hennessy et al. 2002] J. L. Hennessy, D. A. Patterson y D. Goldberg, Computer Architecture: A Quantitative Approach, 3a edición, Morgan Kaufmann (2002).

[H. Lu y Tan 1991] M. S. H. Lu y K. Tan, “Optimization of Multi-Way Join Queries for Parallel Execution”, Proc. of the International Conf. on Very Large Databases (1991).

[Hevner y Yao 1979] A. R. Hevner y S. B. Yao, “Query Processing in Distributed Database Systems”, IEEE Transactions on Software Engineering, volumen SE-5, número 3 (1979), páginas 177–187.

[Haas et al. 1989] L. M. Haas, J. C. Freytag, G. M. Lohman y H. Pirahesh, “Extensible Query Processing in Starburst”, Proc. of the ACM SIGMOD Conf. on Management of Data (1989), páginas 377–388.

[Heywood et al. 2002] I. Heywood, S. Cornelius y S. Carver, An Introduction to Geographical Information Systems, Second Edition, Prentice Hall (2002).

[Haas et al. 1990] L. M. Haas, W. Chang, G. M. Lohman, J. McPherson, P. F. Wilms, G. Lapis, B. G. Lindsay, H. Pirahesh, M. J. Carey y E. J. Shekita, “Starburst Mid-Flight: As the Dust Clears”, IEEE Transactions on Knowledge and Data Engineering, volumen 2, número 1 (1990), páginas 143–160. [Haerder y Reuter 1983] T. Haerder y A. Reuter, “Principles of Transaction-Oriented Database Recovery”, ACM Computing Survey, volumen 15, número 4 (1983), páginas 287–318. [Haerder y Rothermel 1987] T. Haerder y K. Rothermel, “Concepts for Transaction Recovery in Nested Transactions”, Proc. of the ACM SIGMOD Conf. on Management of Data (1987), páginas 239–248. [Hall 1976] P. A. V. Hall, “Optimization of a Single Relational Expression in a Relational Database System”, IBM Journal of Research and Development, volumen 20, número 3 (1976), páginas 244–257. [Halsall 1996] F. Halsall, Data Communications, Computer Networks, and Open Systems, 4a edición, Addison Wesley (1996). [Han y Kamber 2000] J. Han y M. Kamber, Data Mining: Concepts and Techniques, Morgan Kaufmann (2000). [Harinarayan et al. 1996] V. Harinarayan, J. D. Ullman y A. Rajaraman, “Implementing Data Cubes Efficiently”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996).

[Hollingsworth 1994] D. Hollingsworth, The Workflow Reference Model, Workflow Management Coalition, TC00-1003 (1994). [Hollingsworth 2004] D. Hollingsworth. “The Workflow Reference Model 10 Years On”, In Fischer [2004] (2004). [Hong et al. 1993] D. Hong, T. Johnson y S. Chakravarthy, “Real-Time Transaction Scheduling: A Cost Conscious Approach”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993). [Hong y Stonebraker 1991] W. Hong y M. Stonebraker, “Optimization of Parallel Query Execution Plans in XPRS”, Proc. of the International Conf. on Parallel and Distributed Information Systems (1991), páginas 218–225. [Howes et al. 1999] T. A. Howes, M. C. Smith y G. S. Good, Understanding and Deploying LDAP Directory Services, Macmillan Publishing, New York (1999). [Hristidis y Papakonstantinou 2002] V. Hristidis y Y. Papakonstantinou, “DISCOVER: Keyword Search in Relational Databases”, Proc. of the International Conf. on Very Large Databases (2002). [Huang y Garcia-Molina 2001] Y. Huang y H. Garcia-Molina, “Exactly-once Semantics in a Replicated Messaging System”, Proc. of the International Conf. on Data Engineering (2001), páginas 3–12.

www.detodoprogramacion.com


Bibliografía

933

[Hulgeri y Sudarshan 2003] A. Hulgeri y S. Sudarshan, “AniPQO: Almost Non-Intrusive Parametric Query Optimization for Non-Linear Cost Functions”, Proc. of the International Conf. on Very Large Databases (2003).

[Jhingran et al. 1997] A. Jhingran, T. Malkemus y S. Padmanabhan, “Query Optimization in DB2 Parallel Edition”, Data Engineering Bulletin, volumen 20, número 2 (1997), páginas 27–34.

[IBM 1987] IBM, “Systems Application Architecture: Common Programming Interface, Database Reference”, informe técnico, IBM Corporation, IBM Form Number SC26–4348–0 (1987).

[Johnson 1999] T. Johnson, “Performance Measurements of Compressed Bitmap Indices”, Proc. of the International Conf. on Very Large Databases (1999).

[IDEF1X 1993] IDEF1X, “Integration Definition for Information Modeling (IDEF1X)”, informe técnico Federal Information Processing Standards Publication 184, National Institute of Standards and Technology (NIST), disponible en www.idef.com/Downloads/pdf/Idef1x.pdf (1993). [Imielinski y Badrinath 1994] T. Imielinski y B. R. Badrinath, “Mobile Computing — Solutions and Challenges”, Communications of the ACM, volumen 37, número 10 (1994).

[Johnson y Shasha 1993] T. Johnson y D. Shasha, “The Performance of Concurrent B-Tree Algorithms”, ACM Transactions on Database Systems, volumen 18, número 1 (1993). [Jones y Willet 1997] K. S. Jones y P. Willet, editores, Readings in Information Retrieval, Morgan Kaufmann (1997). [Jordan y Russell 2003] D. Jordan y C. Russell, Java Data Objects, O’Reilly (2003).

[Imielinski y Korth 1996] T. Imielinski y H. F. Korth, editores, Mobile Computing, Kluwer Academic Publishers (1996).

[Joshi 1991] A. Joshi, “Adaptive Locking Strategies in a MultiNode Shared Data Model Environment”, Proc. of the International Conf. on Very Large Databases (1991).

[Ioannidis et al. 1992] Y. E. Ioannidis, R. T. Ng, K. Shim y T. K. Sellis, “Parametric Query Optimization”, Proc. of the International Conf. on Very Large Databases (1992), páginas 103–114.

[Joshi et al. 1998] A. Joshi, W. Bridge, J. Loaiza y T. Lahiri, “Checkpointing in Oracle”, Proc. of the International Conf. on Very Large Databases (1998), páginas 665–668.

[Ioannidis y Christodoulakis 1993] Y. Ioannidis y S. Christodoulakis, “Optimal Histograms for Limiting Worst-Case Error Propagation in the Size of Join Results”, ACM Transactions on Database Systems, volumen 18, número 4 (1993), páginas 709–748.

[Kanne y Moerkotte 2000] C.-C. Kanne y G. Moerkotte, “Efficient Storage of XML Data”, Proc. of the International Conf. on Data Engineering (2000), página 198.

[Ioannidis y Poosala 1995] Y. E. Ioannidis y V. Poosala, “Balancing Histogram Optimality and Practicality for Query Result Size Estimation”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 233–244. [Jackson y Moulinier 2002] P. Jackson y I. Moulinier, Natural Language Processing for Online Applications: Text Retrieval, Extraction, and Categorization, John Benjamin (2002). [Jagadish et al. 1993] H. V. Jagadish, A. Silberschatz y S. Sudarshan, “Recovering from Main-Memory Lapses”, Proc. of the International Conf. on Very Large Databases (1993). [Jagadish et al. 1994] H. Jagadish, D. Lieuwen, R. Rastogi, A. Silberschatz y S. Sudarshan, Dali: A High Performance Main Memory Storage Manager (1994). [Jain y Dubes 1988] A. K. Jain y R. C. Dubes, Algorithms for Clustering Data, Prentice Hall (1988). [Jensen et al. 1994] C. S. Jensen et al., “A Consensus Glossary of Temporal Database Concepts”, ACM SIGMOD Record, volumen 23, número 1 (1994), páginas 52–64. [Jensen et al. 1996] C. S. Jensen, R. T. Snodgrass y M. Soo, “Extending Existing Dependency Theory to Temporal Databases”, IEEE Transactions on Knowledge and Data Engineering, volumen 8, número 4 (1996), páginas 563–582.

[Kapitskaia et al. 2000] O. Kapitskaia, R. T. Ng y D. Srivastava, “Evolution and Revolutions in LDAP Directory Caches”, Proc. of the International Conf. on Extending Database Technology (2000), páginas 202–216. [Katz et al. 2004] H. Katz, D. Chamberlin, D. Draper, M. Fernandez, M. Kay, J. Robie, M. Rys, J. Simeon, J. Tivy y P. Wadler, XQuery from the Experts: A Guide to the W3C XML Query Language, Addison Wesley (2004). [Kaushik et al. 2004] R. Kaushik, R. Krishnamurthy, J. F. Naughton y R. Ramakrishnan, “On the Integration of Structure Indexes and Inverted Lists”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004). [Kedem y Silberschatz 1979] Z. M. Kedem y A. Silberschatz, “Controlling Concurrency Using Locking Protocols”, Proc. of the Annual IEEE Symposium on Foundations of Computer Science (1979), páginas 275–285. [Kedem y Silberschatz 1983] Z. M. Kedem y A. Silberschatz, “Locking Protocols: From Exclusive to Shared Locks”, ACM Press, volumen 30, número 4 (1983), páginas 787–804. [Kim 1982] W. Kim, “On Optimizing an SQL-like Nested Query”, ACM Transactions on Database Systems, volumen 3, número 3 (1982), páginas 443–469. [Kim 1995] W. Kim, editor, Modern Database Systems, ACM Press/ Addison Wesley (1995).

www.detodoprogramacion.com


934

Bibliografía

[King 1981] J. J. King, “QUIST: A System for Semantic Query Optimization in Relational Data Bases”, Proc. of the International Conf. on Very Large Databases (1981), páginas 510–517.

tions”, Proc. of the International Conf. on Very Large Databases (1990).

[King et al. 1991] R. P. King, N. Halim, H. Garcia-Molina y C. Polyzois, “Management of a Remote Backup Copy for Disaster Recovery”, ACM Transactions on Database Systems, volumen 16, número 2 (1991), páginas 338–368.

[Korth y Speegle 1994] H. F. Korth y G. Speegle, “Formal Aspects of Concurrency Control in Long Duration Transaction Systems Using the NT/PV Model”, ACM Transactions on Database Systems, volumen 19, número 3 (1994), páginas 492– 535.

[Kitsuregawa et al. 1983] M. Kitsuregawa, H. Tanaka y T. MotoOka, “Application of Hash to a Database Machine and its Architecture”, New Generation Computing, volumen 1, número 1 (1983), páginas 62–74.

[Krishnaprasad et al. 2004] M. Krishnaprasad, Z. Liu, A. Manikutty, J. W. Warner, V. Arora y S. Kotsovolos, “Query Rewrite for XML in Oracle XML DB”, Proc. of the International Conf. on Very Large Databases (2004), páginas 1122–1133.

[Kitsuregawa y Ogawa 1990] M. Kitsuregawa y Y. Ogawa, “Bucket Spreading Parallel Hash: A New, Robust, Parallel Hash Join Method for Skew in the Super Database Computer”, Proc. of the International Conf. on Very Large Databases (1990), páginas 210–221.

[Kung y Lehman 1980] H. T. Kung y P. L. Lehman, “Concurrent Manipulation of Binary Search Trees”, ACM Transactions on Database Systems, volumen 5, número 3 (1980), páginas 339–353.

[Kleinberg 1999] J. M. Kleinberg, “Authoritative Sources in a Hyperlinked Environment”, Journal of the ACM, volumen 46, número 5 (1999), páginas 604–632. [Kleinrock 1975] L. Kleinrock, Queuing Systems, Volume 1: Theory, John Wiley and Sons (1975). [Kleinrock 1976] L. Kleinrock, Queuing Systems, Volume 2: Computer Applications, John Wiley and Sons (1976). [Klug 1982] A. Klug, “Equivalence of Relational Algebra and Relational Calculus Query Languages Having Aggregate Functions”, ACM Press, volumen 29, número 3 (1982), páginas 699–717. [Knapp 1987] E. Knapp, “Deadlock Detection in Distributed Databases”, ACM Computing Survey, volumen 19, número 4 (1987). [Knuth 1973] D. E. Knuth, The Art of Computer Programming, volumen 3, Addison Wesley, Sorting and Searching (1973). [Kohavi y Provost 2001] R. Kohavi y F. Provost, editores, Applications of Data Mining to Electronic Commerce, Kluwer Academic Publishers (2001). [Konstan et al. 1997] J. A. Konstan, B. N. Miller, D. Maltz, J. L. Herlocker, L. R. Gordon y J. Riedl, “GroupLens: Applying Collaborative Filtering to Usenet News”, Communications of the ACM, volumen 40, número 3 (1997), páginas 77–87. [Korth 1982] H. F. Korth, “Deadlock Freedom Using Edge Locks”, ACM Transactions on Database Systems, volumen 7, número 4 (1982), páginas 632–652. [Korth 1983] H. F. Korth, “Locking Primitives in a Database System”, Journal of the ACM, volumen 30, número 1 (1983), páginas 55–79. [Korth et al. 1990] H. F. Korth, E. Levy y A. Silberschatz, “A Formal Approach to Recovery by Compensating Transac-

[Kung y Robinson 1981] H. T. Kung y J. T. Robinson, “Optimistic Concurrency Control”, ACM Transactions on Database Systems, volumen 6, número 2 (1981), páginas 312–326. [Labio et al. 1997] W. Labio, D. Quass y B. Adelberg, “Physical Database Design for Data Warehouses”, Proc. of the International Conf. on Data Engineering (1997). [Lahiri et al. 2001a] T. Lahiri, A. Ganesh, R. Weiss y A. Joshi, “Fast-Start: Quick Fault Recovery in Oracle”, Proc. of the ACM SIGMOD Conf. on Management of Data (2001). [Lahiri et al. 2001b] T. Lahiri, V. Srihari, W. Chan, N. MacNaughton y S. Chandrasekaran, “Cache Fusion: Extending Shared-Disk Clusters with Shared Caches”, Proc. of the International Conf. on Very Large Databases (2001), páginas 683–686. [Lai y Wilkinson 1984] M. Y. Lai y W. K. Wilkinson, “Distributed Transaction Management in JASMIN”, Proc. of the International Conf. on Very Large Databases (1984), páginas 466–472. [Lam y Kuo 2001] K.-Y. Lam y T.-W. Kuo, editores, Real-Time Database Systems, Kluwer (2001). [Lamb et al. 1991] C. Lamb, G. Landis, J. Orenstein y D. Weinreb, “The ObjectStore Database System”, Communications of the ACM, volumen 34, número 10 (1991), páginas 51–63. [Lamport 1978] L. Lamport, “Time, Clocks, and the Ordering of Events in a Distributed System”, Communications of the ACM, volumen 21, número 7 (1978), páginas 558–565. [Lampson y Sturgis 1976] B. Lampson y H. Sturgis, “Crash Recovery in a Distributed Data Storage System”, informe técnico, Computer Science Laboratory, Xerox Palo Alto Research Center,Palo Alto (1976). [Lanzelotte et al. 1993] R. Lanzelotte, P. Valduriez y M. Zar, “On the Effectiveness of Optimization Search Strategies for Parallel Execution Spaces”, Proc. of the International Conf. on Very Large Databases (1993).

www.detodoprogramacion.com


Bibliografía

935

[Larson y Yang 1985] P. Larson y H. Z. Yang, “Computing Queries from Derived Relations”, Proc. of the International Conf. on Very Large Databases (1985), páginas 259–269.

[Lynch et al. 1988] N. A. Lynch, M. Merritt, W. Weihl y A. Fekete, “A Theory of Atomic Transactions”, Proc. of the International Conf. on Database Theory (1988), páginas 41–71.

[Lecluse et al. 1988] C. Lecluse, P. Richard y F. Velez, “O2: An Object-Oriented Data Model”, Proc. of the International Conf. on Very Large Databases (1988), páginas 424–433.

[Lynch y Merritt 1986] N. A. Lynch y M. Merritt, “Introduction to the Theory of Nested Transactions”, Proc. of the International Conf. on Database Theory (1986).

[Lehman y Yao 1981] P. L. Lehman y S. B. Yao, “Efficient Locking for Concurrent Operations on B-trees”, ACM Transactions on Database Systems, volumen 6, número 4 (1981), páginas 650–670. [Lehner et al. 2000] W. Lehner, R. Sidle, H. Pirahesh y R. Cochrane, “Maintenance of Automatic Summary Tables”, Proc. of the ACM SIGMOD Conf. on Management of Data (2000), páginas 512–513. [Li y Mozes 2004] W. Li y A. Mozes, “Computing Frequent Itemsets Inside Oracle 10G”, Proc. of the International Conf. on Very Large Databases (2004), páginas 1253–1256. [Lin et al. 1994] E. T. Lin, E. R. Omiecinski y S. Yalamanchili, “Large Join Optimization on a Hypercube Multiprocessor”, IEEE Transactions on Knowledge and Data Engineering, volumen 6, número 2 (1994), páginas 304–315. [Lindsay et al. 1980] B. G. Lindsay, P. G. Selinger, C. Galtieri, J. N. Gray, R. A. Lorie, T. G. Price, G. R. Putzolu, I. L. Traiger y B. W. Wade. “Notes on Distributed Databases”, In Draffen y Poole, editores, Distributed Data Bases, páginas 247–284. Cambridge University Press, Cambridge, England (1980). [Litwin 1978] W. Litwin, “Virtual Hashing: A Dynamically Changing Hashing”, Proc. of the International Conf. on Very Large Databases (1978), páginas 517–523. [Litwin 1980] W. Litwin, “Linear Hashing: A New Tool for File and Table Addressing”, Proc. of the International Conf. on Very Large Databases (1980), páginas 212–223.

[Mackert y Lohman 1986] L. F. Mackert y G. M. Lohman, “R* Optimizer Validation and Performance Evaluation for Distributed Queries”, Proc. of the International Conf. on Very Large Databases (1986). [Maier 1983] D. Maier, The Theory of Relational Databases, Computer Science Press, Rockville (1983). [Martin et al. 1989] J. Martin, K. K. Chapman y J. Leben, DB2, Concepts, Design, and Programming, Prentice Hall (1989). [Mattison 1996] R. Mattison, Data Warehousing: Strategies, Technologies, and Techniques, McGraw-Hill (1996). [McHugh y Widom 1999] J. McHugh y J. Widom, “Query Optimization for XML”, Proc. of the International Conf. on Very Large Databases (1999), páginas 315–326. [Mehrotra et al. 1991] S. Mehrotra, R. Rastogi, H. F. Korth y A. Silberschatz, “Non-Serializable Executions in Heterogeneous Distributed Database Systems”, Proc. of the International Conf. on Parallel and Distributed Information Systems (1991). [Mehrotra et al. 2001] S. Mehrotra, R. Rastogi, Y. Breitbart, H. F. . Korth y A. Silberschatz, “Overcoming Heterogeneity and Autonomy in Multidatabase Systems.”, Inf. Comput., volumen 167, número 2 (2001), páginas 137–172. [Melton 2002] J. Melton, Advanced SQL:1999 – Understanding Object-Relational and Other Advanced Features, Morgan Kaufmann (2002). [Melton y Eisenberg 2000] J. Melton y A. Eisenberg, Understanding SQL and Java Together : A Guide to SQLJ, JDBC, and Related Technologies, Morgan Kaufmann (2000).

[Litwin 1981] W. Litwin, “Trie Hashing”, Proc. of the ACM SIGMOD Conf. on Management of Data (1981), páginas 19–29.

[Melton y Simon 1993] J. Melton y A. R. Simon, Understanding The New SQL: A Complete Guide, Morgan Kaufmann (1993).

[Lo y Ravishankar 1996] M.-L. Lo y C. V. Ravishankar, “Spatial Hash-Joins”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996).

[Melton y Simon 2001] J. Melton y A. R. Simon, SQL:1999 Understanding Relational Language Components, Morgan Kaufmann (2001).

[Loeb 1998] L. Loeb, Secure Electronic Transactions : Introduction and Technical Reference, Artech House (1998).

[Menasce et al. 1980] D. A. Menasce, G. Popek y R. Muntz, “A Locking Protocol for Resource Coordination in Distributed Databases”, ACM Transactions on Database Systems, volumen 5, número 2 (1980), páginas 103–138.

[Lomet 1981] D. G. Lomet, “Digital B-trees”, Proc. of the International Conf. on Very Large Databases (1981), páginas 333–344. [Lynch 1983] N. A. Lynch, “Multilevel Atomicity–A New Correctness Criterion for Database Concurrency Control”, ACM Transactions on Database Systems, volumen 8, número 4 (1983), páginas 484–502.

[Microsoft 1997] Microsoft, Microsoft ODBC 3.0 Software Development Kit and Programmer’s Reference, Microsoft Press (1997). [Mistry et al. 2001] H. Mistry, P. Roy, S. Sudarshan y K. Ramamritham, “Materialized View Selection and Maintenan-

www.detodoprogramacion.com


936

Bibliografía

ce Using Multi-Query Optimization”, Proc. of the ACM SIGMOD Conf. on Management of Data (2001). [Mitchell 1997] T. M. Mitchell, Machine Learning, McGraw-Hill (1997). [Mohan 1990a] C. Mohan, “ARIES/KVL: A Key-Value Locking Method for Concurrency Control of Multiaction Transactions Operations on B-Tree indexes”, Proc. of the International Conf. on Very Large Databases (1990), páginas 392–405. [Mohan 1990b] C. Mohan, “Commit-LSN: A Novel and Simple Method for Reducing Locking and Latching in Transaction Processing Systems”, Proc. of the International Conf. on Very Large Databases (1990), páginas 406–418. [Mohan 1993] C. Mohan, “IBM’s Relational Database Products:Features and Technologies”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993). [Mohan et al. 1986] C. Mohan, B. Lindsay y R. Obermarck, “Transaction Management in the R* Distributed Database Management System”, ACM Transactions on Database Systems, volumen 11, número 4 (1986), páginas 378–396. [Mohan et al. 1992] C. Mohan, D. Haderle, B. Lindsay, H. Pirahesh y P. Schwarz, “ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging”, ACM Transactions on Database Systems, volumen 17, número 1 (1992). [Mohan y Levine 1992] C. Mohan y F. Levine, “ARIES/IM:An Efficient and High-Concurrency Index Management Method Using Write-Ahead Logging”, Proc. of the ACM SIGMOD Conf. on Management of Data (1992). [Mohan y Lindsay 1983] C. Mohan y B. Lindsay, “Efficient Commit Protocols for the Tree of Processes Model of Distributed Transactions”, Proc. of the ACM Symposium on Principles of Distributed Computing (1983). [Mohan y Narang 1991] C. Mohan y I. Narang, “Recovery and Coherency-Control Protocols for Fast Intersystem Page Transfer and Fine-Granularity Locking in a Shared Disks Transaction Environment”, Proc. of the International Conf. on Very Large Databases (1991).

[Moss 1987] J. E. B. Moss, “Log-Based Recovery for Nested Transactions”, Proc. of the International Conf. on Very Large Databases (1987), páginas 427–432. [MSDN: XML Developer Center ] MSDN: XML Developer Center. “XML and the Database”. http://msdn.microsoft.com/XML/BuildingXML/XMLandDatabase/default.aspx. [Murthy y Banerjee 2003] R. Murthy y S. Banerjee, “XML Schemas in Oracle XML DB”, Proc. of the International Conf. on Very Large Databases (2003), páginas 1009–1018. [Nakayama et al. 1984] T. Nakayama, M. Hirakawa y T. Ichikawa, “Architecture and Algorithm for Parallel Execution of a Join Operation”, Proc. of the International Conf. on Data Engineering (1984). [Ng y Han 1994] R. T. Ng y J. Han, “Efficient and Effective Clustering Methods for Spatial Data Mining”, Proc. of the International Conf. on Very Large Databases (1994). [Nyberg et al. 1995] C. Nyberg, T. Barclay, Z. Cvetanovic, J. Gray y D. B. Lomet, “AlphaSort: A Cache-Sensitive Parallel External Sort”, VLDB Journal, volumen 4, número 4 (1995), páginas 603–627. [O’Neil et al. 2004] P. E. O’Neil, E. J. O’Neil, S. Pal, I. Cseri, G. Schaller y N. Westbury, “ORDPATHs: Insert-Friendly XML Node Labels”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004), páginas 903–908. [O’Neil y O’Neil 2000] P. O’Neil y E. O’Neil, Database: Principles, Programming, Performance, 2a edición, Morgan Kaufmann (2000). [O’Neil y Quass 1997] P. O’Neil y D. Quass, “Improved Query Performance with Variant Indexes”, Proc. of the ACM SIGMOD Conf. on Management of Data (1997). [Orenstein 1982] J. A. Orenstein, “Multidimensional Tries Used for Associative Searching”, Information Processing Letters, volumen 14, número 4 (1982), páginas 150–157. [Ozcan et al. 1997] F. Ozcan, S. Nural, P. Koksal, C. Evrendilek y A. Dogac, “Dynamic Query Optimization in Multidatabases”, Data Engineering Bulletin, volumen 20, número 3 (1997), páginas 38–45.

[Mohan y Narang 1992] C. Mohan y I. Narang, “Efficient Locking and Caching of Data in the Multisystem Shared Disks Transaction Environment”, Proc. of the International Conf. on Extending Database Technology (1992).

[Ozden et al. 1994] B. Ozden, A. Biliris, R. Rastogi y A. Silberschatz, “A Low-cost Storage Server for a Movie on Demand Database”, Proc. of the International Conf. on Very Large Databases (1994).

[Mohan y Narang 1994] C. Mohan y I. Narang, “ARIES/CSA: A Method for Database Recovery in Client-Server Architectures”, Proc. of the ACM SIGMOD Conf. on Management of Data (1994), páginas 55–66.

[Ozden et al. 1996a] B. Ozden, R. Rastogi, P. Shenoy y A. Silberschatz, “Fault-Tolerant Architectures for Continuous Media Servers”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996).

[Moss 1985] J. E. B. Moss, Nested Transactions: An Approach to Reliable Distributed Computing, MIT Press, Cambridge (1985).

[Ozden et al. 1996b] B. Ozden, R. Rastogi y A. Silberschatz, “On the Design of a Low-Cost Video-on-Demand Storage

www.detodoprogramacion.com


Bibliografía

937

System”, Multimedia Systems Journal, volumen 4, número 1 (1996), páginas 40–54.

(RAID)”, Proc. of the ACM SIGMOD Conf. on Management of Data (1988), páginas 109–116.

[Ozsoyoglu y Snodgrass 1995] G. Ozsoyoglu y R. Snodgrass, “Temporal and Real-Time Databases: A Survey”, IEEE Transactions on Knowledge and Data Engineering, volumen 7, número 4 (1995), páginas 513–532.

[Pellenkoft et al. 1997] A. Pellenkoft, C. A. Galindo-Legaria y M. Kersten, “The Complexity of Transformation-Based Join Enumeration”, Proc. of the International Conf. on Very Large Databases, Athens, Greece (1997), páginas 306–315.

[Ozsu y Valduriez 1999] T. Ozsu y P. Valduriez, Principles of Distributed Database Systems, 2a edición, Prentice Hall (1999).

[Pless 1998] V. Pless, Introduction to the Theory of ErrorCorrecting Codes, 3a edición, John Wiley and Sons (1998).

[Padmanabhan et al. 2003] S. Padmanabhan, B. Bhattacharjee, T. Malkemus, L. Cranston y M. Huras, “Multi-Dimensional Clustering: A New Data Layout Scheme in DB2”, Proc. of the ACM SIGMOD Conf. on Management of Data (2003), páginas 637–641. [Pal et al. 2004] S. Pal, I. Cseri, G. Schaller, O. Seeliger, L. Giakoumakis y V. Zolotov, “Indexing XML Data Stored in a Relational Database”, Proc. of the International Conf. on Very Large Databases (2004), páginas 1134–1145. [Pang et al. 1995] H.-H. Pang, M. J. Carey y M. Livny, “Multiclass Scheduling in Real-Time Database Systems”, IEEE Transactions on Knowledge and Data Engineering, volumen 2, número 4 (1995), páginas 533–551. [Papadimitriou 1979] C. H. Papadimitriou, “The Serializability of Concurrent Database Updates”, Journal of the ACM, volumen 26, número 4 (1979), páginas 631–653. [Papadimitriou 1986] C. H. Papadimitriou, The Theory of Database Concurrency Control, Computer Science Press, Rockville (1986). [Papadimitriou et al. 1977] C. H. Papadimitriou, P. A. Bernstein y J. B. Rothnie, “Some Computational Problems Related to Database Concurrency Control”, Proc. of the Conf. on Theoretical Computer Science (1977), páginas 275–282. [Papakonstantinou et al. 1996] Y. Papakonstantinou, A. Gupta y L. Haas, “Capabilities-Based Query Rewriting in Mediator Systems”, Proc. of the International Conf. on Parallel and Distributed Information Systems (1996). [Parker et al. 1983] D. S. Parker, G. J. Popek, G. Rudisin, A. Stoughton, B. J. Walker, E. Walton, J. M. Chow, D. Edwards, S. Kiser y C. Kline, “Detection of Mutual Inconsistency in Distributed Systems”, IEEE Transactions on Software Engineering, volumen 9, número 3 (1983), páginas 240–246. [Patel y DeWitt 1996] J. Patel y D. J. DeWitt, “Partition Based Spatial-Merge Join”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996). [Patterson 2004] D. P. Patterson, “Latency Lags Bandwidth”, Communications of the ACM, volumen 47, número 10 (2004), páginas 71–75. [Patterson et al. 1988] D. A. Patterson, G. Gibson y R. H. Katz, “A Case for Redundant Arrays of Inexpensive Disks

[Poe 1995] V. Poe, Building a Data Warehouse for Decision Support, Prentice Hall (1995). [Poess y Floyd 2000] M. Poess y C. Floyd, “New TPC Benchmarks for Decision Support and Web Commerce”, ACM SIGMOD Record, volumen 29, número 4 (2000). [Poess y Potapov 2003] M. Poess y D. Potapov, “Data Compression in Oracle”, Proc. of the International Conf. on Very Large Databases (2003), páginas 937–947. [Polyzois y Garcia-Molina 1994] C. Polyzois y H. GarciaMolina, “Evaluation of Remote Backup Algorithms for Transaction-Processing Systems”, ACM Transactions on Database Systems, volumen 19, número 3 (1994), páginas 423–449. [Poosala et al. 1996] V. Poosala, Y. E. Ioannidis, P. J. Haas y E. J. Shekita, “Improved Histograms for Selectivity Estimation of Range Predicates”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996), páginas 294–305. [Popek et al. 1981] G. J. Popek, B. J. Walker, J. M. Chow, D. Edwards, C. Kline, G. Rudisin y G. Thiel, “LOCUS: A Network Transparent, High Reliability Distributed System”, Proc. of the Eighth Symposium on Operating System Principles (1981), páginas 169–177. [Pu et al. 1988] C. Pu, G. Kaiser y N. Hutchinson, “SplitTransactions for Open-Ended Activities”, Proc. of the International Conf. on Very Large Databases (1988), páginas 26–37. [Rahm 1993] E. Rahm, “Empirical Performance Evaluation of Concurrency and Coherency Control Protocols for Database Sharing Systems”, ACM Transactions on Database Systems, volumen 8, número 2 (1993). [Ramakrishna y Larson 1989] M. V. Ramakrishna y P. Larson, “File Organization Using Composite Perfect Hashing”, ACM Transactions on Database Systems, volumen 14, número 2 (1989), páginas 231–263. [Ramakrishnan et al. 1992] R. Ramakrishnan, D. Srivastava y S. Sudarshan, Controlling the Search in Bottom-up Evaluation (1992). [Ramakrishnan y Gehrke 2002] R. Ramakrishnan y J. Gehrke, Database Management Systems, 3a edición, McGraw-Hill (2002).

www.detodoprogramacion.com


938

Bibliografía

[Ramakrishnan y Ullman 1995] R. Ramakrishnan y J. D. Ullman, “A Survey of Deductive Database Systems”, Journal of Logic Programming, volumen 23, número 2 (1995), páginas 125–149. [Ramesh et al. 1989] R. Ramesh, A. J. G. Babu y J. P. Kincaid, “Index Optimization: Theory and Experimental Results”, ACM Transactions on Database Systems, volumen 14, número 1 (1989), páginas 41–74. [Rangan et al. 1992] P. V. Rangan, H. M. Vin y S. Ramanathan, “Designing an On-Demand Multimedia Service”, Communications Magazine, volumen 1, número 1 (1992), páginas 56–64. [Rao y Ross 2000] J. Rao y K. A. Ross, “Making B+-Trees Cache Conscious in Main Memory”, Proc. of the ACM SIGMOD Conf. on Management of Data (2000), páginas 475–486. [Rathi et al. 1990] A. Rathi, H. Lu y G. E. Hedrick, “Performance Comparison of Extendable Hashing and Linear Hashing Techniques”, Proc. ACM SIGSmall/PC Symposium on Small Systems (1990), páginas 178–185. [Reed 1978] D. Reed, Naming and Synchronization in a Decentralized Computer System. PhD thesis, Department of Electrical Engineering, MIT, Cambridge (1978). [Reed 1983] D. Reed, “Implementing Atomic Actions on Decentralized Data”, Transactions on Computer Systems, volumen 1, número 1 (1983), páginas 3–23. [Revesz 2002] P. Revesz, Introduction to Constraint Databases, Springer Verlag (2002). [Richardson et al. 1987] J. Richardson, H. Lu y K. Mikkilineni, “Design and Evaluation of Parallel Pipelined Join Algorithms”, Proc. of the ACM SIGMOD Conf. on Management of Data (1987).

ral Support for Programming Languages and Operating Systems (1991), páginas 1–15. [Rosenthal y Reiner 1984] A. Rosenthal y D. Reiner, “Extending the Algebraic Framework of Query Processing to Handle Outerjoins”, Proc. of the International Conf. on Very Large Databases (1984), páginas 334–343. [Ross 1990] K. A. Ross, “Modular Stratification and Magic Sets for DATALOG Programs with Negation”, Proc. of the ACM SIGMOD Conf. on Management of Data (1990). [Ross 1999] S. M. Ross, Introduction to Probability and Statistics for Engineers and Scientists, Harcourt/Academic Press (1999). [Ross et al. 1996] K. Ross, D. Srivastava y S. Sudarshan, “Materialized View Maintenance and Integrity Constraint Checking: Trading Space for Time”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996). [Ross y Srivastava 1997] K. A. Ross y D. Srivastava, “Fast Computation of Sparse Datacubes”, Proc. of the International Conf. on Very Large Databases (1997), páginas 116–125. [Rothermel y Mohan 1989] K. Rothermel y C. Mohan, “ARIES/NT: A Recovery Method Based on Write-Ahead Logging for Nested Transactions”, Proc. of the International Conf. on Very Large Databases (1989), páginas 337–346. [Roy et al. 2000] P. Roy, S. Seshadri, S. Sudarshan y S. Bhobhe, “Efficient and Extensible Algorithms for Multi-Query Optimization”, Proc. of the ACM SIGMOD Conf. on Management of Data (2000). [Rusinkiewicz y Sheth 1995] M. Rusinkiewicz y A. Sheth. “Specification and Execution of Transactional Workflows”, In Kim [1995], páginas 592–620 (1995). [Rustin 1972] R. Rustin, Data Base Systems, Prentice Hall (1972).

[Rivest 1976] R. L. Rivest, “Partial Match Retrieval Via the Method of Superimposed Codes”, SIAM Journal of Computing, volumen 5, número 1 (1976), páginas 19–50. [Rizvi et al. 2004] S. Rizvi, A. Mendelzon, S. Sudarshan y P. Roy, “Extending Query Rewriting Techniques for FineGrained Access Control”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004). [Robinson 1981] J. Robinson, “The k-d-B Tree: A Search Structure for Large Multidimensional Indexes”, Proc. of the ACM SIGMOD Conf. on Management of Data (1981), páginas 10–18. [Roos 2002] R. M. Roos, Java Data Objects, Pearson Education (2002).

[Rys 2001] M. Rys, “Bringing the Internet to Your Database: Using SQL Server 2000 and XML to Build Loosely-Coupled Systems”, Proc. of the International Conf. on Data Engineering (2001), páginas 465–472. [Rys 2003] M. Rys. “XQuery and Relational Database Systems”, In H. Katz, editor, XQuery From the Experts, páginas 353–391. Addison Wesley (2003). [Rys 2004] M. Rys. “What’s New in FOR XML in Microsoft SQL Server 2005”. http://msdn.microsoft.com/library/enus/dnsql90/html/forxml2k5.asp (2004).

[Rosch 2003] W. L. Rosch, The Winn L. Rosch Hardware Bible, 6a edición, Que (2003).

[Sagiv y Yannakakis 1981] Y. Sagiv y M. Yannakakis, “Equivalence among Relational Expressions with the Union and Difference Operators”, Proc. of the ACM SIGMOD Conf. on Management of Data, volumen 27, número 4 (1981).

[Rosenblum y Ousterhout 1991] M. Rosenblum y J. K. Ousterhout, “The Design and Implementation of a Log-Structured File System”, Proc. of the International Conf. on Architectu-

[Salem et al. 1994] K. Salem, H. Garcia-Molina y J. Sands, “Altruistic Locking”, ACM Transactions on Database Systems, volumen 19, número 1 (1994), páginas 117–165.

www.detodoprogramacion.com


Bibliografía

939

[Salem y Garcia-Molina 1986] K. Salem y H. Garcia-Molina, “Disk Striping”, Proc. of the International Conf. on Data Engineering (1986), páginas 336–342.

[Sellis 1988] T. K. Sellis, “Multiple Query Optimization”, ACM Transactions on Database Systems, volumen 13, número 1 (1988), páginas 23–52.

[Salton 1989] G. Salton, Automatic Text Processing, Addison Wesley (1989).

[Sellis et al. 1987] T. K. Sellis, N. Roussopoulos y C. Faloutsos, “The R+ -Tree: A Dynamic Index for Multi-Dimensional Objects”, Proc. of the International Conf. on Very Large Databases (1987), páginas 507–518.

[Samet 1990] H. Samet, The Design and Analysis of Spatial Data Structures, Addison Wesley (1990). [Samet 1995a] H. Samet, “General Research Issues in Multimedia Database Systems”, ACM Computing Survey, volumen 27, número 4 (1995), páginas 630–632. [Samet 1995b] H. Samet. “Spatial Data Structures”, In Kim [1995], páginas 361–385 (1995). [Samet y Aref 1995] H. Samet y W. Aref. “Spatial Data Models and Query Processing”, In Kim [1995], páginas 338–360 (1995). [Sanders 1998] R. E. Sanders, ODBC 3.5 Developer’s Guide, McGraw-Hill (1998). [Sanders 2000] R. E. Sanders, DB2 Universal Database SQL Developer’s Guide, McGraw-Hill (2000). [Sarawagi 2000] S. Sarawagi, “User-Adaptive Exploration of Multidimensional Data”, Proc. of the International Conf. on Very Large Databases (2000), páginas 307–316. [Sarawagi et al. 2002] S. Sarawagi, A. Bhamidipaty, A. Kirpal y C. Mouli, “ALIAS: An Active Learning Led Interactive Deduplication System”, Proc. of the International Conf. on Very Large Databases (2002), páginas 1103–1106. [Schlageter 1981] G. Schlageter, “Optimistic Methods for Concurrency Control in Distributed Database Systems”, Proc. of the International Conf. on Very Large Databases (1981), páginas 125–130. [Schneider 1982] H. J. Schneider, Distributed Data Bases (1982). [Schneider y DeWitt 1989] D. Schneider y D. DeWitt, “A Performance Evaluation of Four Parallel Join Algorithms in a Shared-Nothing Multiprocessor Environment”, Proc. of the ACM SIGMOD Conf. on Management of Data (1989). [Schning 2001] H. Schning, “Tamino - A DBMS Designed for XML”, Proc. of the International Conf. on Data Engineering (2001), páginas 149–154. [Selinger et al. 1979] P. G. Selinger, M. M. Astrahan, D. D. Chamberlin, R. A. Lorie y T. G. Price, “Access Path Selection in a Relational Database System”, Proc. of the ACM SIGMOD Conf. on Management of Data (1979), páginas 23–34. [Selinger y Adiba 1980] P. G. Selinger y M. E. Adiba, “Access Path Selection in Distributed Database Management Systems”, informe técnico RJ2338, IBM Research Laboratory, San Jose (1980).

[Seshadri et al. 1996] P. Seshadri, H. Pirahesh y T. Y. C. Leung, “Complex Query Decorrelation”, Proc. of the International Conf. on Data Engineering (1996), páginas 450–458. [Shafer et al. 1996] J. C. Shafer, R. Agrawal y M. Mehta, “SPRINT: A Scalable Parallel Classifier for Data Mining”, Proc. of the International Conf. on Very Large Databases (1996), páginas 544–555. [Shanmugasundaram et al. 1999] J. Shanmugasundaram, G. He, K. Tufte, C. Zhang, D. DeWitt y J. Naughton, “Relational Databases for Querying XML Documents: Limitations and Opportunities”, Proc. of the International Conf. on Very Large Databases (1999). [Shapiro 1986] L. D. Shapiro, “Join Processing in Database Systems with Large Main Memories”, ACM Transactions on Database Systems, volumen 11, número 3 (1986), páginas 239–264. [Shasha et al. 1995] D. Shasha, F. Llirabat, E. Simon y P. Valduriez, “Transaction Chopping: Algorithms and Performance Studies”, ACM Transactions on Database Systems, volumen 20, número 3 (1995), páginas 325–363. [Shasha y Bonnet 2002] D. Shasha y P. Bonnet, Database Tuning: Principles, Experiments, and Troubleshooting Techniques, Morgan Kaufmann (2002). [Shatdal y Naughton 1993] A. Shatdal y J. Naughton, “Using Shared Virtual Memory for Parallel Join Processing”, Proc. of the ACM SIGMOD Conf. on Management of Data (1993). [Silberschatz 1982] A. Silberschatz, “A Multi-Version Concurrency Control Scheme With No Rollbacks”, Proc. of the ACM Symposium on Principles of Distributed Computing (1982), páginas 216–223. [Silberschatz et al. 1990] A. Silberschatz, M. R. Stonebraker y J. D. Ullman, “Database Systems: Achievements and Opportunities”, ACM SIGMOD Record, volumen 19, número 4 (1990). [Silberschatz et al. 1996] A. Silberschatz, M. Stonebraker y J. Ullman, “Database Research: Achievements and Opportunities into the 21st Century”, informe técnico CS-TR-96-1563, Department of Computer Science, Stanford University, Stanford (1996). [Silberschatz et al. 2001] A. Silberschatz, P. B. Galvin y G. Gagne, Operating System Concepts, 6a edición, John Wiley and Sons (2001).

www.detodoprogramacion.com


940

Bibliografía

[Silberschatz y Kedem 1980] A. Silberschatz y Z. Kedem, “Consistency in Hierarchical Database Systems”, Journal of the ACM, volumen 27, número 1 (1980), páginas 72–80.

[Stonebraker 1986] M. Stonebraker, “Inclusion of New Types in Relational Database Systems”, Proc. of the International Conf. on Data Engineering (1986), páginas 262–269.

[Simmen et al. 1996] D. Simmen, E. Shekita y T. Malkemus, “Fundamental Techniques for Order Optimization”, Proc. of the ACM SIGMOD Conf. on Management of Data, Montreal, Canada (1996), páginas 57–67.

[Stonebraker et al. 1989] M. Stonebraker, P. Aoki y M. Seltzer, “Parallelism in XPRS”, Proc. of the ACM SIGMOD Conf. on Management of Data (1989).

[Skeen 1981] D. Skeen, “Non-blocking Commit Protocols”, Proc. of the ACM SIGMOD Conf. on Management of Data (1981), páginas 133–142.

[Stonebraker et al. 1990] M. Stonebraker, A. Jhingran, J. Goh y S. Potamianos, “On Rules, Procedure, Caching and Views in Database Systems”, Proc. of the ACM SIGMOD Conf. on Management of Data (1990), páginas 281–290.

[Soderland 1999] S. Soderland, “Learning Information Extraction Rules for Semi-structured and Free Text”, Machine Learning, volumen 34, número 1–3 (1999), páginas 233–272.

[Stonebraker y Rowe 1986] M. Stonebraker y L. Rowe, “The Design of POSTGRES”, Proc. of the ACM SIGMOD Conf. on Management of Data (1986).

[Soo 1991] M. Soo, “Bibliography on Temporal Databases”, ACM SIGMOD Record, volumen 20, número 1 (1991), páginas 14–23.

[Stuart et al. 1984] D. G. Stuart, G. Buckley y A. Silberschatz, “A Centralized Deadlock Detection Algorithm”, informe técnico, Department of Computer Sciences, University of Texas, Austin (1984).

[Spector y Schwarz 1983] A. Z. Spector y P. M. Schwarz, “Transactions: A Construct for Reliable Distributed Computing”, Operating Systems Review, volumen 17, número 2 (1983), páginas 18–35.

[Sudarshan y Ramakrishnan 1991] S. Sudarshan y R. Ramakrishnan, “Aggregation and Relevance in Deductive Databases”, Proc. of the International Conf. on Very Large Databases (1991).

[SQL/XML 2004] SQL/XML. “ISO/IEC 9075-14:2003, Information Technology: Database languages: SQL.Part 14: XMLRelated Specifications (SQL/XML)” (2004).

[Tanenbaum 2002] A. S. Tanenbaum, Computer Networks, 4a edición, Prentice Hall (2002).

[Srikant y Agrawal 1996a] R. Srikant y R. Agrawal, “Mining Quantitative Association Rules in Large Relational Tables”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996).

[Tansel et al. 1993] A. Tansel, J. Clifford, S. Gadia, S. Jajodia, A. Segev y R. Snodgrass, Temporal Databases: Theory, Design and Implementation, Benjamin Cummings, Redwood City (1993).

[Srikant y Agrawal 1996b] R. Srikant y R. Agrawal, “Mining Sequential Patterns: Generalizations and Performance Improvements”, Proc. of the International Conf. on Extending Database Technology (1996), páginas 3–17.

[Teorey et al. 1986] T. J. Teorey, D. Yang y J. P. Fry, “A Logical Design Methodology for Relational Databases Using the Extended Entity-Relationship Model”, ACM Computing Survey, volumen 18, número 2 (1986), páginas 197–222.

[Srinivasan et al. 2000a] J. Srinivasan, S. Das, C. Freiwald, E. I. Chong, M. Jagannath, A. Yalamanchi, R. Krishnan, A.-T. Tran, S. DeFazio y J. Banerjee, “Oracle 8i Index-Organized Table and Its Application to New Domains”, Proc. of the International Conf. on Very Large Databases (2000), páginas 285–296.

[Thalheim 2000] B. Thalheim, Entity-Relationship Modeling : Foundations of Database Technology, Springer Verlag (2000).

[Srinivasan et al. 2000b] J. Srinivasan, R. Murthy, S. Sundara, N. Agarwal y S. DeFazio, “Extensible Indexing: A Framework for Integrating Domain-Specific Indexing Schemes into Oracle 8i”, Proc. of the International Conf. on Data Engineering (2000), páginas 91–100. [Stam y Snodgrass 1988] R. Stam y R. Snodgrass, “A Bibliography on Temporal Databases”, IEEE Transactions on Knowledge and Data Engineering, volumen 7, número 4 (1988), páginas 231–239. [Stinson 2002] B. Stinson, PostgreSQL Essential Reference, New Riders (2002).

[Thomas 1979] R. H. Thomas, “A Majority Consensus Approach to Concurrency Control”, ACM Transactions on Database Systems, volumen 4, número 2 (1979), páginas 180–219. [Thomas 1996] S. A. Thomas, IPng and the TCP/IP Protocols: Implementing the Next Generation Internet, John Wiley and Sons (1996). [Traiger et al. 1982] I. L. Traiger, J. N. Gray, C. A. Galtieri y B. G. Lindsay, “Transactions and Consistency in Distributed Database Management Systems”, ACM Transactions on Database Systems, volumen 7, número 3 (1982), páginas 323–342. [Tremblay y Sorenson 1985] J. P. Tremblay y P. G. Sorenson, The Theory and Practice of Compiler Writing, McGraw-Hill (1985).

www.detodoprogramacion.com


Bibliografía

941

[Tsukuda et al. 1992] S. Tsukuda, M. Nakano, M. Kitsuregawa y M. Takagi, “Parallel Hash Join on Shared-Everything Multiprocessor”, Proc. of the International Conf. on Data Engineering (1992).

[Weikum y Schek 1984] G. Weikum y H. J. Schek, “Architectural Issues of Transaction Management in Multi-Level Systems”, Proc. of the International Conf. on Very Large Databases (1984), páginas 454–465.

[Tyagi et al. 2003] S. Tyagi, M. Vorburger, K. McCammon y H. Bobzin, Core Java Data Objects, Prentice Hall (2003).

[Weltman y Dahbura 2000] R. Weltman y T. Dahbura, LDAP Programming with Java, Addison Wesley (2000).

[Ullman 1988] J. D. Ullman, Principles of Database and Knowledge-base Systems, volumen 1, Computer Science Press, Rockville (1988).

[Wilschut et al. 1995] A. N. Wilschut, J. Flokstra y P. M. Apers, “Parallel Evaluation of Multi-Join Queues”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 115– 126.

[Ullman 1989] J. D. Ullman, Principles of Database and Knowledge-base Systems, volumen 2, Computer Science Press, Rockville (1989). [Umar 1997] A. Umar, Application (Re)Engineering : Building Web-Based Applications and Dealing With Legacies, Prentice Hall (1997). [UniSQL 1991] UniSQL/X Database Management System User’s Manual: Release 1.2. UniSQL, Inc. (1991). [Verhofstad 1978] J. S. M. Verhofstad, “Recovery Techniques for Database Systems”, ACM Computing Survey, volumen 10, número 2 (1978), páginas 167–195. [Vista 1998] D. Vista, “Integration of Incremental View Maintenance into Query Optimizers”, Proc. of the International Conf. on Extending Database Technology (1998). [Vitter 2001] J. S. Vitter, “External Memory Algorithms and Data Structures: Dealing with Massive Data”, ACM Computing Surveys, volumen 33, (2001), páginas 209–271. [Wachter y Reuter 1992] H. Wachter y A. Reuter. “The ConTract Model”, In A. K. Elmagarmid, editor, Database Transaction Models for Advanced Applications. Morgan Kaufmann (1992). [Walsh et al. 2004] N. Walsh et al. “XQuery 1.0 and XPath 2.0 Data Model”. http://www.w3.org/TR/xpath-datamodel/. currently a W3C Working Draft (2004). [Walton et al. 1991] C. Walton, A. Dale y R. Jenevein, “A Taxonomy and Performance Model of Data Skew Effects in Parallel Joins”, Proc. of the International Conf. on Very Large Databases (1991). [Weihl y Liskov 1990] W. Weihl y B. Liskov. “Implementation of Resilient, Atomic Data Types”, In Zdonik y Maier [1990], páginas 332–344 (1990).

[Wipfler 1987] A. J. Wipfler, CICS: Application Development and Programming, Macmillan Publishing, New York (1987). [Witkowski et al. 2003a] A. Witkowski, S. Bellamkonda, T. Bozkaya, G. Dorman, N. Folkert, A. Gupta, L. Sheng y S. Subramanian, “Spreadsheets in RDBMS for OLAP”, Proc. of the ACM SIGMOD Conf. on Management of Data (2003), páginas 52–63. [Witkowski et al. 2003b] A. Witkowski, S. Bellamkonda, T. Bozkaya, N. Folkert, A. Gupta, L. Sheng y S. Subramanian, “Business Modelling Using SQL Spreadsheets”, Proc. of the International Conf. on Very Large Databases (2003), páginas 1117–1120. [Witten et al. 1999] I. H. Witten, A. Moffat y T. C. Bell, Managing Gigabytes: Compressing and Indexing Documents and Images, Second Edition, Morgan Kaufmann (1999). [Witten y Frank 1999] I. H. Witten y E. Frank, Data Mining: Practical Machine Learning Tools and Techniques with Java Implementations, Morgan Kaufmann (1999). [Wolf 1991] J. Wolf, “An Effective Algorithm for Parallelizing Hash Joins in the Presence of Data Skew”, Proc. of the International Conf. on Data Engineering (1991). [Wong 1977] E. Wong, “Retrieving Dispersed Data from SDD1: A System for Distributed Databases”, Proc. of the Berkeley Workshop on Distributed Data Management and Computer Networks (1977), páginas 217–235. [Wu et al. 2003] Y. Wu, J. M. Patel y H. V. Jagadish, “Structural Join Order Selection for XML Query Optimization”, Proc. of the International Conf. on Data Engineering (2003). [Wu y Buchmann 1998] M. Wu y A. Buchmann, “Encoded Bitmap Indexing for Data Warehouses”, Proc. of the International Conf. on Data Engineering (1998).

[Weikum 1991] G. Weikum, “Principles and Realization Strategies of Multilevel Transaction Management”, ACM Transactions on Database Systems, volumen 16, número 1 (1991).

[X/Open 1991] X/Open Snapshot: X/Open DTP: XA Interface. X/Open Company, Ltd. (1991).

[Weikum et al. 1990] G. Weikum, C. Hasse, P. Broessler y P. Muth, “Multi-Level Recovery”, Proc. of the ACM SIGMOD Conf. on Management of Data (1990), páginas 109–123.

[Yan y Larson 1995] W. P. Yan y P. A. Larson, “Eager Aggregation and Lazy Aggregation”, Proc. of the International Conf. on Very Large Databases, Zurich (1995).

www.detodoprogramacion.com


942

Bibliografía

[Yannakakis et al. 1979] M. Yannakakis, C. H. Papadimitriou y H. T. Kung, “Locking Protocols: Safety and Freedom from Deadlock”, Proc. of the IEEE Symposium on the Foundations of Computer Science (1979), páginas 286–297.

[Zhou y Ross 2004] J. Zhou y K. A. Ross, “Buffering Database Operations for Enhanced Instruction Cache Performance”, Proc. of the ACM SIGMOD Conf. on Management of Data (2004), páginas 191–202.

[Zaharioudakis et al. 2000] M. Zaharioudakis, R. Cochrane, G. Lapis, H. Pirahesh y M. Urata, “Answering Complex SQL Queries using Automatic Summary Tables”, Proc. of the ACM SIGMOD Conf. on Management of Data (2000), páginas 105– 116.

[Zhuge et al. 1995] Y. Zhuge, H. Garcia-Molina, J. Hammer y J. Widom, “View Maintenance in a Warehousing Environment”, Proc. of the ACM SIGMOD Conf. on Management of Data (1995), páginas 316–327.

[Zaniolo et al. 1997] C. Zaniolo, S. Ceri, C. Faloutsos, R. Snodgrass, R. Zicari y V. S. Subrahmanian, Advanced Database Systems, Morgan Kaufmann (1997). [Zdonik y Maier 1990] S. Zdonik y D. Maier, Readings in ObjectOriented Database Systems, Morgan Kaufmann (1990). [Zeller y Gray 1990] H. Zeller y J. Gray, “An Adaptive Hash Join Algorithm for Multiuser Environments”, Proc. of the International Conf. on Very Large Databases (1990), páginas 186– 197. [Zhang et al. 1996] T. Zhang, R. Ramakrishnan y M. Livny, “BIRCH: An Efficient Data Clustering Method for Very Large Databases”, Proc. of the ACM SIGMOD Conf. on Management of Data (1996), páginas 103–114.

[Zikopoulos et al. 2000] P. Zikopoulos, R. Melnyk y L. Logomirski, DB2 for Dummies, Hungry Minds, Inc. (2000). [Zikopoulos et al. 2004] P. Zikopoulos, G. Baklarz, D. deRoos y R. B. Melnyk, DB2 Version 8: The Official Guide, IBM Press (2004). [Zilio et al. 2004] D. Zilio, J. Rao, S. Lightstone, G. Lohman, A. Storm, C. Garcia-Arellano y S. Fadden, “DB2 Design Advisor: Integrated Automatic Physical Database Design”, Proc. of the International Conf. on Very Large Databases (2004). [Zloof 1977] M. M. Zloof, “Query-by-Example: A Data Base Language”, IBM Systems Journal, volumen 16, número 4 (1977), páginas 324–343.

www.detodoprogramacion.com


Índice 1FN, véase forma normal, primera 2FN, véase forma normal, segunda 3FN, véase forma normal, tercera 4FN, véase forma normal, cuarta a priori, 622 ABD, véase administrador de bases de datos abstracción, 605 abstracción de datos, 4 nivel de vistas, 5 nivel físico, 5 nivel lógico, 5 Access de Microsoft, 59 ACID, 508, 777, 780 Active Directory, 290 Active Server Pages, 270 Active Server Pages.NET, 272 actualizaciones, 55, 87 ad hoc, 743 administrador de bases de datos, 22 ADO (ActiveX Data Objects), 117, 747, 905 ADO.NET, 117 AES (Advanced Encryption Standard), 286 Agarwal, Sameet, 885 agregación, 196 funciones, 49, 73, 75 binarias, 608 operación, 50 paralela, 684 agrupación de conexiones, 273 agrupaciones, 615, 660 agrupamiento, 623 aglomerativo, 623 divisivo, 623 jerárquico, 623 Ailamaki, Anastassia, 807 aislamiento, 508, 509 AIX, 859 ajuste de la curva, 620 ajuste del rendimiento, 733 álgebra relacional, 36 expresión, 38, 715 algoritmo de acoso, 713 de elección, 713, 724 de grafos, 644 de programación dinámica, 489 de recuperación, 701 del ascensor, 373 híbrido de reunión por mezcla, 457

impaciente, 616 Rijndael, 286 alias, 696, 721 de tipos, 102, 103 all privileges, 111 almacenamiento, 367 óptico, 368 conectado en red, 372 distribuido de datos, 694 en cinta, 368 en conexión, 369 en discos magnéticos, 368 estable, 568 nativo, 353 no volátil, 369, 568, 584 primario, 369 secundario, 369 seguro, 287 sin conexión, 369 terciario, 369, 382 volátil, 369, 568 almacenes de datos, 602, 612 arquitectura dirigida por el destino, 613 los orígenes, 613 alta disponibilidad, 567 Amazon, 357 ámbito, 313 Ampex, exploración helicoidal, 383 ampliabilidad, 658 de transacciones, 658 lineal, 658 por lotes, 658 sublineal, 658 análisis estadístico, 602 anfitriones móviles, 768 anidamiento, 312 anidar, 332 subconsultas, 76 ANSI (American National Standards Institute), 61, 745, 809, 891 Apache DB, 328 proyecto Jakarta, 270 sistema Tomcat, 297 aplicaciones multisistema, 781 árboles, 340 B+, véase índices, árbol B+ B, véase índices, árbol B binario, 410 completo, 500

cuadráticos, 762 PR, 762 regionales, 762 de operadores, 466, 678 en memoria, 410 equilibrado, 408 k-d, 761 k-d B, 761 R, véase índices, árbol R archivos, 386 cabecera, 388 estructura, 390 organización, 373 asociativa (hash), 390 en montículos, 390 secuencial, 390 reorganizar, 391 secuenciales, 390 fragmentados, 374 indexados, 402 secuenciales indexados, 436 ARIES, 566, 588, 597, 803, 824, 859, 879, 902 Armstrong, axiomas, 232 completos, 232 correctos, 232 Arpanet, 667 arquitectura de dos capas, 20 de memoria no uniforme, 663 de tres capas, 20 disco compartido, 660 jerárquica, 660, 662 memoria compartida, 660 paralela de bases de datos, 660 sin compartimiento, 660 Arquitectura común de agente para solicitudes de objetos, 747 ASCII, 717 aserto, 110 asignación, operación, 48 asistentes para el ajuste, 738 asociación, 421 abierta, 424 cerrada, 424 dinámica, 426 esquemas, 431 extensible, 426, 430 función, 401 lineal, 431 reglas, 621 asociaciones, 615, 621 943

www.detodoprogramacion.com


944

Índice

asociativa, propiedad, 46, 478 ASP (Active Server Pages), 260, 270, 272 ASP.NET, 272 asunción de un rol único, 249 atómico, 223 ATA (AT Attachment), 371 ataques de diccionario, 287 de personas intermedias, 788 atasco, 423 atomicidad, 18, 507, 508, 512, 567, 571 ante fallos, 783 atributos, 13, 29, 172, 334 autorreferencial, 313 compuesto, 175, 304 de dimensión, 603 de medida, 603 de partición, 617 derivado, 176 descriptivo, 174 determinado funcionalmente, 233 determinantes, 618 monovalorado, 175 multivalorado, 175 raros, 235 simple, 175 valor, 172 aumento, 522 autentificar, 288 autodocumentado, 331 autonomía, 717 local, 664 autoridad, 637 autorización, 9, 62, 111 de actualización, 9 de eliminación, 9 de inserción, 9 de lectura, 9 en el nivel de las filas, 285 read, 284 update, 284 axiomas, 232 ayuda a la toma de decisiones, 602, 673, 742, 743 B+, árbol, véase índices, árbol B+ B, árbol, véase índices, árbol B bases de datos, 1 CAD, 323 con memoria intermedia, 582 de diseño, 757 distribuidas heterogéneas, 693 homogéneas, 693 en memoria principal, 788 móviles, 754 multimedia, 765 orientadas a objetos, 301, 322 basadas en lenguajes de programación persistentes, 323 relacionales diseño, 219 orientadas a objetos, 322 relacionales basadas en objetos, 301 temporales, 754

virtual, 718 privada, 284 batidores Web, 641 Bayes lógica ingenua, 920 teorema, 620 BEA, 270, 777 biblioteca de etiquetas, 271 big-endian, 718 billete, 798 bits de sal, 287 Blakeley, José A., 885 blob, 104 bloqueos, 522, 529, 700 bajada, 535 compartido, 544 compatibilidad, 530 comunicación, 657 con límite de tiempo, 550 concesión, 529, 533 conversiones, 535 de dos fases, 792 de la siguiente clave, 559 de valores clave, 559 del índice, 555 en modo compartido, 529 en modo exclusivo, 529 exclusivo, 544 explícito, 544 expropiación, 549 función de compatibilidad, 529 gestor, 536 único, 704 distribuido, 704 implícito, 544 liberación, 657 modos intencional, 545 intencional-compartido, 545 intencional-exclusivo, 545 intencional-exclusivo y compartido, 545 protocolos, 560 con árboles B enlazados, 558 de árbol, 538 de dos fases, 533, 544 de dos fases multiversión, 548 de granularidad múltiple, 546 definición, 532 del índice, 555 del cangrejo, 557 estricto de dos fases, 534 riguroso de dos fases, 534 solicitud, 529 subida, 535 tabla, 536 bloques, 373, 383, 570 clavados, 384 de memoria intermedia, 570 físicos, 570 Bluetooth, 769 bolsas, 787 borrado, 54, 84 borrar, instrucción, 553, 553 brazo del disco, 370

www.detodoprogramacion.com

buffer, véase memoria intermedia bus, 660 búsqueda, 558 binaria, 446 difusa, 613 lineal, 446 C, 11, 62, 112 DB2, 863 monitores de teleprocesamiento, 779 PostgreSQL, 809 C++, 11, 62, 316, 319, 507 monitores de teleprocesamiento, 779 C2F, véase protocolos, de compromiso, de dos fases C3F, véase protocolos, de compromiso, de tres fases cabeza, 153 de lectura y escritura, 370 caché, 367 alojar, 657 coherencia, 657, 677 CAD (Computer Aided Design), 756, 757 cadena de desbordamiento, 424 cadenas de caracteres operaciones, 69 caída del sistema, 567 caja límite, 762 cajones, 421 de desbordamiento, 424 desbordamiento, 423 cálculo relacional de dominios, 141 de tuplas, 137 Call Level Interface, véase CLI (Call Level Interface) cambiadores automáticos, 368 de cintas, 383 de discos, 382 cambio de contexto, 778 caminos de acceso, 447 carga, 614 carga de trabajo, 498, 738 case, 124 casos, 621 catálogos, 104, 117, 120, 356 del sistema, 393 cauce, 466 CD (Compact Disk), 368 celda, 768 celular, véase teléfonos móviles centroide, 623 certificados digitales, 289, 788 CGI (Common Gateway Interface), véase interfaz, de pasarela común ChemML, 356 ciclos falsos, 710 CICS, 777 cierre, 226, 232, 234, 246 transitivo, 127, 160, 160 cifrado clave pública, 286 clave privada, 286 CIFS, 372 cilindro, 370


Índice 945

cintas magnéticas, 382 círculos, 756 clases de objetos, 720 clasificación, 616 densa, 98 por popularidad, 635 por prestigio, 635 clasificadores bayesianos, 620, 620 ingenuos, 620 de árboles de decisión, 616 de redes neuronales, 620 clave de búsqueda, 390 claves, 178 candidata, 34, 178 de búsqueda, 402 externa, 35, 107, 109, 279 primaria, 34, 63, 178 claves de búsqueda accesos bajo varias, 418 compuesta, 419 CLI (Call Level Interface), 117, 746 normas, 745 clientes, 20 clob, 104 CLR (Common Language Runtime), 125, 908, 909 CLR .NET, 908 Cobol, 11, 62, 112 CODASYL de DBTG, 745 Codd, E. F., 23, 59, 257 códigos de corrección de errores tipo memoria, 377 de Reed-Solomon, 380 coerción, 102 coincidencia, 347 cola duradera, 780 ColdFusion, véase lenguajes, de marcas, de ColdFusion COM (Component Object Model), 908 Common Object Request Broker Architecture, véase CORBA componentes control de concurrencia, 510, 516 gestión de recuperaciones, 509 gestión de transacciones, 18, 509 compresión de la carga de trabajo, 739 del prefijo, 417 comprobación de la secuencialidad, 522 de validación, 543 compromiso, véase protocolos, de compromiso concepto, 639 concreción, 605 condiciones de excepción, 124 de partición, 617 conexión continua, 667 discontinua, 667 confianza, 621 conflicto, 517

conjunto de entidades, 13, 171 débiles, 189, 189, 203 de nivel inferior, 193 de nivel superior, 193 fuertes, 189, 203 identificadoras, 189 propietarias, 189 conjunto de relaciones, 13, 173, 179, 200 binario, 175 grado, 175 recursivo, 173 conjuntos comparación, 77 de formación, 616 de resultados actualizables, 120 de valores, 175 grandes de elementos, 622 operaciones, 71 conmutativa, propiedad, 477 connect by, 834 Consejo para el rendimiento del procesamiento de las transacciones, 742 consenso de quórum, 706 conserva las dependencias, 229 consistencia, 18, 507, 508, 770 de grado dos, 555 de los datos, 105, 513, 581 consistente en cuanto a operaciones, 588 consulta gráfica mediante ejemplos, 150 consultas, 410 básica, 128 basada en conceptos, 639 concreta, 674 de los primeros K, 503 de proximidad, 760 de rango, 674 de vecino más próximo, 760 definición, 8 dependiente de la ubicación, 768 espacial, 760 monótona, 129 motor de ejecución, 444 optimización, 475, 686 basada en costes, 476 con tableau, 503 de actualizaciones, 503 de agregación, 502 de los primeros K, 503 de multiconsultas, 503 paramétrica, 502 semántica, 503 plan de ejecución, 444 plan de evaluación, 444 procesador, 22 procesamiento, 443 distribuido, 714 técnicas, 789 procesamiento distribuido, 769 recursiva, 128 regional, 760 sobre una relación, 144 sobre varias relaciones, 146 contador lógico, 540

www.detodoprogramacion.com

contaminación de los motores de búsqueda, 638 contenido de información, 618 contexto, 333 control de admisión, 766 control de concurrencia, 701 esquema, 543, 579 esquemas, 514, 522, 529 multiversión, 547, 793 optimista, 544 subsistema, 386 control de transacciones, 62 controlador de disco, 371 cookie, 266 coordinador de transacciones, 697 suplente, 713 copia en la sombra, 512 copia principal, 694, 705 copo de nieve, esquema, 614 CORBA, 747, 749 corrección fuerte, 797 correlaciones, 622 corresponden, 308 correspondencia de cardinalidades, 14, 177, 200 corte, 605 de cubos, 605 costes, 714 de inicio, 659 crawlers, véase batidores Web creación de imágenes, 375, 377 creador de mercado, 787 cross join, 94 Crystal Reports, 261 cuadrícula de diseño, 150 cuadro de condiciones, 147, 147 cubo, 125 cubos de datos, 604 cuellos de botella, 733 cuerpo, 153 cume_dist, 610 current_date, 102 current_time, 102 D'Hers, Thierry, 885 DAT (Digital Audio Tape), 383 Data Encryption Standard, 286 data mining, véase minería de datos Data Universal Numbering System, 747 data warehouses, véase almacenes de datos Database Task Group, 745 Datalog, 27, 137, 151, 162 programa, 153 recursividad, 158 reglas, 153 DataSet, 747 datos archivados, 368 CAD, 756 de difusión, 770 de medios continuos, 754, 765 espaciales, 753 fragmentados, 353


946

Índice

datos (cont.) geográficos, 753, 756, 758, 759 aplicaciones, 759 globales, 797 isócronos, 765 locales, 797 medios continuos, 766 multidimensionales, 603 multimedia, 754 formatos, 766 por líneas, 758 temporales, 251, 753 válidos, 251 vectoriales, 759 DB2 de IBM, 23, 59 DB2 Universal Database de IBM, 859 DBA, véase administrador de bases de datos DBC de Teradata, 680, 687 DBTG, véase Database Task Group DEC (Digital Equipment Corporation), 671 definición de tipos de documentos, 335 delete, 64, 887 depende de, 154 directamente de, 154 indirectamente de, 154 dependencias de compromiso, 539 de reunión, 248 de subconjuntos, 107 del valor, 798 existencial, 189 parcial, 255 que generan igualdades, 245 que generan tuplas, 245 transitivas, 230 dependencias funcionales, 14, 222, 225, 231 cumple, 225 implicada lógicamente, 232 temporales, 251, 755 triviales, 226 dependencias multivaloradas, 244-246 trivial, 245 DES, 286 desanidamiento, 311 desbordamiento de una tabla de asociación, 460 descomposiciones, 224 con pérdidas, 223, 237 que conservan las dependencias, 238 sin pérdidas, 223, 237 desconexiones, 770 descorrelación, 494 descripción, descubrimiento e integración universales, 357 desduplicación, 613 desnormalización, 250 desviación, 622 detección de fallos, 592 diagrama E-R, 180, 200 diagramas de esquema, 35 diccionarios de datos, 9, 393, 394, 837, 842

diferencia de conjuntos, operación, 39, 464 diferencial, 495 DigiCash, 788 Digital Subscriber Line, 667 dimension, 843 directorio, 643, 644 Directorio Activo, 290 discos ópticos, 382 compartido, 662 con imagen, 569 de registro histórico, 374 de vídeo digital, 368 digital versátil, 368 fallo, 567 magnéticos, 370 planificación, 373 salida forzada de bloques, 384 discriminante, 189 diseño conceptual, 12, 170 disparador, 273 disponibilidad, 710 elevada, 591, 710 dispositivo cabeza-disco, 370 distinct types, 102 distribución de datos, 376 en el nivel de bits, 376 en el nivel de bloques, 376 distribuidor, 907 dividir, 411 división, 558 cuadrática, 764 de la red, 701 estrategias, 674 horizontal, 674 operación, 46 por asociación, 681 por rangos, 681 recursiva, 460 sesgada, 460 sesgo, 676 DLT (Digital Linear Tape), 383 documentos sin estructurar, 632 DOM (Document Object Model), 265, 349 domain type, 103 domiciliación, 613 dominios, 29, 63, 140, 175 atómicos, 30, 302 drop trigger, 276 DSL, 667 DTD (Document Type Definition), 335 DUNS, 747 duplicación instantánea, 907 por mezcla, 907 transaccional, 907 durabilidad, 18, 508, 509, 512, 567 grados dos muy seguro, 593 dos seguro, 593 uno seguro, 593 DVD (Digital Video Disk), 368 EBCDIC, 717 ejecuciones no secuenciables, 792

www.detodoprogramacion.com

ejemplares, 6, 154 básico de una regla, 154 de la base de datos, 31 de la relación, 31, 173 ejemplos de formación, 616 elección, 711 elemento, 332, 656 eliminación de duplicados, 145 paralela, 684 elipses, 756 encauzamiento bajo demanda, 468 por los productores, 468 Encina, 777, 781 enfoque incremental, 749 entidad, 171 de procesamiento, 781 entornos distribuidos, 704 entradas, 720 de construcción, 459 de prueba, 459 envolturas, 718, 748 equipos asociados, 474 equirreunión, 452 equivalentes, 476 ERP, 785 error del sistema, 567 lógico, 567 es/son, 639 escribir, operación, 793 escrituras a ciegas, 520 externas observables, 511 espacio de intercambio, 583 espacio de nombres, 334 predeterminado, 334 espacios de tablas, 837 especialización, 190, 191, 308 parcial, 194 total, 194 esperar, 530 esperar--morir, 549 esqueletos de tablas, 144, 149 resultado, 149 esquemas único de relación, 149 de la base de datos, 31 de la relación, 31 definición, 6, 63 físico, 6 lógico, 6 estabilidad del cursor, 556 estaciones para el soporte de movilidad, 768 estadísticas y estimación del coste, 502 estado de ejecución, 468, 783 estados de terminación aceptables, 783 no aceptables, 783 inconsistente, 509 preparado, 699 estrategia de extracción inmediata, 385


Índice 947

estrategia (cont.) de gestión de la memoria intermedia, 385 de semirreunión, 716 de sustitución, 384 más recientemente utilizado, 385 estrella, esquema, 614 estructura de índice ordenado, 420 de páginas con ranuras, 389, 389 etiquetas, 329 evaluación correlacionada, 493 encauzada, 467 materializada, 467 evento-condición-acción, 274 evitación del desbordamiento, 461 except, 71 excepto, operación, 72 exceso de ajuste, 619 exclusión mutua, 655 expansión de vistas, 83, 156 exploración de la relación, 490, 674 del índice, 447, 490 sólo del índice, 490 explorador de archivo, 446 exposición de datos no comprometidos, 791 expresión de ruta, 341 expresiones de camino, 315 extensiones de clases, 319 extensiones persistentes, 323 extracción, 468, 614 extracción de información, sistemas, 642 factor de escape, 461 fallo durante una transferencia de datos, 569 en el sistema, 512 falso negativo, 640 falso positivo, 640 fantasma, fenómeno, 554, 559 fase de diseño físico, 12, 170 lógico, 12, 170 fases crecimiento, 533 decrecimiento, 533 deshacer, 587 escritura, 543 lectura, 543 rehacer, 587 validación, 543 fiabilidad, 375 Fibre Channel, 373 fila, 30 filas de ejemplo, 144 FireWire, 371 firmas digitales, 288 Flashback, 850 flujos de trabajo, 703, 783 definición, 781 ejecución, 782

especificación, 782, 783 insegura, 785 estado, 783 recuperación, 785 sistema gestor, 784 arquitectura centralizada, 784 arquitectura completamente distribuida, 784 arquitectura parcialmente distribuida, 784 FLWOR, 343 FNBC, véase forma normal, de BoyceCodd FNDC, véase forma normal, de dominios y claves foreign key, 107 forma normal, 219 cuarta, 244, 246 de Boyce-Codd, 226 de dominios y claves, 248 de reunión por proyección, 248 primera, 224, 302 quinta, 248 segunda, 229, 248, 255 tercera, 229 algoritmo de síntesis, 242 Forms de Oracle, 260 Fortran, 62, 112 FoxPro, 59 fragmentación de los datos, 695 horizontal, 695, 695 vertical, 695, 695 fragmentos y réplicas, 681, 683 frecuencia del término, 633 frecuencia inversa de los documentos, 633 from, 67, 311 función de asociación, 421 funciones constructoras, 306 de agregación no-descomponibles, 607 de tabla, 121 fusión, 558 fusionar, 411 ganancia de información, 618 ganancia de velocidad, 658 lineal, 658 sublineal, 658 generación impaciente de tuplas, 468 generación interactiva de índices, 688 generalización, 191, 308 de solapamiento, 194 parcial, 194 sobre la condición de disjunción, 194 total, 194 gestor de bloqueos, véase bloqueos, gestor de colas, 780 de control de concurrencia, 18 de la memoria intermedia, 384 de recursos, 780 de transacciones, 697

www.detodoprogramacion.com

getConnection, 117 Global Trade Item Number, 747 GNU, 808 Google, 357 google.com, 266 GPS (Global Positioning System), 759 GQBE, 150 grafo de autorización, 280 de espera, 551 de la base de datos, 538 de precedencia, 522, 525 dirigido acíclico, 538 global de espera, 709 local de espera, 708 gran explosión, enfoque, 749 grant, 111, 280 granularidad, 544 múltiple, 544 Graphical Query-By-Example (GQBE), 150 Grupo de administración de objetos, 747 Grupo de gestión de bases de datos de objetos, 747 grupos, 50 GTIN, 747 guiones en el lado del servidor, 270 hebra, 654 hecho, 153 herencia única, 193 de los atributos, 193 múltiple, 193, 307 herir-esperar, 549 heurísticas, 502 Himalaya de Compaq, 687 Hinson, Gerald, 885 hipercubo, 660 hipervínculos, 262 histograma, 483, 676 de equianchura, 483 de equiprofundidad, 483 hojas de estilo, 264, 347 en cascada, 264 homónimos, 638 hora universal coordinada, 755 HP-UX, 859 HTML (Hyper-Text Markup Language), 329 HTML-DB, 260 HTTP (Hyper-Text Transfer Protocol), 263, 748 HTTPS (Hyper-Text Transfer Protocol Secure), 289 IDE (Integrated Drive Electronics), 371 idempotente, 574 identificador del elemento de datos, 572 identificadores lógicos de fila, 839 IDF (Inverse Document Frequency), 633 IDL (Interface Description Language), 747 id_tupla, 695


948

Índice

IEEE (Institute of Electrical and Electronics Engineers), 745 inanición, 533, 550, 552 inconsistencia de los datos, 3 incrementar, 563 independencia de recuperación, 591 física respecto de los datos, 6 indexación ordenada esquemas, 431 índices, 401 árbol B, 417 algoritmo de control de concurrencia, 585 enlazados, 558 árbol B+, 408, 415, 431, 561 borrado, 411 inserción, 411 redistribuir, 412 árbol R, 420 asociativo, 401, 421, 425 construcción, 459 prueba, 459 compuesto, 449 con agrupación, 402 construcción ascendente, 439 datos espaciales, 761 de cobertura, 420 de función, 352 de ganancia de información, 618 de proyección, 441 denso, 403 disperso, 403 documentos, 639 entrada, 403 espacio adicional requerido, 402 GiST, 816, 824, 826 invertido, 639 mapas de bits, 433 de existencia, 434 intersección, 433 multinivel, 405 ordenado, 401 por capas de bits, 441 primario, 402 secuencial, 408, 414, 431 secundario, 402 selección, 498 sin agrupación, 402 tiempo de acceso, 402 de borrado, 402 de inserción, 402 tipos de acceso, 402 inferir, 155 informática móvil, 768 información geométrica, 756 informar, 743 informes de invalidación, 771 Informix, 59 ingeniería inversa, 748 Ingres, 23, 59, 807 inicio de sesión único, 289 inserción, 55, 85, 468 inserción y borrado, 558

insert, 64, 887 insertar, 553 instantáneas, 251, 854 actualizable, 854 sólo de lectura, 854 instrucciones atómicas, 655 int, 102 integridad, 61 referencial, 107 interactivamente, 688 interbloqueos, 532, 546, 548, 565 detección, 549, 551, 708 centralizada, 709 prevención, 549, 708 recuperación, 549, 552 intercambio de operadores, 687 intercambio en caliente, 381 interfaz de nivel de llamada, 746 de pasarela común, 265 del gestor de recursos, 780 para programas de aplicación, 115 interferencia, 659, 742 Internet, 667 intersección, operación, 44, 72, 464 intersect, 71 interval, 755 Inverse Document Frequency (IDF), 633 IPv4, 812 IPv6, 812 ISO (International Organization for Standardization), 61, 720, 745 iterador, 468, 829 J2EE (Java 2 Enterprise Edition), 270, 834 Jakobsson, Hakan, 833 Java, 11, 62, 112, 265, 507 Java Database Objects (JDO), 321 Java Server Pages, 270 Javascript, 265 JDBC (Java Database Connectivity), 11, 62, 104, 115, 117, 265, 316, 347, 653, 835 JDeveloper, 834 JDO, 321 jerarquías, 127, 193, 605 de clasificación, 643 JPEG (Joint Picture Experts Group), 766 JScript, 270, 747 JSP (Java Server Pages), 260 jukebox, 368, 382 Kerberos, 289 Krishnamurthy, Sailesh, 807 límite de tiempo, 550 línea de suscriptor digital, 667 LAN, 666 LDAP (Lightweight Directory Access Protocol), 719, 720 LDAP Data Interchange Format, 721 LDD, véase lenguajes, de definición de datos LDIF, 721 Least Recently Used, 384, 385 leer, 508

www.detodoprogramacion.com

leer uno, escribir todos, 712 leer uno, escribir todos los disponibles, 712 leer, operación, 793 lenguajes de almacenamiento y definición de datos, 8 de consultas, 8, 35 incorporado, 316 no procedimental, 137 temporales, 755 de definición de datos, 7, 8, 61, 62 de descripción de interfaces, 747 de guiones, 265 del lado del cliente, 265 de manipulación de datos, 7, 61 de marcas, 329 de ColdFusion, 270 de hipertexto, 329 extensible, 7, 329 inalámbrico, 769 de marcas de hipertexto, 262 de modelado unificado, 210 de programación persistentes, 301, 316, 322 estándar generalizado de marcas, 329 no procedimentales, 36 procedimentales, 35 limpieza de los datos, 613 línea poligonal, 756 quebrada, 756 Linux, 807, 859 lista libre, 388 lista-deshacer, 580 lista-rehacer, 580 literal negativo, 153 positivo, 153 little-endian, 718 llamada a procedimientos remotos, 781 LMD, véase lenguajes, de manipulación de datos Loader, 855 Local Area Network, 666 localtime, 102 lógica de negocio, 21 Lotus Notes, 668 LRU, 385 MAC (Media Access Control), 812 Macromedia Flash, 265 Macromedia Shockwave, 265 malla, 660 manejadores, 124 máquina paralela grano fino, 653, 657 grano grueso, 657 masivamente paralela, 657 marca, 329 marca-temporal-E, 540, 564 marca-temporal-L, 540 marcas temporales esquema multiversión, 547 materializa, 466


Índice 949

media armónica, 742 mediadora, aplicación, 358 mediadores, sistemas, 718 medidas de Gini, 617 de la entropía, 617 mejor partición, 618 memoria compartida, 661, 661 flash, 367 intermedia, 384 de disco, 570 de escritura no volátil, 374 doble, 467 forzar la salida, 571 no volátil de acceso aleatorio, 374 principal, 367 virtual, 582 distribuida, 662 menos recientemente utilizado, 384 mensajería persistente, 665 implementación, 703 mensajes persistentes, 702 merge, 131 metadatos, 9 métodos, 305 métrica compuesta consultas por hora, 744 precio/rendimiento, 744 mezcla de N vías, 450 mezcla-purga, operación, 613 microcomputadora, 767 minería de datos, 18, 602, 615 minería de texto, 624 modelo de árbol, 340 de alambres, 758 de datos de red, 7 definición, 6 entidad-relación, 13, 171 jerárquico, 7 orientado a objetos, 15 relacional, 29, 673 relacional orientado a objetos, 16 de espacio vectorial, 634 de objetos componentes, 908 de objetos documento, 265, 349 de proceso por cliente, 777 de recorrido aleatorio, 636 de servidor único, 778 de simulación del rendimiento, 741 de varios servidores y un solo encaminador, 779 de varios servidores y varios encaminadores, 779 modificaciones no comprometidas, 575 módulo de almacenamiento persistente, 122 momento de la transacción, 251 monótona, 161 monitores de procesamiento de transacciones, 777 Most Recently Used, 385 MP3, 766

MPEG (Moving Picture Experts Group), 766 multiconjuntos, 49, 309 multienhebramiento, 778 multiprogramación, 514 multitarea, 778 MVS, 859 Myers, Dirk, 885 número de secuencia del registro histórico (NSR), 588, 589 NAS (Network Attached Storage), 372 Netscape, 270 NetWare, 778 NFS (Network File System), 372 niveles de consistencia compromiso de lectura, 557 lectura repetible, 557 secuenciable, 556 sin compromiso de lectura, 557 nodos, 340, 637, 663 nombre distinguido, 720 relativo, 720 normas, 744 801.11, 769 802.16, 769 anticipativas, 744 de cifrado avanzado, 286 de cifrado de datos, 286 de facto, 744 formales, 744 JDBC, 117, 745 ODBC, 745, 746 reaccionarias, 744 SQL, 435 opcionales, 890 X/Open Distributed Transaction Processing, 780 notificación, 273 Novell, 778 NSRPágina, 589 nulos, 15, 31, 176 NUMA (Nonuniform Memory Architecture), 663 numeración de versiones, 771 NVRAM (Nonvolatile Random-Access Memory), véase memoria, no volátil de acceso aleatorio ObjectStore, 319 objeto hueco, 322 Objetos de bases de datos de Java (JDO), 321 ODBC (Open Database Connectivity), 11, 62, 115, 265, 316, 653, 904 ODMG (Object Database Management Group), 319, 320, 747 OLE-DB, 746, 899 OMA (Object Management Architecture), 747 OMG (Object Management Group), 747 Online Analytical Processing, 742 Online Transaction Processing, 742 ontologías, 639 OO1, 744

www.detodoprogramacion.com

OO7, 744 Open Directory Project, 645 operaciones coste de la evaluación paralela, 684 deshacer, 575, 576 física, 585 lógica, 585 entrada, 570 escribir, 571 lógicas, 585 leer, 571 rehacer, 574, 576 fisiológicas, 588 relacionales, 157 salida, 570 operadores relacionales, 70 optimización de consultas, 445, 475 global, 718 heurística, 491 optimizadores basados en el coste, 488 Oracle, 2, 23, 59, 121, 285, 327, 352, 399, 492, 597, 603, 678, 740, 789, 833 ORB (Object Request Broker), 747 orden de secuencialidad, 523 interesante, 490 lexicográfico, 419 más significativo, 718 menos significativo, 718 ordenación con división por rangos, 679 externa, 450 paralela, 679 por marcas temporales, 540 topológica, 523 ordenación y mezcla externas paralelas, 679 ordenación-mezcla externa, 450 order by, 70 organización de archivos en agrupaciones de varias tablas, 390, 392 OS X, 807 OS/400, 859 páginas amarillas, 719 páginas blancas, 719 páginas Web activas, 264 Padmanabhan, Sriram, 859 PageRank, 636 paginación en la sombra, 796 palabras clave, 631 palabras de parada, 633 Papadimitriou, Spiros, 807 parámetros ajustables, 735 paralelismo de datos, 679 de encauzamiento, 685 de grano grueso, 652 en consultas, 678 en operaciones, 678, 679 entre consultas, 677 entre operaciones, 678, 685 independiente, 686


950

Índice

paridad distribuida con bloques entrelazados, 379 parte-de, 639 particiones, 698 binarias, 618 múltiples, 618 participación, 173 parcial y total, 179 Pascal, 62, 112 pasos, 781 PATA (Parallel ATA), 371, 373 patrones descriptivos, 615 perezosa, generación, 468 periodo de validez, 251 Perl, 270, 807, 809, 817 persistencia de los objetos, 317 pertenencia a conjuntos, 76 definida por el atributo, 193 definida por el usuario, 193 definida por la condición, 193 pestillos, 583 petabyte, 369 PHP, 270, 809 Pirzada, Vaqar, 885 pistas, 370 pivotaje, 605 PL/I, 62, 112 planes sólo de índices, 502 planificaciones, 514 consultas paralelas, 686 equivalente en cuanto a conflictos, 518 en cuanto a vistas, 520 legal, 533 recuperable, 521, 521 secuenciable en cuanto a conflictos, 519 en cuanto a vistas, 520 secuencial, 514 sin cascada, 521, 521 plantillas, 347 plato, 370 población, 621 polígonos, 756 posee, 189 PostgreSQL, 807 postmaster, 830 PowerBuilder de Sybase, 260 precede, 533 precisión, 640 predicción, 615 preextracción, 656 prefs, 266 preparada, 665 primitivas de evaluación, 444 privilegios, 111 concesión, 279 execute, 279 references, 279 de SQL, 281 usage, 279 problema de Halloween, 504 procesadores local, 677

virtual, 676 procesamiento en conexión analítico, 742 de transacciones, 742 proceso escritor de bases de datos, 654 escritor del registro, 655 gestor de bloqueos, 654 monitor de procesos, 655 punto de revisión, 655 servidor, 654 proceso de entrega de mensajes, 703 productividad, 513, 657, 742 producto cartesiano, 30, 36, 39 programas de aplicación, 11 Prolog, 137, 151, 162 propagación perezosa, 708 protocolos basados en grafos, 792 basados en marcas temporales, 792 de acceso a directorios, 719 de acceso a directorios X.500, 720 de aplicaciones inalámbrico, 769 de bloqueo, 704 de compromiso, 698, 699 de dos fases, 665, 698, 699 de tres fases, 698, 701 en grupo, 789, 790 de control de concurrencia, 677 de mayoría, 705 de ordenación por marcas temporales, 540 de transferencia de hipertexto, 265 de validación, 792 globales-lectura, 798 globales-lectura-escritura/localeslectura, 798 ligero de acceso a directorios, 719, 720 locales-lectura, 798 sesgado, 706 simple de acceso a objetos, 357, 748 proximidad, 634 proyección, 37 generalizada, 48 paralela, 684 temporal, 755 proyecto de directorio abierto, 645 pruebas de rendimiento, 741 familias de tareas, 741 OLAP, 742 OLTP, 742 OODB, 744 TPC, 742 PSM (Persistent Storage Module), 122 public, 111, 281 publicador, 906 puntero persistente, 318 punto de bloqueo, 534 punto fijo, 129, 159 PuntoFijo-Datalog, 159 puntos de almacenamiento, 591 puntos de revisión, 578, 580, 586 difuso, 580, 588 Python, 270

www.detodoprogramacion.com

QBE, 27 QBE (Query-By-Example), 137, 144, 162 QMF (Query Management Facility), 165 quórum de escritura, 706 de lectura, 706 R, árbol, véase índices, árbol R réplica, 885 completa, 694 de actualización distribuida, 708 de datos, 694 maestro-esclavo, 707 multimaestro, 708 raíz, 332 RAID, 569, 767 RAID (Redundant Array of Independent Disks paridad con bits entrelazados, 378 paridad con bloques enrelazados, 379 RAID (Redundant Array of Independent Disks), 375 Ramos, Bill, 885 Rathakrishnan, Balaji, 885 Rdb de DEC, 23 Rdb de Oracle, 678 REA, 582 RealAudio, 766 realimentación de la relevancia, 634 reasignación de los sectores dañados, 371 recall, 640 rechazo falso, 640 recubrimiento canónico, 235, 235 recuperabilidad, 520, 770, 791 de elementos de datos de gran tamaño, 795 recuperación, 571, 579, 701 a un instante, 596 al reiniciar, 580, 587 basada en el registro histórico, 572 basada en la semejanza, 767 esquema, 567, 581 optimizaciones, 591 subsistema, 386 recuperación (recall), 640 recuperación de fallos, 18 algoritmo, 789 recuperación de información, 631 basada en la semejanza, 634 recursividad, 160 estructural, 348 recursos para presentaciones, 780 redes, 767 de área amplia, 666, 667 de área de almacenamiento, 371, 667 de área local, 666 de interconexión, 659 redundancia, 3, 375 P+Q, 380 referencia, 723 referencias cruzadas, 251 registro de escritura anticipada (REA), 582 registro histórico, 572, 796 con memoria intermedia, 581


Índice 951

registro histórico (cont.) de operaciones, 795 físico, 585 registros, 585 forzar, 582 lógico, 585, 795 registro de actualización, 572 registro punto de revisión, 589 registros de compensación, 586, 589 registros, 572 índice, 403 reglas, 19, 151, 153, 615 aumentatividad, 232 de equivalencia, 477 conjunto mínimo, 480 de escritura de Thomas, 542 de los cinco minutos, 736 del minuto, 736 descomposición, 233 pseudotransitividad, 233 reflexividad, 232 transitividad, 232 unión, 233 regresión, 620 lineal, 620 reingeniería, 749 relaciones, 13, 30, 173 bitemporales, 754 derivadas, 80 desnormalizada, 737 externa, 452 identificadora, 189 instantáneas, 755 interna, 452 referenciada, 35 referenciante, 35 temporales, 754 uno a uno, 177 uno a varios, 177 varios a uno, 177 varios a varios, 177 relevancia, 633 relevo, 768 en caliente, 592 reloj del sistema, 540 lógico, 707 rendimiento, 791 de la reconstrucción, 380 renombramiento, operación, 41, 68 repetición de la historia, 587 replicados, 664 representación relacional agregación, 206 atributos compuestos, 204 combinación de esquemas, 204 conjuntos de entidades débiles, 202 conjuntos de entidades fuertes, 201 conjuntos de relaciones, 202 generalización, 205 redundancia, 203 repudio, 288 requisitos funcionales especificación, 12, 170

resolución del desbordamiento, 461 respuesta a las preguntas, 643 respuesta por desafío, 288 restricciones, 238, 247 de completitud, 194 de consistencia, 3, 8 de definición por condición, 195 de integridad, 105 referencial, 107 legales, 225 resultados, 783 retículo, 193 retroceso, 552 en cascada, 534 parcial, 552 total, 552 reunión, 45 con bucles anidados en paralelo, 683 con fragmentos y réplicas, 681, 682 asimétricos, 681 cruzada, 94 de banda, 689 de unión, 94 en bucle anidado, 452 indexada, 455 por bloques, 454 encauzada, 469 espacial, 760 externa, 51 completa, 53, 93 por la derecha, 52, 93 por la izquierda, 52, 93 minimización, 503 natural, 45, 92 operaciones, 92 orden en profundidad por la izquierda, 491 paralela algoritmos, 680 por asociación, 459 híbrida, 462 por asociación dividida en paralelo, 683 por división, 680, 680 por mezcla, 455 por ordenación-mezcla, 455 temporal, 755 zeta, 46 revoke, 111, 282 REXX, 863 robustez, 710 rol entidad, 173 RosettaNet, 356 RPC (Remote Procedure Call), 781 transaccionales, 781 Rys, Michael, 885 saga, 794 SAN (Storage Area Network), 667 SATA (Serial ATA), 371, 373 satisface, 155, 225 SAX (Simple API for XML), 350 Schroeder, Bianca, 807

www.detodoprogramacion.com

SCSI (Small Computer System Interconnect), 371 sectores, 370 secuencialidad, 516 de dos niveles, 797 en cuanto a conflictos, 517 asegurar, 533 en cuanto a vistas, 517 propiedad, 529 protocolos basados en el bloqueo, 529 basados en grafos, 537 secuencias, 450 secuencias de ejecución, 514 segmento rectilíneo, 756 seguridad, 157 selección, 36, 347 conjuntiva, 448 de reemplazamiento, 473 disyuntiva, 448 paralela, 684 temporal, 755 select, 65, 66, 313, 887, 891 selectividad, 484 semántica programa, 155, 156 reglas, 154 semejanza del coseno, 634 Sequel, 61 Server-Side Javascript, 270 servicio Web, 357 servidores, 20 de aplicaciones, 21 de nombres, 696 Web, 265, 779 servlet, 267 sesgo, 659, 681, 688 de ejecución, 675, 680 de los valores de los atributos, 676 en una relación, 675 SET (Secure Electronic Transaction), 788 SGBD, 1 SGML (Standard Generalized Markup Language), 329 showplan, 887 SIGMOD, conferencia de la ACM, 807 sin compartimiento, 662 sin conexión, 266 sinónimos, 638 sintaxis bidimensional, 144 sistema dividido, 698 sistema de archivos, 386 sistema de bases de datos múltiples, 717 sistema de posicionamiento global, 759 sistema de procesamiento de archivos, 3 sistema gestor de bases de datos, 1 sistemas clientes, 653 de archivos de diario, 374 de colas, 734


952

Índice

sistemas (cont.) de discos compartidos, 667 de diseño asistido por computadora, 757 de gestión de flujos de trabajo, 665 de información geográfica, 756 de planificación de los recursos de las empresas, 785 de tiempo real, 790 heredados, 748 monousuario, 652 multiusuario, 652 paralelos, 657 persistentes de C++, 319 relacionales, 323 remotos de copia de seguridad, 595 servidores, 653 de consultas, 654 de datos, 654, 656 de transacciones, 654 sistemas de bases de datos cliente-servidor, 651 distribuidos, 651, 663, 693 distribuidos y heterogéneos, 664 múltiples, 664, 796 paralelos, 651, 673 sitio, 663 principal, 591, 705 remoto de copia de seguridad, 591 secundario, 591 smallint, 102 SOAP, 357 SOAP (Simple Object Access Protocol), 748 sobrecarga, 319 software envolvente, 358 Solaris, 859 soporte, 621 span, 755 SQL, 61, 323, 507 dinámico, 62 dominios char, 63 double precision, 63 float, 63 int, 63 numeric, 63 real, 63 smallint, 63 varchar, 63 incorporado, 62, 112 SQL Server de Microsoft, 59 SQL-92, 62 Standard Generalized Markup Language, 329 Storage Area Network, 371 subárboles disjuntos, 538 subastas, 787 inversas, 787 subclase, 192 subconsultas, 78 escalares, 130 subesquemas, 6 subexpresiones comunes, 503 subtabla, 308

subtareas, 791 sufijo, 722 sumas de comprobación, 371 Sun Microsystems, 321, 745 superclase, 192 superclase-subclase, 191 superclave, 34, 178, 225 superusuario, 279 supuesto de fallo-parada, 567 suscriptores, 907 sustitución de bloques utilizados menos recientemente, 385 Sybase, 59 synset, 639 System R, 23, 59, 61, 474, 491, 527, 597, 828, 859 término, 632 tabla de páginas desfasadas, 588 TablaPáginasDesfasadas, 589 tablas, 29, 30 de dimensiones, 614 de hechos, 614 dinámica, 603 tabulación cruzada, 603 tag library, 271 tarea, 781 tarjetas inteligentes, 288 Tcl, 808 teléfonos móviles, 184, 768 teoría de colas, 735 terabyte, 369 Teradata, 687 Term Frequency (TF), 633 terminales, 767 test de potencia, 744 de productividad, 744 texto completo, 632 TF (Term Frequency), 633 Thomas, véase reglas, de escritura de Thomas tiempo de acceso, 372 de búsqueda, 372 medio, 372 de compromiso, 592 de latencia medio, 372 de latencia rotacional, 372 de recuperación, 592 de respuesta, 657 de servicio, 741 de transacción, 754 en SQL, 754 límite estricto, 790 firme, 790 flexible, 790 medio de reparación, 376 de respuesta, 514 entre fallos, 372 entre pérdidas de datos, 376 para concluir, 742 válido, 754

www.detodoprogramacion.com

tiempo límite, 790 tipos de datos coerción, 102 compatibles, 102 de conjunto, 318 de fila, 305 definidos por el usuario, 304 estructurados, 102 más concreto, 307 tipos de dominios, 63, 103 Tk, 808 tolerancia ante fallos, 662 Top End, 777 TP, 777 TPS (transacciones por segundo), 743 transacciones, 90, 777 abortada, 510 activa, 510 anidada, 794 cancelar, 511 compensadora, 510, 794 comprometida, 510 concurrentes, 579 de actualización, 548 de corta duración, 792 de sólo lectura, 548 definición, 18, 507, 507 distribuida, 697 dudosas, 701 ejecución concurrente, 513 secuencial, 513 electrónica segura, 788 fallida, 510 fallo, 567 flujo de tareas, 781 flujo de trabajo, 781 global, 663, 697, 796 instantánea consistente, 707 interactiva compleja, 795 de larga duración, 799 larga duración, 791 llamada a procedimientos remotos, 653 local, 663, 697, 796 múltiples, 513 modificación diferida, 573 inmediata, 575 multinivel, 794 parcialmente comprometida, 510 procesadas por minilotes, 741 reiniciar, 511 retrocedida, 510 retroceso, 579, 585 en cascada, 521 terminada, 510 Transaction Processing Performance Council, 742 transferencia de prestigio, 636 del control, 592 transformación, 614 transformar, 613


Índice 953

transparencia de la fragmentación, 696 de la réplica, 696 de la ubicación, 696 de los datos, 696 traza de auditoría, 285 triangulación, 756 tries, 440 triviales, 226 tupla, 30 Turing máquina universal, 11 premio, 23 Tuxedo, 777 UDDI, 357 Ultrium, 383 UML (Unified Modeling Language), 210 union, 71 unión, 38, 71, 464 union join, 94 unique, 106 Universel Temps Coordoné, 755 Unix, 807, 859 update, 111, 887 upsert, 834 URL (Uniform Resource Locator), 263 USB (Universal Serial Bus), 368, 371 UTC, 755 utilización, 513 valores anterior, 572 continuos, 618 nuevo, 572

variables de correlación, 493 externas, 783 tupla, 30, 68 varrays, 835 VBScript, 270, 747 vector de división, 674 por rangos equilibrado, 676 vector de versiones, 771 velocidad de transferencia de datos, 372 ventana, 611 versiones, 547 multiconjunto, 70 vídeo servidor, 767 Virtual Private Database, 284 vistas, 81, 82, 155, 283 actualizables, 89 definición, 61, 82 materializadas, 83, 494, 503 mantenimiento, 83, 495, 613 mantenimiento diferido, 495, 738 mantenimiento incremental, 495 mantenimiento inmediato, 495, 738 selección, 498 no recursiva, 154 paramétricas, 122 recursiva, 83, 154 Visual Basic, 115, 779, 905 Visual C++, 260 visualización de datos, 624 VM, 859 volcado de archivo, 584 difuso, 585 volcar, 584

www.detodoprogramacion.com

VPD, 284 VRML (Virtual Reality Markup Language), 265 Waas, Florian, 885 WAN, 667 WAP (Wireless Application Protocol), 769 Web, 262 WebSphere, 270 where, 66, 84 Wide Area Networks, 667 Windows, 859 2000, 859 XP, 859 with, 80, 94, 134 WML (Wireless Markup Language), 769 World Wide Web, 262 WSDL, Web Services Descripción Language, 357 XML (Extensible Markup Language), 329 datos relacionales publicados, 353 XPath, 340, 341 XPS de Informix, 687 XQJ, 347 XQuery, 340, 343 XSLT (XSL Transformations), 340 XSLT (XSLT Transformations), 347, 347 keys, 348 Yahoo, 623, 645 z/OS, 859 Zope, 270 Zwilling, Michael, 885


Juegos, Revistas, Cursos, Software, Sistemas Operativos, Antivirus y más … Gratis para el Conocimiento...! www.detodoprogramas.com Visítanos y compruébalo

Material para los amantes de la Programación Java, C/C++/C#,Visual.Net, SQL, Python, Javascript, Oracle, Algoritmos, CSS, Desarrollo Web, Joomla, jquery, Ajax y Mucho Mas… www.detodoprogramacion.com Visitanos

Libros Universitarios, Contabilidad, Matemáticas, obras literarias, Administración, ingeniería y mas…


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.