btree - Universidad Austral

Anuncio
Ф Indice
2. Introducción
3. Operaciones sobre una base de datos
3. Multiway-Tree
5. B-TREE
8. B+-TREE
9. Los algoritmos
a. Búsqueda
b. Inserción
c. Eliminación
12.Costos de los algoritmos
14.B*-TREE
15.Bibliografía consultada
1
Ф Introducción
Todos sabemos que una de las aplicaciones más importantes de las computadoras es
la de guardar y manipular información, en especial, grandes cantidades de
información. La manipulación de estos datos consiste en la inserción, lectura,
modificación y borrado de los mismos. Los datos se guardan en la memoria
secundaria de la máquina (el disco) y para poder llevar a cabo estos procesos, la
información debe ser recuperada y llevada a la memoria principal (la RAM) para que
el procesador pueda acceder a ella.
Luego, para asegurar que el proceso de manipulación será veloz, es necesario
organizar correctamente los datos.
Normalmente los datos se guardan en una Base de Datos. Se define a ésta como
una colección de datos relacionados entre sí.
Las bases de datos guardan en sus tablas registros, los cuales contienen información
clasificada en campos. Por ejemplo en una tabla de alumnos de la facultad, cada
registro le corresponderá a un alumno, y dentro de éste se guardarán los datos:
nombre, apellido, legajo, año, etc... Éstos son los campos. Una universidad guarda
datos sobre miles de alumnos, luego si no organizamos esta información será muy
difícil encontrar un registro en particular. Cuanto más rápida sea la base de datos,
más rápido realizará la computadora la manipulación de la información y por lo tanto
más tiempo tendrá para llevar a cabo otras operaciones.
¿Qué significa organizar la información?
Organizar los datos es ordenarlos de la manera más útil, haciendo fácil y eficiente su
manipulación. Si tuviésemos que organizar, volviendo al mismo ejemplo, una
colección de registros de alumnos, podríamos por ejemplo colocar los registros en
carpetas con las iniciales de los apellidos de éstos, o sea, ordenarlos por orden
alfabético. En este caso tendríamos carpetas de la A a la Z y sería más fácil
encontrar un alumno que si estuviesen todos los registros apilados en un solo cajón.
Pero tambíen podríamos organizarlo de otra forma: ahora que están así, colocar las
carpetas en cajones. Un cajón que tenga las carpetas de la A a la F, otro con las
carpetas de la G a la N, de la O a la T y un último de la U a la Z. Ahora es más
rápido buscar una carpeta que antes, y luego más veloz el acceso a un dato de algún
alumno.
Veamos: hemos creado con esto un índice (INDEX), lo que nos ha servido para
organizar la información. Pero qué ocurre si nos ponemos a pensar, que una
facultad tiene muchos años en su carrera, luego muchísimos registros de alumnos
para guardar, y además, una universidad tiene muchas facultades. Podríamos
entonces tener varios muebles con cajones, un mueble para cada año. Luego
podríamos también agregar un nuevo nivel de indexación, teniendo un conjunto de
muebles o archivos para cada facultad.
En la computadora
Este caso es concreto en la realidad. ¿Qué ocurre cuando diseñamos una base de
datos para guardar la información en la computadora?
Inicialmente hay que definir a cada registro de un conjunto de n registros como un ri
al cual le corresponderá una clave(key) identificadora única ki . Al conjunto de datos
asociados a un registro se lo definirá como ai.
Recordemos que la información está guardada en la memoria secundaria y debe ser
recuperada. Como la colección de datos es muy grande (en la mayoría de los
2
casos), será necesario un index file o archivo índice que funcione en paralelo con el
archivo de datos para hacer más veloz la manipulación de este último.
En el data file tendremos registros de la forma:
ai = <valores de los campos del registro>
Mientras que en el index file los registros de índice serán de la forma:
ki = <ri , ai>
Siendo ai una referencia al registro de datos que se encuentra en el data file.
Habrá que tener en cuenta ciertas consideraciones:
 Para que funcione bien el proceso de recuperación de datos es necesaria una
clave identificadora para cada registro.
 Es necesario que las claves tengan un orden natural entre sí, esto es
importante a la hora de querer acceder secuencialmente a la colección de
datos.
 El tamaño de los registros de índice es mucho menor (casi siempre) que el
