Articulo de referencia

Árbol B+

Un árbol B+ es un árbol m-ario con un número variable, pero a menudo grande, de hijos por nodo. Un árbol B+ consta de una raíz, nodos internos y hojas. [ 1 ] La raíz puede ser u...

Un árbol B+ es un árbol m-ario con un número variable, pero a menudo grande, de hijos por nodo. Un árbol B+ consta de una raíz, nodos internos y hojas. [ 1 ] La raíz puede ser una hoja o un nodo con dos o más hijos.

Un árbol B+ puede considerarse como un árbol B en el que cada nodo contiene solo claves (no pares clave-valor) y al que se le añade un nivel adicional en la parte inferior con hojas enlazadas.

El valor principal de un árbol B+ reside en el almacenamiento de datos para su recuperación eficiente en un contexto de almacenamiento orientado a bloques , en particular, en sistemas de archivos . Esto se debe principalmente a que, a diferencia de los árboles de búsqueda binaria , los árboles B+ tienen un factor de ramificación muy alto (número de punteros a nodos hijos en un nodo, [ 1 ] normalmente del orden de 100 o más), lo que reduce el número de operaciones de E/S necesarias para encontrar un elemento en el árbol.

Historia

No existe un único documento que introduzca el concepto de árbol B+. En cambio, la idea de mantener todos los datos en los nodos hoja se menciona repetidamente como una variante interesante del árbol B, introducido por R. Bayer y E. McCreight. [ 2 ] Douglas Comer señala en un estudio temprano sobre árboles B (que también abarca los árboles B+) que el árbol B+ se utilizó en el software de acceso a datos VSAM de IBM y hace referencia a un artículo publicado por IBM en 1973. [ 3 ]

Estructura

Estructura de puntero

Formato de nodo de árbol B+ donde K=4. (p_i representa los punteros, k_i representa las claves de búsqueda).

Al igual que otros árboles, los árboles B+ se pueden representar como una colección de tres tipos de nodos: raíz , interno (también llamado interior) y hoja . En los árboles B+, se mantienen las siguientes propiedades para estos nodos:

  • Siki{\textstyle k_{i}}existe en cualquier nodo de un árbol B+, entonces k i -1 existe en ese nodo dondei1{\displaystyle i\geq 1}.
  • Todos los nodos hoja tienen el mismo número de ancestros (es decir, todos están a la misma profundidad).

Las propiedades de puntero de los nodos se resumen en las tablas siguientes:

  • K : Número máximo de claves de búsqueda potenciales para cada nodo en un árbol B+. (Este valor es constante en todo el árbol).
  • p i : El puntero en el índice de nodo basado en cero i .
  • k i : La clave de búsqueda en el índice de nodo basado en cero i .

límites de nodo

Los límites de los nodos se resumen en la tabla siguiente: [ 4 ] [ 5 ]

Intervalos en nodos internos

Un ejemplo sencillo de árbol B+ que vincula las claves 1–7 con los valores de datos d 1 -d 7 . La lista enlazada (en rojo) permite un recorrido rápido en orden. El factor de ramificación de este árbol en particular esb{\displaystyle b}=4. Tanto las claves en los nodos hoja como en los nodos internos están coloreadas de gris aquí.

Por definición, cada valor contenido en el árbol B+ es una clave contenida en un único nodo hoja. Cada clave debe ser directamente comparable con todas las demás, lo que forma un orden total . [ 6 ] Esto permite que cada nodo hoja mantenga todas sus claves ordenadas en todo momento, lo que a su vez permite que cada nodo interno construya una colección ordenada de intervalos que representan la extensión contigua de los valores contenidos en una hoja dada. Los nodos internos superiores en el árbol pueden entonces construir sus propios intervalos, que agregan recursivamente los intervalos contenidos en sus propios nodos internos hijos. Finalmente, la raíz de un árbol B+ representa todo el rango de valores en el árbol, donde cada nodo interno representa un subintervalo.

