BITMAP es un tipo de dato que almacena un conjunto de enteros sin signo de 32 bits. Basado en el estándar RoaringBitmap, utiliza un formato de compresión con rotación automática para lograr un almacenamiento eficiente, una deduplicación precisa y operaciones de conjuntos sobre datos a gran escala. Su formato de serialización estandarizado permite la interoperabilidad a nivel binario con sistemas externos.
Solo Ververica Runtime (VVR) 11.5 y versiones posteriores de Realtime Compute for Apache Flink admiten el tipo de dato BITMAP y sus funciones relacionadas.
Límites
BITMAP solo admite el tipo INT (entero de 32 bits). Para almacenar otros tipos de datos:
BIGINT (entero de 64 bits): Cree un diccionario para asignar valores a INT según las características de los datos, o utilice particionamiento por cubos.
Tipos no enteros: Cree un diccionario para asignar valores a INT.
BITMAP comprime datos continuos y densos con mucha mayor eficacia que datos discretos y dispersos. Utilice la asignación de datos para mejorar la eficiencia de la compresión.
Cómo obtener un valor BITMAP
Existen tres formas de obtener un valor BITMAP, cada una adecuada para un escenario diferente:
|
Escenario |
Función a utilizar |
|
Agregar una columna de enteros durante el procesamiento de flujos |
|
|
Crear un bitmap a partir de un arreglo existente |
|
|
Deserializar un bitmap desde un sistema externo |
|
Guía de rendimiento para funciones de agregación
Al usar funciones de agregación BITMAP, habilite MiniBatch o utilice agregación por ventanas. Esto reduce la sobrecarga de acceso al estado y mejora significativamente el rendimiento.
Las funciones de agregación BITMAP ofrecen su mejor rendimiento con entradas Append-Only. El rendimiento se degrada notablemente con entradas Retraction.
Evite agregaciones GroupBy multinivel sobre BITMAPs.
Lista de funciones
Las funciones BITMAP se dividen en cuatro categorías: construcción de bitmaps, operaciones lógicas, información estadística y conversión de formato.
Funciones de agregación
Las funciones de agregación operan sobre filas dentro de un grupo.
|
SQL |
Table API |
Tipo de entrada |
Tipo de salida |
Descripción |
|
|
|
INT |
BITMAP |
Agrega enteros de 32 bits en un bitmap. |
|
|
|
BITMAP |
BITMAP |
Agrega la intersección (AND) de varios bitmaps. |
|
|
|
BITMAP |
BITMAP |
Agrega la unión (OR) de varios bitmaps. |
|
|
|
BITMAP |
BITMAP |
Agrega la operación OR exclusiva (XOR) de varios bitmaps. |
|
|
|
INT |
BIGINT |
Agrega enteros de 32 bits en un bitmap y devuelve su cardinalidad como un entero de 64 bits. |
|
|
|
BITMAP |
BIGINT |
Agrega la intersección (AND) de varios bitmaps y devuelve la cardinalidad. |
|
|
|
BITMAP |
BIGINT |
Agrega la unión (OR) de varios bitmaps y devuelve la cardinalidad. |
|
|
|
BITMAP |
BIGINT |
Agrega la operación OR exclusiva (XOR) de varios bitmaps y devuelve la cardinalidad. |
Optimización de cardinalidad: Cuando solo necesita el conteo —no el bitmap en sí— utilice BITMAP_XX_CARDINALITY_AGG() directamente en lugar de envolver BITMAP_CARDINALITY(BITMAP_XX_AGG()). Ambas opciones devuelven el mismo resultado, pero la forma directa evita materializar un bitmap intermedio y ofrece un mejor rendimiento.
-- Preferred: returns cardinality directly
SELECT BITMAP_OR_CARDINALITY_AGG(bitmap_col) FROM my_table;
-- Equivalent but less efficient: materializes the bitmap first
SELECT BITMAP_CARDINALITY(BITMAP_OR_AGG(bitmap_col)) FROM my_table;
Funciones escalares
Las funciones escalares operan sobre valores BITMAP individuales.
BITMAP_BUILD(array)
Crea un BITMAP a partir de un arreglo de enteros de 32 bits. Devuelve NULL si la entrada es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
|
|
Tipo de salida |
BITMAP |
SELECT BITMAP_TO_STRING(BITMAP_BUILD(ARRAY[1, 2, 3, 4, 5]));
-- Result: {1,2,3,4,5}
-- NULL input returns NULL
SELECT BITMAP_BUILD(NULL);
-- Result: NULL
BITMAP_CARDINALITY(bitmap)
Devuelve el número de elementos distintos en un bitmap como un entero de 64 bits. Los valores duplicados se cuentan una sola vez. Devuelve NULL si la entrada es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP |
|
Tipo de salida |
BIGINT |
SELECT BITMAP_CARDINALITY(BITMAP_BUILD(ARRAY[1, 2, 3, 3, 5]));
-- Result: 4 (3 appears twice but is counted once)
Consejo: En canalizaciones de agregación, utiliceBITMAP_XX_CARDINALITY_AGG()directamente en lugar deBITMAP_CARDINALITY(BITMAP_XX_AGG())para obtener un mejor rendimiento.
BITMAP_AND(bitmap1, bitmap2)
Devuelve la intersección (AND) de dos bitmaps, es decir, los elementos presentes en ambos. Devuelve NULL si alguna de las entradas es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP, BITMAP |
|
Tipo de salida |
BITMAP |
-- Normal case
SELECT BITMAP_TO_STRING(
BITMAP_AND(BITMAP_BUILD(ARRAY[1, 2, 3]), BITMAP_BUILD(ARRAY[2, 3, 4]))
);
-- Result: {2,3}
-- NULL input returns NULL
SELECT BITMAP_TO_STRING(
BITMAP_AND(BITMAP_BUILD(ARRAY[1, 2, 3]), NULL)
);
-- Result: NULL
BITMAP_OR(bitmap1, bitmap2)
Devuelve la unión (OR) de dos bitmaps, es decir, todos los elementos distintos de ambos. Devuelve NULL si alguna de las entradas es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP, BITMAP |
|
Tipo de salida |
BITMAP |
-- Normal case
SELECT BITMAP_TO_STRING(
BITMAP_OR(BITMAP_BUILD(ARRAY[1, 2, 3]), BITMAP_BUILD(ARRAY[3, 4, 5]))
);
-- Result: {1,2,3,4,5}
-- NULL input returns NULL
SELECT BITMAP_TO_STRING(
BITMAP_OR(BITMAP_BUILD(ARRAY[1, 2, 3]), NULL)
);
-- Result: NULL
BITMAP_XOR(bitmap1, bitmap2)
Devuelve la operación OR exclusiva (XOR) de dos bitmaps, es decir, los elementos que están en cualquiera de los dos bitmaps pero no en ambos. Devuelve NULL si alguna de las entradas es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP, BITMAP |
|
Tipo de salida |
BITMAP |
SELECT BITMAP_TO_STRING(
BITMAP_XOR(BITMAP_BUILD(ARRAY[1, 2, 3]), BITMAP_BUILD(ARRAY[2, 3, 4]))
);
-- Result: {1,4}
BITMAP_ANDNOT(bitmap1, bitmap2)
Devuelve la diferencia (AND NOT) de dos bitmaps, es decir, los elementos en bitmap1 que no están en bitmap2. Devuelve NULL si alguna de las entradas es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP, BITMAP |
|
Tipo de salida |
BITMAP |
SELECT BITMAP_TO_STRING(
BITMAP_ANDNOT(BITMAP_BUILD(ARRAY[1, 2, 3]), BITMAP_BUILD(ARRAY[2, 3, 4]))
);
-- Result: {1}
BITMAP_FROM_BYTES(bytes)
Deserializa un arreglo de bytes en un BITMAP. El arreglo de bytes debe seguir la especificación de formato RoaringBitmap de 32 bits. Utilice esta función para importar bitmaps generados por sistemas externos. Devuelve NULL si la entrada es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BYTES |
|
Tipo de salida |
BITMAP |
BITMAP_TO_BYTES(bitmap)
Serializa un BITMAP en un arreglo de bytes siguiendo la especificación de formato RoaringBitmap de 32 bits. Utilice esta función para exportar bitmaps a sistemas externos compatibles con RoaringBitmap. Devuelve NULL si la entrada es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP |
|
Tipo de salida |
BYTES |
BITMAP_TO_ARRAY(bitmap)
Convierte un BITMAP en un ARRAY<INT>. Los valores se ordenan mediante Integer.compareUnsigned. Devuelve NULL si la entrada es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP |
|
Tipo de salida |
|
SELECT BITMAP_TO_ARRAY(BITMAP_BUILD(ARRAY[3, 1, 2]));
-- Result: [1, 2, 3] (sorted by Integer.compareUnsigned)
BITMAP_TO_STRING(bitmap)
Convierte un BITMAP en una cadena separada por comas y encerrada entre llaves. Los valores se ordenan mediante Integer.compareUnsigned. Si la cadena resultante es demasiado larga, se trunca y termina con .... Devuelve NULL si la entrada es NULL.
|
**Table API** |
** |
|
Tipo de entrada |
BITMAP |
|
Tipo de salida |
STRING |
Ejemplos de salida:
|
Entrada |
Salida |
|
Bitmap vacío |
|
|
|
|
|
Bitmap que contiene los equivalentes sin signo de -2 y -1 |
|
|
Bitmap con muchos elementos |
|
BITMAP almacena enteros sin signo de 32 bits. Los valores que aparecen como negativos cuando se interpretan como enteros con signo de 32 bits (como -1 y -2) se representan con sus equivalentes sin signo (4294967295 y 4294967294) en la salida.
Almacenamiento de datos no INT en BITMAP
Dado que BITMAP solo acepta INT (enteros de 32 bits), utilice los siguientes patrones para manejar otros tipos de datos:
|
Tipo de dato |
Enfoque |
|
BIGINT (64 bits) |
Construya un diccionario que asigne cada valor BIGINT a un INT único, o particione los datos en cubos dentro del rango de INT. |
|
Cadena u otros tipos no enteros |
Construya un diccionario que asigne cada valor distinto a un INT único. |
Para rangos de enteros continuos y densos (como IDs de usuario secuenciales), la compresión BITMAP es muy eficaz. Para datos dispersos o no secuenciales, la asignación mediante diccionarios mejora la eficiencia de la compresión.