Sistema gestor de base de datos orientado a columnas
# Sistema gestor de base de datos orientado a columnas

Un sistema gestor de base de datos orientado a columnas (o sistema de administración de base de datos columnar) es un sistema gestor de la base de datos (SGBD) que almacena tablas de datos por columnas en lugar de por fila. Los usos prácticos de un almacén de columna versus un almacén de filas difiere un poco en el mundo de los SGBD relacionales. Ambas bases de datos, columnar y de filas, pueden utilizar un lenguaje de consultas de bases de datos tradicionales como SQL para cargar datos y realizar consultas. Ambas bases de datos, de filas y columnares, pueden convertirse en la columna vertebral de un sistema para servir datos a herramientas comunes de extracción, transformación y carga (ETL) y de visualización de datos. Sin embargo, almacenando datos en columnas en lugar de en filas, la base de datos puede acceder de forma más precisa a los datos que necesita para responder a una consulta en vez de escanear y descartar datos no deseados en filas. El rendimiento de consultas incrementa para ciertas cargas de trabajo.

## Descripción

### Contexto

Un sistema de administración de bases de datos relacional proporciona datos que representan una tabla bidimensional, de columnas y filas. Por ejemplo, una base de datos podría tener esta tabla:

| RowId | EmpId | Apellido | Nombre | Salario |
| - | - | - | - | - |
| 001 | 10 | Smith | Joe | 60000 |
| 002 | 12 | Jones | Mary | 80000 |
| 003 | 11 | Johnson | Cathy | 94000 |
| 004 | 22 | Jones | Bob | 55000 |

Esta tabla sencilla incluye un identificador de empleado (EmpId), campos de nombre (Apellido y Nombre) y un salario (Salario). Este formato bidimensional es una abstracción . En una implementación real, el hardware de almacenamiento requiere que los datos estén serializados de una forma u otra.

Las operaciones más costosas que involucran a los discos duros son las búsquedas. Para mejorar el rendimiento global, los datos relacionados deberían ser almacenados en una forma que minimice el número de búsquedas. Esto está conocido como cercanía de referencias, y el concepto básico aparece en un número de contextos diferentes. Los discos duros están organizados en una serie de sectores de una medida fija, típicamente suficiente para almacenar varias filas de la tabla. Organizando los datos de la table de manera que las filas quepan dentro de estos sectores, y agrupando filas relacionadas en sectores secuenciales, el número de sectores que necesitan ser leídos o buscados es minimizado en muchos casos, junto con el número de búsquedas.

Desde el año 2017 en un estudio de Pinnecke et al. se cubrieron técnicas para hibridación de columna-/fila.

### Sistemas orientados a filas

Un método común de almacenar una tabla es serializar cada fila de datos, así:

Cuando el dato es insertado en la tabla, le es asignado un ID (identificador) interno, el rowid que es utilizado internamente en el sistema para referirse al dato. En este caso los registros tienen rowids secuenciales independientes del empid asignado al usuario. En este ejemplo, el SGBD utiliza enteros cortos para almacenar rowids. En la práctica, normalmente se utilizan números más grandes, de 64-bits o de 128-bits.

Los sistemas basados en filas son diseñados para retornar datos eficientemente para una fila entera, o registro, en tan pocas operaciones como sea posible. Esto encaja con el caso de uso común donde el sistema está intentando recuperar información sobre un objeto particular, por ejemplo la información de contacto de un usuario en un rolodex sistema, o la información de un producto para un sistema de compra en línea. Almacenando los datos del registro en un solo sector del disco, junto con registros relacionados, el sistema puede recuperar registros rápidamente con un mínimo de operaciones de disco.

Los sistemas basados en fila no son eficaces al realizar operaciones sobre conjuntos amplios en la tabla completa, al contrario de cuando las hace para un número pequeño de registros concretos. Por ejemplo, para encontrar todos los registros en la tabla del ejemplo con salarios entre 40,000 y 50,000, el SGBD tendría que escanear completamente toda la tabla en busca de registros que cumplan ese criterio. Aunque la tabla del ejemplo anterior probablemente cabe en un único sector de disco, una tabla con unos cuantos centenares de filas no lo hará, y se necesitarán múltiples operaciones de disco múltiple para recuperar los datos y examinarlos.