Para que se conserve esta información de intervalo recursivo, los nodos internos deben contener adicionalmentemetro1{\displaystyle m-1}copias de las clavesli{\displaystyle l_{i}}parai[1,metro1]{\displaystyle i\in [1,m-1]}representa el elemento más pequeño dentro del intervalo cubierto por el hijo con índice i (que puede ser un nodo interno o una hoja). Donde m representa el número real de hijos para un nodo interno dado.

Características

El orden o factor de ramificación b de un árbol B+ mide la capacidad de los nodos internos, es decir, su número máximo permitido de nodos hijos directos. Este valor es constante en todo el árbol. Para un árbol B+ de orden b con h niveles de índice:

  • El número máximo de registros almacenados esnortemáximo=bhbh1{\displaystyle n_{\max }=b^{h}-b^{h-1}}{bh1{\displaystyle b^{h-1}}se resta para tener en cuenta los punteros siguientes que no apuntan a registros de datos, sino que apuntan al siguiente nodo hoja}
  • El número mínimo de registros almacenados esnortemin=2b2h12b2h2{\displaystyle n_{\min }=2\left\lceil {\tfrac {b}{2}}\right\rceil ^{h-1}-2\left\lceil {\tfrac {b}{2}}\right\rceil ^{h-2}}
  • El número mínimo de claves esnortekmetroinorte=2b2h11{\displaystyle n_{\mathrm {kmin} }=2\left\lceil {\tfrac {b}{2}}\right\rceil ^{h-1}-1}
  • El número máximo de claves esnortekmetroaincógnita=bh1{\displaystyle n_{\mathrm {kmax} }=b^{h}-1}
  • El espacio necesario para almacenar el árbol esO(norte){\displaystyle O(n)}
  • Insertar un registro requiereO(registrobnorte){\displaystyle O(\log _{b}n)}operaciones
  • Encontrar un registro requiereO(registrobnorte){\displaystyle O(\log _{b}n)}operaciones
  • Eliminar un registro (previamente ubicado) requiereO(registrobnorte){\displaystyle O(\log _{b}n)}operaciones
  • Realizar una consulta de rango con k elementos que se encuentran dentro del rango requiereO(registrobnorte+k){\displaystyle O(\log _{b}n+k)}operaciones
  • La estructura de árbol B+ se expande/contrae a medida que aumenta/disminuye el número de registros . No existen restricciones en el tamaño de los árboles B+. Por lo tanto, aumenta la usabilidad de un sistema de base de datos .
  • Cualquier cambio en la estructura no afecta el rendimiento debido a las propiedades equilibradas del árbol. [ 7 ]
  • Los datos se almacenan en los nodos hoja y una mayor ramificación de los nodos internos ayuda a reducir la altura del árbol, disminuyendo así el tiempo de búsqueda. Como resultado, funciona bien en dispositivos de almacenamiento secundario. [ 8 ]
  • La búsqueda se vuelve extremadamente sencilla porque todos los registros se almacenan únicamente en el nodo hoja y se ordenan secuencialmente en la lista enlazada.
  • Podemos recuperar rangos o recuperar parcialmente usando un árbol B+. Esto se hace más fácil y rápido al recorrer la estructura del árbol. Esta característica hace que la estructura del árbol B+ se aplique en muchos métodos de búsqueda. [ 7 ]

Algoritmos

Estamos buscando un valor k en el árbol B+. Esto significa que, comenzando desde la raíz, estamos buscando la hoja que pueda contener el valor k . En cada nodo, determinamos qué nodo interno debemos seguir. Un nodo interno del árbol B+ tiene como máximometrob{\displaystyle m\leq b} hijos, donde cada uno de ellos representa un subintervalo diferente. Seleccionamos el hijo correspondiente mediante una búsqueda lineal de las m entradas, luego, cuando finalmente llegamos a una hoja, hacemos una búsqueda lineal de sus n elementos para la clave deseada. Debido a que solo recorremos una rama de todos los hijos en cada peldaño del árbol, logramosO(registronorte){\displaystyle O(\log N)}tiempo de ejecución, donde N es el número total de claves almacenadas en las hojas del árbol B+. [ 4 ]