tamaño de un registro de datos, por eso se trabaja velozmente organizando
los registros del archivo índice. Sería una locura ponerse a manipular
directamente el archivo de datos, dado el gran tamaño que tiene cada uno de
los registros.
Ф Operaciones sobre una base de datos
Las operaciones básicas que se pueden realizar sobre una base de datos son:
 Inserción (alta)
 Eliminación (baja)
 Búsqueda
 Next (siguiente)  Acceso Secuencial
Todas éstas tienen un costo de operación relativo a cómo tengamos organizados los
datos. Un buen index file asegura la eficiencia de estas operaciones. Si nos
ponemos a pensar en la velocidad de nuestro procesador, estas operaciones llevadas
a cabo sobre un índice en memoria no tienen un costo relativamente alto, son
bastante veloces, pero...
A pesar de que manejaremos los registros a partir de su índice, estos pueden ser
muy grandes debido a la gran cantidad de registros guardados, y luego no entrarán
en la memoria principal. Deberán trabajarse entonces desde disco.
Al tener algoritmos que se manejan con acceso a disco, todo lo que sea
procesamiento en memoria tiene un coste despreciable, ya que el acceso a disco es
millones de veces más lento que el trabajo en memoria. Pensemos que con un
procesador de 1000 MHz, un ciclo de su reloj (los ciclos máquina son de algunos
ciclos de reloj y cada operación básica tarda un cierto número de ciclo de máquina)
es de 1 nano segundo. Comparando con la velocidad de un acceso a disco, ésta es
del orden de los milisegundos. Es notable por qué se desprecia el trabajo del
procesador sobre la memoria RAM en comparación con el acceso a disco.
Ф Multiway Tree
Planteémonos sabiendo cuáles son ahora nuestras necesidades, el diseño de una
estructura de datos acorde. Imaginemos qué pasaría si utilizáramos una lista
ordenada para esto. La búsqueda es secuencial, a lo sumo puede lograrse una
búsqueda binaria, pero para cada comparación se realizaría un acceso a disco. No
tiene mucho sentido que digamos...
3
Pensemos ahora en algo más avanzado: un BST o árbol de búsqueda binario. O
mejor, un AVL. Supongamos que pudiésemos implementar esta estructura en disco.
El AVL nos asegura que todos los algoritmos serán de orden logarítmico. Pero
pensemos en un árbol AVL concreto.
Supongamos que las claves de los registros son números enteros. Si quisiéramos
buscar un registro cuya clave es el 315, siendo el árbol mostrado el index file,
deberíamos hacer 4 accesos a disco. Imaginemos ahora que tenemos una base de
datos, con una gran cantidad de registros, tal vez miles. La cantidad de accesos a
disco para una búsqueda sería muy grande y luego la búsqueda terriblemente lenta.
Definitivamente esta estructura no es la adecuada para lo que necesitamos.
Aquí aparece la necesidad de implementar el concepto abstracto introducido
anteriormente. El ejemplo de la universidad es un tipo de index que se conoce como
Multilevel Index o índice multinivel, en el cual se hacen agrupaciones de los registros
por niveles, un nivel es el índice del nivel que tiene más abajo, hasta llegar al último
que tiene el acceso al data file. La traducción de un índice multinivel a la informática
es un Multiway-Tree. Éste es un árbol M-Ario, o sea, cada nodo tiene como máximo
M hijos.
Veamos un multilevel index (VER FIGURA), en particular, uno de 2 niveles. En éste
los registros del índice o index entry del 2º nivel tienen claves para la búsqueda y
punteros a los entry del primer nivel. Los registros del primer nivel tienen las claves
identificadoras y los punteros correspondientes a los registros en el data file. Pero
veamos que un index entry es un nodo que contiene más de una clave, en este caso
en particular, contiene 4 claves y 4 punteros. Supongamos que queremos buscar el
registro de clave 71. Entonces levantamos a memoria el index entry del 2º nivel.
Recordemos que la búsqueda en memoria sobre este registro es despreciable. Se
busca y vemos que el valor 71 está entre el 55 y el 85, luego nos guiamos por el
puntero correspondiente a levantar a memoria el index entry respectivo del 1º nivel.
Aquí buscamos el 71 y el puntero correspondiente nos llevará directo al bloques de
registros en el data file donde se encuentra el registro buscado.
Veamos que hicimos una búsqueda con 2 accesos a disco en una base de 26
registros. Imagine la posibilidad de disminución de accesos en comparación con un
4
árbol binario. (Notar que al llegar al bloque deberá hacerse una búsqueda secuencial
para encontrar el registro, luego en realidad serán 3 accesos para hallarlo).
El árbol M-Ario es la implementación de un registro multilevel, y evoluciona a lo que
llamamos B-TREE.
Multilevel Index de 2 niveles
Ф B-TREE
En 1970 R. Bayer y E. McCreight descubrieron un tipo de M-Way Tree al que
llamaron B-Tree, el cual logra actualizar y buscar sobre un archivo grande con
“buena” eficiencia garantizada y utilizando algoritmos relativamente sencillos.
El B-Tree de orden m satisface las siguientes condiciones:
i)
Todo nodo tiene como máximo m hijos
ii)
Todo nodo, excepto por la raíz y las hojas, tiene al menos m/2 hijos
iii) La raíz tiene por lo menos 2 hijos (a menos que sea una hoja)
iv) Todas las hojas se encuentran en el mismo nivel y no tienen información
5
v)
Un nodo interno (no es hoja) con k hijos posee k-1 claves
Definición en “Art Of Computer Programming, 3rd Edition – D. Knuth”, cuando usa la
definición de Bayer y McCreight.
Puede considerarse, como las hojas no tienen punteros a otros nodos, que no son
parte del árbol, sino el último nivel de indexación antes del datafile.
Ésta
consideración es útil dado que los nodos hoja son diferentes a los nodos internos del
árbol.
Las características del B-Tree aseguran que se encuentra balanceado (ver
característica iv) ). Esto se logra en los algoritmos de inserción y eliminación con
dos algoritmos respectivos auxiliares: split y concatenation
(separación y
concatenación) que serán explicados más adelante.
Elmasri y Navathe hacen una definición formal del B-Tree de búsqueda, pensado ya
en la implementación para una base de datos:
Un B-Tree de orden p se define:
1. Cada nodo interno es de la forma:
<P1, <K1,Pr1>, P2, <K2,Pr2>, ..., <Kq-i,Prq-i>, Pq>
2.
3.
4.
5.
donde q  p . Cada Pi es un puntero a otro nodo, cada Pri es un puntero a un
registro del data file al cual corresponde una clave Ki.
Dentro de cada nodo, K1 < K2 < ... < Kq-1
Para todo valor X de búsqueda en el subárbol apuntado por Pi se encontrará:
Ki-1 < X < Ki , para 1 < i < q ; X < Ki para i =1 ; Ki-1 < X para i = q
Cada nodo tiene como máximo p punteros a hijos.
Cada nodo, excepto la raíz y las hojas, tienen al menos ( p / 2) punteros a
nodos. La raíz tiene por lo menos 2 punteros a menos que sea el único nodo
en el árbol (es hoja).
6. Un nodo con q punteros a nodos, q  p, tiene q-1 valores clave de búsqueda y
por lo tanto q-1 punteros a registros de datos.
7. Las hojas se encuentran en el mismo nivel. Tienen la misma estructura que
los nodos internos con excepción de que sus punteros Pi a nodos son todos
null.
“Fundamentals Of Database Systems – Elmasri & Navathe”
6
Veamos la estructura de un nodo de un B-Tree, según la definición mencionada:
La estructura del B-Tree será:
Este en particular es un B-Tree de p = 3.
Vayamos de a poco observando...
¿Cuál es la ventaja del B-Tree?
Si utilizamos un orden p grande, digamos p = 200, el árbol crecerá a lo ancho en vez
de a lo alto, asegurando una baja cantidad de accesos a disco.
Pero este B-Tree tiene un inconveniente a nivel de eficiencia. ¿Qué ocurre cuando
eliminamos un registro de nuestra base? Digamos que queremos eliminar el registro
de clave 8 del B-Tree mostrado. Esto necesitaría de una reorganización del árbol
que en disco tendría un gran coste con un orden p elevado.
Otra característica importante a considerar es el coste de la operación NEXT. Si
trabajamos en un B-TREE, debemos conservar en una pila el camino recorrido para
llegar al siguiente registro correspondiente y el coste de la operación será
significativo dado que debemos volver a acceder a nodos a los que ya habíamos
accedido para llegar a donde estábamos.
Hay una mejora de este árbol que es el B+-TREE.
Ф B+-TREE
7
La mayoría de las implementaciones utilizan éste árbol. En un B-TREE, toda clave
aparece una sola vez en todo el árbol, y se encuentra con su correspondiente
puntero al registro respectivo. En un B +-TREE, los punteros a registros de datos sólo
se guardan en las hojas del árbol, luego la estructura de las hojas difiere de la
estructura de los nodos internos. Otra característica interesante del B +-TREE es que
las hojas están unidas unas a otras secuencialmente permitiendo un veloz acceso
secuencial de la base de datos (recordar operación NEXT). En el caso del B+-TREE,
algunos valores de clave se repetirán en los nodos internos para guiar la búsqueda.
La estructura de un B+-TREE de orden p es la siguiente:
1. Cada nodo interno es de la forma:
<P1, K1, P2, K2, ..., Pq-1, Kq-1, Pq>
donde q  p y cada Pi es un puntero a nodo.
2. Dentro de cada nodo interno, K1 < K2 < ... < Kq-1
3. Para todo valor X de búsqueda en el subárbol apuntado por Pi se encontrará:
Ki-1 < X  Ki , para 1 < i < q ; X  Ki para i =1 ; Ki-1 < X para i = q
4. Cada nodo tiene como máximo p punteros a nodos hijos.
5. Cada nodo, excepto la raíz, tiene por lo menos ( p / 2) punteros a nodo. La
raíz tiene por lo menos 2 punteros a hijos si es un nodo interno.
6. Un nodo interno con q punteros, q  p, tiene q-1 claves de búsqueda.
Estructura de un nodo interno del B+-TREE
La estructura de los nodos hoja del B+-TREE es la siguiente:
1. Cada nodo hoja es de la forma:
<<K1, Pr1>, <K2, Pr2>, ..., <Kq-1, Prq-1>, Pnext >
donde q  p, cada Pri es un puntero a registro de datos y Pnext apunta a la
siguiente hoja en el B+-TREE.
2. Dentro de cada nodo hoja, K1 < K2 < ... < Kq-1 , q  p
3. Cada Pri es un puntero al registro de datos cuya clave es K i.
4. Cada nodo hoja tiene al menos ( p / 2) valores.
5. Todos los nodos hoja están en el mismo nivel.
8
Estructura de un nodo hoja del B+-TREE
Para un B+-TREE contruido sobre un campo clave, los punteros en los nodos internos
apuntan a sectores del disco donde se guardan otros nodos; los punteros en los
nodos hoja apuntan a sectores del disco donde se encuentran los registros de datos
correspondientes, excepto por el Pnext que apunta a la siguiente hoja en el árbol. Si
empezamos en la hoja más a la izquierda, podremos recorrer los registros como si la
estructura fuese una lista ordenada. Puede además incluirse un puntero Pprevious para
agregar funcionalidad y así poder realizar fácilmente la operación PREVIOUS.
Ф Los algoritmos
Los algoritmos de inserción y eliminación pueden ser algo complicados y tienen un
coste que es relativamente alto, debido a que deben acceder algunas veces al disco.
Igualmente se demuestra por análisis y simulación que luego de ingresar y eliminar
numerosos valores al árbol, éste mantiene sus nodos internos un 69% llenos y desde
ese punto hay muy pocas eliminaciones e inserciones sobre los nodos internos.
Esto asegura una gran eficiencia en la inserción y eliminación (en el caso promedio)
en el árbol.
ATENCIÓN: La inserción o eliminación de un registro no implica esta operación sobre
un nodo interno (Si esto no se comprende, revisar la definición de B+-TREE).
Búsqueda
La descripción del algoritmo de búsqueda es un poco trivial. Alcanza con analizar la
característica 3. de la definición de B+-TREE. Dada una clave X a buscar, se empieza
en la raíz. El valor X estará acotado como indica la característica 3., y luego a la
búsqueda le corresponderá acceder a un nodo hijo en correspondencia a la acotación
de X con respecto a las claves del nodo donde se está buscando.
Por ejemplo:
9
Si queremos buscar el registro de clave 5, empezamos por la raíz. El 5 coincide con
la clave K1 y luego seguiremos la búsqueda por el nodo apuntado por P 1. Aquí
hallamos que 5 > K1 siendo K1 = 3. Luego seguimos la búsqueda por el nodo
apuntado por P2, en este caso, una hoja. En esta hoja encontraremos la clave 5, o
sea, K1 = 5 y le corresponde un puntero Pr1 que apunta al registro de datos de clave
5 en el datafile.
Inserción
El algoritmo de inserción es un poco más complicado. Veamos este caso.
Al insertar en primer lugar el 8 y el 5, la raíz es el único nodo y es además un nodo
hoja.
Notemos algo:
- Todo valor debe existir en el nivel de las hojas porque todo puntero a
registros está en ellas.
- Sólo algunos valores de clave están en los nodos internos, éstos sirven para
guiar la búsqueda.
- Cada clave que aparece en un nodo interno es además la clave más a la
derecha del subárbol apuntado por el puntero a la izquierda de la clave
interna mencionada.
Cuando un nodo hoja hace overflow (posee más que p-1 claves) éste debe ser
separado (split). Las primeras ( p  1) / 2 claves se mantienen en el nodo a separar
y las demás se mueven hacia un nuevo nodo hoja. La clave
( p  1) / 2 -ésima
se
copia como clave hacia el nodo interno padre y sobre el padre también se agrega un
puntero a la nueva hoja. Si la inserción de esta nueva clave en el padre lo lleva al
overflow, entonces se debe hacer split sobre éste, con la diferencia de que la clave
( p  1) / 2 -ésima se mueve hacia el padre, no se copia. El split puede propagarse
hacia arriba hasta la raíz, y si ésta hace overflow, entonces se separa, se crea una
nueva raíz padre de la anterior y luego el B+-TREE adquiere un nuevo nivel.
Aclaración:
Éste algoritmo de inserción caracteriza al árbol como un “bottom-up tree”. Pues
crece de abajo hacia arriba. La otra posibilidad sería ir separando los nodos en la
bajada. O sea, si al ingresar una nueva clave y cuando esta va bajando se
encuentra con un nodo lleno, entonces hacemos split sobre éste y seguimos bajando
la clave hasta llegar a las hojas. Este sería un “top-down tree”, pues crece de arriba
hacia abajo (nos referimos al sentido de propagación del split). Normalmente se
10
utiliza el bottom-up, pero en un B-TREE debido a que es muy “chato” la diferencia no
es notable, por lo tanto puede usarse cualquier de los dos algoritmos consiguiendo la
misma eficiencia.
Eliminación
Cuando un registro es borrado, siempre se elimina del nivel de hojas. Si el valor de
clave que es borrado se encuentra en un nodo interno, también debe ser removido
aquí. Esto último se logra cambiando la clave interna por la nueva clave más a la
derecha en el subárbol apuntado por el puntero izquierdo a la clave interna
mencionada.
Cuando eliminamos una clave de un nodo, si éste queda con al menos  p / 2 hijos no
hay problema, el proceso ha finalizado. Pero puede pasar que se llegue a un
underflow, o sea, que el nodo posea menos hijos que los necesarios:
(NOTAR QUE EL NODO HOJA TIENE COMO MÁXIMO p-1 HIJOS)
En este caso se intentan en orden:
- Redistribución:
Se toma un nodo hermano y se redistribuyen las claves hasta que ambos
tengan al menos  p / 2 hijos. Normalmente se intenta primero con el
-
hermano izquierdo, si no es posible se intenta con el derecho y en última
instancia se hace una redistribución con ambos. Notar que siempre para un
nodo dado, el puntero respectivo en su padre debe tener a su derecha una
clave igual o mayor a la mayor clave del nodo mencionado.
A veces la redistribución no es posible, pues los nodos quedarían en
underflow. En este caso se lleva a cabo otra solución.
Nota:La redistribución no se propaga.
Concatenación:
Es la unión del nodo con su hermano. Esto conlleva una disminución de 1 en
la cantidad de nodos y por lo tanto una disminución de 1 en las claves y
punteros del padre. Primero se intenta concatenar con el hermano izquierdo,
si no es posible se lo hará con el derecho.
Al disminuir la cantidad de claves del padre, la concatenación puede
propagarse hasta que la raíz llegue a tener menos de 2 hijos, en cuyo caso se
generará una disminución de la altura del árbol.
Nota:A veces la concatenación puede generar un split.
ATENCIÓN:
El nodo hoja tiene como máximo p-1 punteros (no contamos el pnext), luego al aplicar
el algoritmo de eliminación explicado sobre las hojas se debe interpretar:
“Tener al menos  p / 2 hijos”  “tener al menos ( p  1) / 2 punteros”
Aclaración:
Este es un posible algoritmo. También existe otra variante de éste, que es un
algoritmo un poco más eficiente.
Al eliminar una clave, no necesariamente es eliminada de los nodos internos, ya que
sigue sirviendo como guía para la búsqueda. Llegado el caso que se de una
concatenación puede que se elimine un valor de clave en un nodo interno, pero no
forzaremos esta situación si la clave eliminada coincide con una que se encuentra en
el árbol, como se mencionó en el algoritmo anterior. Esto disminuye el coste del
algoritmo de eliminación.
11
Ф Los costos de los algoritmos
Llámese p ó m, es el orden del árbol al cual nos referimos, o sea, la cantidad
máxima de hijos que posee un nodo.
Pensemos que cuanto más grande sea nuestro p, más ancho será el árbol, luego
menos accesos a disco serán necesarios para encontrar un nodo. Pero pensemos
también, que al ser mayor p, más grandes serán los nodos que debemos levantar en
memoria. Luego el tamaño no puede ser arbitrario, ya que el nodo debe entrar en
memoria.
Los costos de los algoritmos dependerán de la altura del árbol, y ésta depende del
órden del mismo.
Puede demostrarse (no viene al caso) que la altura (h) del árbol será:
 N  1