Para mejorar el rendimiento de estos tipos de operaciones (las cuales son muy comunes, y generalmente son la razón de utilizar un SGBD) la mayoría de los SGBDs soporta el uso de índices de base de datos, los cuales almacenan todos los valores de un conjunto de columnas junto con punteros al rowid que regresan a la tabla original. Un índice en la columna de salario se vería algo así:

Ya que los índices almacenan solo piezas solas de datos, en vez de filas enteras, los índices son generalmente mucho más pequeños que las tablas de almacenamiento principales. Escaneando este conjunto más pequeño de datos se reduce el número de operaciones de disco. Si el índice es utilizado intensivamente, puede reducir dramáticamente el tiempo para realizar operaciones comunes. Sin embargo, mantener índices añade sobrecarga al sistema, especialmente cuando se escriben nuevos datos a la base de datos. Los registros no solo necesitan ser almacenados en la tabla principal, sino que todos los índices ligados también tienen que ser actualizados.

La principal razón de por qué los índices mejoran dramáticamente el rendimiento en grandes conjuntos de datos es porque los índices de bases de datos en una o más columnas están ordenados típicamente por valor, lo que hace muy rápidas las operaciones de consultas de rangos (como el ejemplo anterior "encontrar todos los registros con salarios entre 40,000 y 50,000"), ya que se tiene una complejidad de tiempo más baja.

Un número de bases de datos orientadas a filas están diseñadas para caber enteramente en la RAM, una base de datos en memoria. Estos sistemas no dependen de operaciones de disco, y tienen tiempo de acceso igual que al conjunto de datos completo. Esto reduce la necesidad de índices, ya que requiere la misma cantidad de operaciones para escanear completamente los datos originales, que para escaneo de índice completo para propósitos de una agregación típica. Tales sistemas pueden ser, por tanto, más sencillos y más pequeños, pero solo pueden manejar bases de datos que caben en memoria.

### Sistemas orientados a columnas

Una base de datos orientada a columnas serializa juntos todos los valores de una columna, luego los valores de la columna siguiente, y así consecutivamente. Para nuestra tabla de ejemplo, el dato sería almacenado de este modo:

En este diseño, cualquiera de las columnas encaja más cercanamente a la estructura de índice en un sistema basado en filas. Esto puede causar confusión, lo que puede llevar a la creencia equivocada de que un almacén orientado a columnas "es realmente solo" un almacén orientado a filas con un índice en cada columna. Sin embargo, es el mapeo de los datos lo que difiere dramáticamente. En una sistema orientado a filas indexado, la llave primaria es el rowid que es mapeado a partir de los datos indexados. En un sistema orientado a columnas, la llave primaria es el dato, el cual es mapeado a partir de los rowids. Esto puede parecer sutil, pero la diferencia puede ser vista en esta modificación común al mismo almacén donde los dos elementos "Jones" son comprimidos en un solo elemento con dos rowids:

Si un sistema orientado a columnas será más eficaz, o no, en la operación depende en gran medida de la carga de trabajo a ser automatizada. Las operaciones que recuperan todos los datos para un objeto dado (la fila entera) son más lentas. Un sistema basado en filas puede recuperar la fila en una sola lectura de disco, mientras que en un sistema columnar se requieren numerosas operaciones de disco para recuperar los datos de múltiples columnas. Aun así, estas operaciones de fila entera son generalmente raras. En la mayoría de los casos, solo un subconjunto limitado de datos es recuperado. En una aplicación rolodex, por ejemplo, recuperar el nombre y apellido de muchas filas para construir una lista de contactos es mucho más común que leer todos los datos para una única dirección. Esto es aún más cierto para escribir datos en la base de datos, especialmente si los datos tienden a ser "escasos" con muchas columnas opcionales. Por esta razón, los almacenes de columna han demostrado excelente desempeño en el mundo real a pesar de muchas desventajas teóricas.