función search( k , root ) es let leaf = leaf_search(k, root) for leaf_key in leaf.keys(): if k = leaf_key: return true return false
La función leaf_search( k , node ) es si node es una hoja: devuelve node. let p = node.children() let l = node.left_sided_intervals() assert|pag|=|l|+1{\displaystyle |p|=|l|+1}sea ​​m = p.len() para i desde 1 hasta m - 1: sikl[i]{\displaystyle k\leq l[i]}: devolver leaf_search(k, p[i]) devolver leaf_search(k, p[m])

Tenga en cuenta que este pseudocódigo utiliza indexación de matrices basada en 1.

Inserción

  • Realiza una búsqueda para determinar en qué nodo debe ir el nuevo registro.
  • Si el nodo no está lleno (como máximo)b1{\displaystyle b-1}entradas después de la inserción), agregue el registro.
  • De lo contrario, antes de insertar el nuevo registro
    • Divide el nodo.
      • El nodo original tiene(K+1)/2{\displaystyle \lceil (K+1)/2\rceil}elementos
      • nuevo nodo tiene(K+1)/2{\displaystyle \lfloor (K+1)/2\rfloor }elementos
    • Copiar(K+1)/2{\displaystyle \lceil (K+1)/2\rceil}-la clave al padre, e insertar el nuevo nodo en el padre.
    • Repita el proceso hasta encontrar un padre que no necesite dividirse.
    • Inserta el nuevo registro en el nuevo nodo.
  • Si la raíz se divide, trátela como si tuviera un padre vacío y divídala como se describe anteriormente.

Los árboles B+ crecen en la raíz y no en las hojas. [ 1 ]

Carga a granel

A partir de un conjunto de registros de datos, queremos crear un índice de árbol B+ en un campo clave. Un enfoque consiste en insertar cada registro en un árbol vacío. Sin embargo, esto resulta bastante costoso, ya que cada entrada requiere comenzar desde la raíz y descender hasta la página hoja correspondiente. Una alternativa eficiente es utilizar la carga masiva.

  • El primer paso consiste en ordenar las entradas de datos según una clave de búsqueda en orden ascendente.
  • Asignamos una página vacía para que sirva como raíz e insertamos en ella un puntero a la primera página de entradas.
  • Cuando la raíz está llena, la dividimos y creamos una nueva página raíz.
  • Continúe insertando entradas en la página de índice más a la derecha, justo encima del nivel de hoja, hasta que todas las entradas estén indexadas.

Nota:

  • Cuando se llena la página de índice situada más a la derecha del nivel de hoja, esta se divide;
  • Esta acción puede, a su vez, provocar una división de la página de índice más a la derecha, acercándola un paso más a la raíz;
  • Las divisiones solo ocurren en el camino más a la derecha desde la raíz hasta el nivel de la hoja. [ 9 ]

Supresión

El objetivo del algoritmo de eliminación es suprimir el nodo de entrada deseado de la estructura de árbol. Llamamos recursivamente al algoritmo de eliminación en el nodo correspondiente hasta que no se encuentre ningún nodo. En cada llamada a la función, recorremos la estructura utilizando el índice para navegar hasta encontrar el nodo, lo eliminamos y luego volvemos a la raíz.

En la entrada L que deseamos eliminar:

  • Si L está al menos medio lleno, listo.
  • Si L tiene solo d-1 entradas, intente redistribuir, tomando prestado de un nodo hermano (nodo adyacente con el mismo padre que L).
    Tras la redistribución de dos nodos hermanos, el nodo padre debe actualizarse para reflejar este cambio. La clave de índice que apunta al segundo hermano debe tomar el valor más pequeño de ese nodo para convertirse en la clave de índice.
  • Si la redistribución falla, se fusionan L y su nodo hermano. Tras la fusión, el nodo padre se actualiza eliminando la clave de índice que apunta a la entrada eliminada. En otras palabras, si se produjo la fusión, se debe eliminar la entrada (que apunta a L o a su nodo hermano) del nodo padre de L.

Nota: la fusión podría propagarse a la raíz, lo que significa una altura decreciente. [ 10 ]