h  log p / 2  

 2 
Siendo N = cantidad de claves en el árbol
Costo en la búsqueda:
Para clasificar los costos se separarán los costos de lectura y escritura.
Sean:
f = cantidad de nodos accedidos
 = cantidad de escrituras realizadas
Para la búsqueda tendremos:
fmin
1
fmax
h
min
0
max
0
El análisis de esto es trivial.
Luego, para un N=1.999.998 y un p=199, se requieren como máximo 3 accesos a
nodos para hallar una clave. (Ver la fórmula de h)
Normalmente se trabaja con la raíz en memoria para no tener que levantarla en cada
operación, lo que significaría en este caso que necesitaríamos tan sólo 2 accesos a
disco para hallar una clave. Pensemos que el índice maneja 2 millones de claves.
Bastante eficiente, ¿no?
12
Veamos algunos valores:
La tabla muestra en función del orden p y la cantidad de claves N, la cantidad de
accesos a nodos necesarios para concretar una búsqueda.
¿Pero qué sucede cuando uno levanta un nodo en memoria?
El nodo podría contener una lista enlazada de los elementos <K i, Pi>, luego debemos
hacer una búsqueda interna de la clave en el nodo. Una característica de la
implementación puede ser que el nodo guarde cuántas claves tiene en su interior, o
sea, cuán lleno está. Puede entonces hacerse lo siguiente:
- Si tiene pocas claves, se hace una búsqueda secuencial
- De lo contrario, lo más veloz será una búsqueda binaria
¿A qué nos lleva todo esto?
Empírica y analíticamente se llega a un intervalo de valores de p que son los
óptimos, éste valor dependerá de las características de la computadora sobre la que
queramos manejar nuestro árbol.
La elección de un valor de p no es sencilla.
Bayer y McCreight construyeron con buenos resultados una manera de elegir el
orden del B-TREE, pero el desarrollo es bastante complejo y depende de los tiempos
de acceso de la máquina, tanto a nivel de memoria primaria como secundaria.
Coste de la inserción:
fmin
h
fmax
h
min
1
max
2h+1
En el mejor caso, solo necesitamos recorrer el árbol y hacer la inserción, sin ninguna
separación.
El el peor caso, debemos separar el nodo y el overflow se propaga hasta la raíz,
llevándonos a separala y creando un nuevo nivel para el árbol. Luego se necesitan
los h accesos para recorrer el árbol más la escritura de dos nodos por cada uno
separado (aparece uno nuevo en cada separación) y la creación de una nueva raíz
(2h+1).
Coste de la eliminación:
fmin
h
fmax
2h-1
min
1
max
h+1
En el mejor caso, recorremos el árbol y eliminamos la clave correspondiente.
13
En el peor caso,
modificada.
la concatenación se propaga hasta el hijo de la raíz y la raíz es
Ф B*-TREE
Knuth basándose en un concepto de Bayer y McCreight crea una variante del árbol
B-TREE con algunas mejoras.
Bayer y MacCreight proponían un concepto de manejo diferente del overflow. En vez
de generar siempre un split se trata antes de redistribuir las claves con los
hermanos, si esto no es posible, entonces forzar el split. Esto lleva a redefinir el
árbol condicionando los nodos a estar 2/3 llenos siempre. La nueva construcción
logra una búsqueda más rápida pero una inserción más costosa.
14
15
16
Ф Bibliografía consultada
Libros:
► The Art of Computer Programming, 3rd Vol. – D. E. Knuth
► Fundamentals of Database Systems – Elmasri and Navathe
► Algorithms In C++ – R. Sedgewick
Publicaciones:
► The Ubiquitous B-TREE – D. Comer
► Organization and Maintenance Of Large Ordered Indexes – Bayer and McCreight
17
Descargar