El particionamiento, la indexación, el cacheo, las vistas, los cubos OLAP, y los sistemas transaccionales tales como "write-ahead logging" o el control de concurrencia mediante versiones múltiples, todo esto afecta dramáticamente la organización física de cualquier sistema. Dicho esto, los sistemas RDBMS enfocados en procesamiento de transacciones en línea (OLTP) son más orientados a filas, mientras que los sistemas centrados en procesamiento analítico en línea (OLAP) son un equilibrio orientación a filas y a columnas.

## Beneficios

Las comparaciones entre bases de datos orientadas a filas y orientadas a columnas típicamente se enfocan en la eficiencia de acceso al disco duro para una carga de trabajo dada, ya que el tiempo de búsqueda es increíblemente largo comparado a los otros cuellos de botella en computadoras. Por ejemplo, un típico disco duro Serial ATA (SATA) tiene un tiempo de búsqueda promedio de entre 16 y 22 milisegundos, mientras que el acceso DRAM en un procesador Intel Core i7 toma en promedio 60 nanosegundos, casi 400,000 veces más rápido. Claramente, el acceso a disco es un cuello de botella importante en el manejo de grandes cantidades de datos. Las bases de datos columnares impulsan el rendimiento al reducir la cantidad de datos que necesitan ser leídos del disco, debido a que comprime eficientemente los datos columnares similares, y a que lee solo los datos necesarios para responder a una consulta.

En la práctica, las bases de datos columnares son muy convenientes para cargas de trabajo tipo OLAP (por ej., almacenes de datos) las cuales típicamente involucran consultas altamente complejas sobre todos los datos (posiblemente petabytes). Sin embargo, se requiere algo de trabajo para escribir datos en una base de datos columnar. Las transacciones (INSERT's) tienen que ser separadas en columnas y comprimidas cuando son almacenadas, haciéndolas menos convenientes para cargas de trabajo OLTP. Las bases de datos orientadas a filas son muy convenientes para cargas de trabajo tipo OLTP las cuales están mayoritariamente cargadas de transacciones interactivas. Por ejemplo, la recuperación de todos los datos de una única fila es más eficiente cuando esos datos están localizados en una única ubicación (minimizando búsquedas en disco), como lo es en arquitecturas orientadas a filas. Sin embargo, los sistemas orientados a columnas han sido desarrollados como híbridos capaces de ambas operaciones, OLTP y OLAP. Algunas de las restricciones OLTP, enfrentadas por los sistemas orientados a columnas, son mediadas utilizando (entre otras cualidades) almacenamiento de datos en memoria. Los sistemas orientados a columnas adecuados para roles OLAP y OLTP reducen de manera efectiva la huella de datos total al remover la necesidad de sistemas separados.

### Compresión

Los datos de las columnas son de un tipo uniforme; por tanto, hay algunas oportunidades disponibles para optimizaciones de tamaño de almacenamiento en estos datos que no están disponibles en datos orientados a filas. Por ejemplo, muchos esquemas modernos de compresión que son populares, tales como el LZW o la compresión RLE, hacen uso de la similitud de los datos adyacentes para comprimirlos; los valores faltantes y los valores repetidos, que son comunes en datos clínicos, pueden ser representados por un marcador de dos bits. Aunque estas mismas técnicas pueden ser utilizadas en datos orientados a filas, en una implementación típica se alcanzarán resultados menos efectivos.

Para mejorar la compresión, el ordenar filas también puede ayudar. Por ejemplo, utilizando índices bitmap, la ordenación puede mejorar la compresión en un orden de magnitud. Para maximizar los beneficios de la compresión del orden lexicográfico con respecto a la compresión RLE, es mejor usar columnas de baja cardinalidad como las primeras llaves de ordenación. Por ejemplo, dada una tabla con columnas sexo, edad, nombre, sería mejor ordenar primero respecto al valor sexo (cardinalidad de dos), luego por edad (cardinalidad <150), y luego por nombre.

La compresión columnar alcanza una reducción en espacio en disco a expensas de la eficiencia de recuperación. A mayor compresión adyacente alcanzada, mayor puede llegar a ser la dificultad de realizar accesos aleatorios, ya que los datos podrían necesitar ser descomprimidos para ser leídos. Por consiguiente, algunas veces las arquitecturas orientadas a columnas son enriquecidas con mecanismos adicionales que persiguen la minimización de la necesidad de acceder a datos comprimidos.