Eliminación de árbol B+

Implementación

Las hojas (los bloques de índice más bajos) del árbol B+ suelen estar enlazadas entre sí mediante una lista enlazada; esto simplifica y optimiza las consultas de rango o la iteración (ordenada) a través de los bloques (aunque el límite superior mencionado anteriormente puede alcanzarse incluso sin esta adición). Esto no incrementa sustancialmente el consumo de espacio ni el mantenimiento del árbol. Esto ilustra una de las ventajas significativas de un árbol B+ sobre un árbol B; en un árbol B, dado que no todas las claves están presentes en las hojas, no se puede construir una lista enlazada ordenada de este tipo. Por lo tanto, un árbol B+ resulta particularmente útil como índice de un sistema de base de datos , donde los datos suelen residir en disco, ya que permite que el árbol B+ proporcione una estructura eficiente para almacenar los datos (esto se describe en [ 11 ] : 238 como la estructura de índice "Alternativa 1").

Si un sistema de almacenamiento tiene un tamaño de bloque de B bytes y las claves a almacenar tienen un tamaño de k, posiblemente el árbol B+ más eficiente sea aquel dondeb=Bk1{\displaystyle b={\tfrac {B}{k}}-1}Aunque teóricamente esta operación puntual no es necesaria, en la práctica suele haber un pequeño espacio adicional ocupado por los bloques de índice (por ejemplo, las referencias a listas enlazadas en los bloques hoja). Un bloque de índice ligeramente mayor que el bloque real del sistema de almacenamiento supone una disminución significativa del rendimiento; por lo tanto, es preferible ser precavido.

Si los nodos del árbol B+ se organizan como arreglos de elementos, insertar o eliminar un elemento puede llevar bastante tiempo, ya que, en promedio, será necesario desplazar la mitad del arreglo. Para solucionar este problema, los elementos dentro de un nodo pueden organizarse en un árbol binario o un árbol B+ en lugar de un arreglo.

Los árboles B+ también pueden utilizarse para datos almacenados en la RAM. En este caso, una opción razonable para el tamaño del bloque sería el tamaño de la línea de caché del procesador.

La eficiencia espacial de los árboles B+ se puede mejorar utilizando algunas técnicas de compresión. Una posibilidad es utilizar la codificación delta para comprimir las claves almacenadas en cada bloque. Para los bloques internos, el ahorro de espacio se puede lograr comprimiendo claves o punteros. Para las claves de cadena, se puede ahorrar espacio utilizando la siguiente técnica: Normalmente, la i -ésima entrada de un bloque interno contiene la primera clave del bloque .i+1{\displaystyle i+1}En lugar de almacenar la clave completa, podríamos almacenar el prefijo más corto de la primera clave del bloque .i+1{\displaystyle i+1}que es estrictamente mayor (en orden lexicográfico) que la última clave del bloque i . También hay una forma sencilla de comprimir punteros: si suponemos que algunos bloques consecutivosi,i+1,...i+k{\displaystyle i,i+1,...i+k}Si se almacenan de forma contigua, bastará con almacenar únicamente un puntero al primer bloque y el número de bloques consecutivos.

Todas las técnicas de compresión mencionadas anteriormente presentan inconvenientes. En primer lugar, es necesario descomprimir un bloque completo para extraer un solo elemento. Una técnica para solucionar este problema consiste en dividir cada bloque en subbloques y comprimirlos por separado. De esta forma, para buscar o insertar un elemento, solo será necesario descomprimir o comprimir un subbloque en lugar de un bloque completo. Otro inconveniente de las técnicas de compresión es que el número de elementos almacenados puede variar considerablemente de un bloque a otro, dependiendo de la eficacia de la compresión.

Aplicaciones

Sistemas de archivos

