Análisis del Formato de Almacenamiento de Tablas en DuckDB – Parte 2

Análisis del Formato de Almacenamiento de Tablas en DuckDB - Parte 2 - Marketplace Insights - Imagen generada por IA

DuckDB Internals: Análisis del Formato de Almacenamiento de Tablas

El formato de almacenamiento de tablas de DuckDB es esencial para comprender cómo se gestionan y organizan los datos en esta base de datos. Este artículo se centra en el análisis del formato de almacenamiento de tablas basado en el código fuente de DuckDB v1.3.1, proporcionando detalles técnicos cruciales para desarrolladores y administradores de bases de datos.

En el artículo anterior, se ofreció una visión general del formato de archivo y del almacenamiento de metadatos de DuckDB. Sin embargo, se omitieron los detalles sobre el formato de almacenamiento de tablas debido a su complejidad. A continuación, se presenta un análisis exhaustivo de este formato, comenzando por la estructura de datos asociada al catálogo y su jerarquía.

Estructura de Datos del Catálogo

El catálogo es el punto de entrada principal para acceder a un archivo de DuckDB y gestiona varios objetos CatalogEntry en memoria. Las tablas son representadas por un objeto DuckTableEntry, que contiene un puntero crucial a un objeto DataTable. Los siguientes elementos son fundamentales para la comprensión de la estructura de datos de las tablas:

  • Una AttachedDatabase (correspondiente a un archivo de base de datos) contiene un catálogo.
  • Un Catalog (correspondiente al diccionario de datos) alberga múltiples esquemas.
  • Un Schema (similar a una base de datos en MySQL) contiene múltiples tablas, índices, funciones y otros objetos.
  • El foco de este artículo, la tabla, se representa en el catálogo como un objeto DuckTableEntry, que tiene un puntero a la clase DataTable.

Perspectiva Jerárquica del Almacenamiento de Tablas

Desde una perspectiva de alto nivel, el almacenamiento de tablas se organiza en una jerarquía de cuatro capas:

  • Una Tabla se particiona horizontalmente por filas en múltiples Row Groups.
  • Un Row Group se particiona verticalmente por columnas en múltiples objetos Column Data.
  • Un objeto Column Data se particiona horizontalmente por filas en múltiples Column Segments.
  • Un Column Segment representa los datos almacenados, generalmente correspondiente a un bloque de datos de 256 KB.

Es importante notar que el orden visual de las columnas en los diagramas es solo para claridad. En práctica, todos los datos de columna se almacenan de acuerdo al orden de filas, identificado por un Row ID. Esto permite localizar con precisión todos los datos para una fila dada, siendo una dependencia clave para el Segment Tree que se discutirá más adelante.

Estructuras de Datos en el Código Fuente

Al mapear estos conceptos al código fuente, se revelan las siguientes estructuras de datos:

  • Una tabla corresponde a un objeto DataTable, que contiene un puntero a un RowGroupCollection.
  • Un RowGroup contiene un arreglo de objetos ColumnData, uno para cada columna en la tabla.
  • ColumnData tiene varias subclases, como StandardColumnData y ValidityColumnData.

Árbol de Segmentos

Ambos pasos de partición horizontal utilizan un Segment Tree para gestionar el nivel siguiente de la jerarquía. RowGroup y ColumnSegment heredan de SegmentBase, permitiéndoles funcionar como nodos dentro de un SegmentTree. Cada nodo en un SegmentTree representa un rango de filas.

El árbol de segmentos no es un árbol en sí, sino un arreglo ordenado, lo que permite búsquedas binarias rápidas en el Row ID para localizar el nodo de segmento correcto.

Formato de Almacenamiento de la Tabla

Los datos de una tabla se almacenan físicamente en cuatro ubicaciones distintas:

  • Metadatos del Catálogo: El TableCatalogEntry reside en la lista de bloques meta del catálogo principal.
  • Metadatos Estructurales de la Tabla: La jerarquía desde Row Groups hasta Column Segments se almacena en una lista de bloques meta dedicada.
  • Información de Versión: Cada Row Group tiene información de versión, utilizada para rastrear filas eliminadas, almacenada en una lista de bloques meta separada.
  • Datos Reales: Los datos reales de la tabla residen en bloques de datos de 256 KB.

Proceso de Escritura

Durante un checkpoint, se utilizan dos instancias de MetadataWriter: uno para las entradas del catálogo y otro para los metadatos detallados de la tabla. El flujo de llamadas al escribir datos de tabla es de arriba hacia abajo, pero el flujo de datos es de abajo hacia arriba, ya que los componentes de nivel inferior deben devolver punteros a los niveles superiores.

Persistencia de Datos y Metadatos de Columnas

En esta etapa, se generan objetos DataPointer, cada uno representando un ColumnSegment. El proceso comienza en ColumnDataCheckpointer::WriteToDisk y abarca desde la actualización de segmentos hasta la finalización de la compresión y almacenamiento en bloques de datos.

El contenido específico de los metadatos de Column Data consiste en dos partes principales: el arreglo de data_pointers y los metadatos de la columna de validez, ambos representando la estructura de datos de los segmentos.

Conclusión

El análisis del formato de almacenamiento de tablas en DuckDB revela una estructura compleja pero organizada. Al comprender estas jerarquías y procesos, los desarrolladores y administradores pueden optimizar su uso de DuckDB para aplicaciones de análisis y gestión de datos eficientes.

Para más información, puedes consultar el artículo original en Alibaba Cloud.

Nota: Este contenido original ha sido modificado con IA y revisado por un especialista. Imagen generada por IA.

Deja una respuesta