Los sistemas de archivos ReiserFS , NSS , XFS , JFS , ReFS y BFS utilizan este tipo de árbol para la indexación de metadatos; BFS también utiliza árboles B+ para almacenar directorios. NTFS utiliza árboles B+ para la indexación de directorios y metadatos relacionados con la seguridad. EXT4 utiliza árboles de extensión (una estructura de datos de árbol B+ modificada) para la indexación de extensiones de archivos. [ 12 ] APFS utiliza árboles B+ para almacenar asignaciones de identificadores de objetos del sistema de archivos a sus ubicaciones en el disco, y para almacenar registros del sistema de archivos (incluidos directorios), aunque los nodos hoja de estos árboles carecen de punteros hermanos. [ 13 ]

Sistemas de bases de datos

Los sistemas de gestión de bases de datos relacionales como IBM Db2 , [ 11 ] Informix , [ 11 ] Microsoft SQL Server , [ 11 ] Oracle 8 , [ 11 ] Sybase ASE , [ 11 ] y SQLite [ 14 ] admiten este tipo de árbol para los índices de las tablas, aunque cada uno de estos sistemas implementa la estructura básica del árbol B+ con variaciones y extensiones. Muchos sistemas de gestión de bases de datos NoSQL como CouchDB [ 15 ] [ a ] y Tokyo Cabinet [ 16 ] también admiten este tipo de árbol para el acceso y almacenamiento de datos.

Encontrar objetos en una base de datos de alta dimensión que sean comparables a un objeto de consulta específico es uno de los procedimientos más utilizados, aunque costoso, en este tipo de sistemas. En tales situaciones, encontrar el vecino más cercano mediante un árbol B+ resulta productivo. [ 17 ]

iDistance

El árbol B+ se utiliza de manera eficiente para construir un método de búsqueda indexada llamado iDistance. iDistance busca k vecinos más cercanos (kNN) en espacios métricos de alta dimensión. Los datos en estos espacios se dividen según estrategias de espacio o partición, y cada partición tiene un valor de índice cercano a la partición. A partir de aquí, estos puntos se pueden implementar de manera eficiente utilizando el árbol B+, por lo que las consultas se asignan a una búsqueda de rango de una sola dimensión. En otras palabras, la técnica iDistance puede considerarse una forma de acelerar el escaneo secuencial. En lugar de escanear los registros desde el principio hasta el final del archivo de datos, iDistance comienza el escaneo desde los puntos donde los vecinos más cercanos se pueden obtener tempranamente con una probabilidad muy alta. [ 18 ]

NVRAM

La memoria de acceso aleatorio no volátil (NVRAM) ha estado utilizando la estructura de árbol B+ como técnica principal de acceso a la memoria para el sistema de Internet de las Cosas (IoT) debido a su consumo de energía no estático y la alta solidez de la memoria de celda.  B+ puede regular el tráfico de datos a la memoria de manera eficiente. Además, con estrategias avanzadas sobre las frecuencias de algunas hojas o puntos de referencia de uso frecuente, el árbol B+ muestra resultados significativos en el aumento de la resistencia de los sistemas de bases de datos. [ 19 ]

Véase también

Notas

  1. Véase la nota después del tercer párrafo.

Referencias

  1. 1 2 3 4 Elmasri, Ramez ; Navathe, Shamkant B. (2010). Fundamentos de los sistemas de bases de datos (6ª  ed.). Upper Saddle River, Nueva Jersey: Pearson Education. págs. 652–660 . ISBN  9780136086208. LCCN 2010010677 . OCLC 586123196 . OL 24411294M .   
  2. Bayer, R.; McCreight, E. (noviembre de 1970). «Organización y mantenimiento de grandes índices ordenados» . Actas del Taller ACM SIGFIDET (ahora SIGMOD) de 1970 sobre Descripción, Acceso y Control de Datos - SIGFIDET '70 . págs. 107–141 . doi : 10.1145/1734663.1734671 . ISBN  978-1-4503-7941-0.
  3. Comer, Douglas (1979). "Árbol B ubicuo" . ACM Computing Surveys . 11 (2): 121– 137. doi : 10.1145/356770.356776 . S2CID 101673 . 
  4. 1 2 Pollari-Malmi, Kerttu. ""Árboles B+"" (PDF) . Informática, Facultad de Ciencias, Universidad de Helsinki . p.  3. Archivado del original (PDF) el 14 de abril de 2021.
  5. Silberschatz, Abraham; Korth, Henry F.; Sudarshan, S. (2020). Conceptos de sistemas de bases de datos (Séptima ed.). Nueva York, NY: McGraw-Hill Education. ISBN  978-1-260-08450-4.
  6. ^ Grust, Torsten (verano de 2013). ""Indexación estructurada en árbol: ISAM y árboles B+"" (PDF) . Logo der Universität Tübingen Department of Computer Science: Database Systems . p.  84. Archivado del original (PDF) el 31 de octubre de 2020.
  7. 1 2 Zeitler, Erik; Risch, Tore (2010). "División escalable de flujos de datos masivos" . Sistemas de bases de datos para aplicaciones avanzadas . Notas de clase en informática. Vol. 5982. págs. 184–198 . doi : 10.1007/978-3-642-12098-5_15 . ISBN   978-3-642-12097-8.
  8. Xu, Chang; Shou, Lidan; Chen, Gang; Yan, Cheng; Hu, Tianlei (2010). "Migración de actualizaciones: un árbol B+ eficiente para almacenamiento flash". Sistemas de bases de datos para aplicaciones avanzadas . Notas de clase en ciencias de la computación. Vol. 5982. págs. 276–290 . doi : 10.1007/978-3-642-12098-5_22 . ISBN   978-3-642-12097-8.
  9. "ECS 165B: Implementación de sistemas de bases de datos, Lección 6" (PDF) . Departamento de Ciencias de la Computación de UC Davis . 9 de abril de 2010. págs. 21–23 . 
  10. ^ Ramakrishnan, Raghu; Johannes Gehrke (2003). Sistemas de gestión de bases de datos (3ª ed.). Boston: McGraw-Hill. ISBN  0-07-246563-8OCLC 49977005 
  11. 1 2 3 4 5 6 Raghu, Ramakrishnan; Johannes, Gehrke (2000). Sistemas de gestión de bases de datos (2.ª ed.). McGraw-Hill Higher Education. pág. 267.  ISBN 978-0-07-245052-1
  12. Giampaolo, Dominic (1999). Diseño práctico de sistemas de archivos con el sistema de archivos Be (PDF) . Morgan Kaufmann. ISBN 1-55860-497-9Archivado del original (PDF) el 13 de febrero de 2017. Consultado el 29 de julio de 2014 .
  13. "Árboles B". Referencia del sistema de archivos de Apple (PDF) . Apple Inc. 22 de junio de 2020. pág. 122. Consultado el 10 de marzo de 2021 . 
  14. Descripción general de SQLite versión 3
  15. Guía de CouchDB
  16. Referencia al Gabinete de Tokio. Archivado el 12 de septiembre de 2009 en Wayback Machine .
  17. Sistemas de bases de datos para aplicaciones avanzadas . Japón. 2010.{{cite book}}: CS1 mantenimiento: falta el editor de ubicación ( enlace )
  18. Jagadish, HV; Ooi, Beng Chin; Tan, Kian-Lee; Yu, Cui; Zhang, Rui (junio de 2005). "iDistance: un método de indexación basado en árboles B+ adaptativo para la búsqueda del vecino más cercano" . ACM Transactions on Database Systems . 30 (2): 364–397 . doi : 10.1145/1071610.1071612 . ISSN 0362-5915 . S2CID 967678 .  
  19. Dharamjeet; Chen, Tseng-Yi; Chang, Yuan-Hao; Wu, Chun-Feng; Lee, Chi-Heng; Shih, Wei-Kuan (diciembre de 2021). "Más allá de la consideración de reducción de escritura: un esquema de indexación de árbol B⁺ habilitado para nivelación de desgaste sobre una arquitectura basada en NVRAM". IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems . 40 (12): 2455– 2466. Bibcode : 2021ITCAD..40.2455D . doi : 10.1109/TCAD.2021.3049677 . ISSN 0278-0070 . S2CID 234157183 .  
  • Árbol B+ en Python, utilizado para implementar una lista
  • Notas del índice del árbol B+ del Dr. Monge