Tous les produits
Search
Centre de documentation

AnalyticDB:User segmentation functions (Roaring Bitmap)

Dernière mise à jour :Aug 10, 2026

Roaring Bitmap est un format de bitmap compressé optimisé pour les opérations ensemblistes haute performance. Utilisez-le dans AnalyticDB for MySQL pour la déduplication, le filtrage des utilisateurs basé sur des tags et les calculs de séries temporelles sur de grands volumes de données.

Quand utiliser Roaring Bitmap

Roaring Bitmap offre de meilleures performances que les requêtes standards COUNT(DISTINCT ...) lorsque chaque groupe du bitmap contient moins de 100 millions d'entrées. Pour les espaces d'UID plus vastes, augmentez le nombre de groupes en conséquence (par exemple, un espace d'UID de 10 milliards nécessite au moins 100 groupes).

Prérequis de version

Type de table Version minimale
Tables externes OSS 3.1.6.4
Tables internes 3.2.1.0

Les versions V3.2.8.0 et ultérieures prennent en charge les données BIGINT dans Roaring Bitmap (étendant la plage de valeurs aux entiers 64 bits). Contactez le support technique pour activer cette fonctionnalité. Une fois activée, les fonctions sélectionnées acceptent les entrées BIGINT et leur type de retour passe de INTEGER à BIGINT. Pour plus de détails, consultez la section Fonctions.

Pour afficher ou mettre à jour la version de votre cluster, accédez à la section Configuration Information de la page Cluster Information dans la console AnalyticDB for MySQL.

Limitations

  • Aucune opération SELECT directe sur les colonnes ROARINGBITMAP. Utilisez UNNEST pour afficher les éléments :

    SELECT * FROM unnest(RB_BUILD(ARRAY[1,2,3]));
  • Les clusters antérieurs à la version V3.2.1.0 ne prennent en charge ROARINGBITMAP que dans les tables externes OSS. Pour utiliser les opérations de bitmap sur les tables internes dans ces versions, stockez les bitmaps au format VARBINARY et convertissez-les lors de l'exécution de la requête à l'aide de RB_BUILD_VARBINARY :

    -- Define an internal table with VARBINARY
    CREATE TABLE test_rb_cstore (id INT, rb VARBINARY);
    
    -- Query using bitmap functions
    SELECT RB_CARDINALITY(RB_BUILD_VARBINARY(rb)) FROM test_rb_cstore;

Construire un Roaring Bitmap

Trois fonctions permettent de construire un Roaring Bitmap, chacune correspondant à une source d'entrée différente :

Fonction Entrée Cas d'utilisation
RB_BUILD(array) Tableau d'entiers Construction d'un bitmap à partir d'un tableau littéral
RB_BUILD_AGG(integer) Entier (agrégat) Agrégation d'entiers au niveau des lignes dans un bitmap
RB_BUILD_VARBINARY(varbinary) VARBINARY Lecture de bitmaps stockés au format VARBINARY dans des tables internes

Fonctions

Fonctions scalaires

Fonction Type d'entrée Type de sortie Description Exemple
RB_BUILD ARRAY(INT) ou ARRAY(BIGINT) ROARING BITMAP Construit un Roaring Bitmap à partir d'un tableau d'entiers. RB_BUILD(ARRAY[1,2,3])
RB_BUILD_RANGE INT, INT ou BIGINT, BIGINT ROARING BITMAP Construit un Roaring Bitmap à partir d'une plage : début (inclus) à fin (exclus). RB_BUILD_RANGE(0, 10000)
RB_BUILD_VARBINARY VARBINARY ROARING BITMAP Construit un Roaring Bitmap à partir de données VARBINARY. RB_BUILD_VARBINARY(RB_TO_VARBINARY(RB_BUILD(ARRAY[1,2,3])))
RB_CARDINALITY ROARING BITMAP BIGINT Renvoie le nombre d'éléments dans le bitmap. RB_CARDINALITY(RB_BUILD(ARRAY[1,2,3]))
RB_CONTAINS ROARING BITMAP, INT ou ROARING BITMAP, BIGINT BOOLEAN Renvoie true si le bitmap contient l'entier spécifié. RB_CONTAINS(RB_BUILD(ARRAY[1,2,3]), 3)
RB_CONTAINS ROARING BITMAP, ROARING BITMAP BOOLEAN Renvoie true si le premier bitmap contient tous les éléments du second. RB_CONTAINS(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3]))
RB_AND ROARING BITMAP, ROARING BITMAP ROARING BITMAP Renvoie l'intersection (AND) de deux bitmaps. RB_AND(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4]))
RB_OR ROARING BITMAP, ROARING BITMAP ROARING BITMAP Renvoie l'union (OR) de deux bitmaps. RB_OR(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4]))
RB_XOR ROARING BITMAP, ROARING BITMAP ROARING BITMAP Renvoie le OU exclusif (XOR) de deux bitmaps. RB_XOR(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4]))
RB_AND_NULL2EMPTY ROARING BITMAP, ROARING BITMAP ROARING BITMAP Opération AND avec gestion sécurisée des valeurs nulles : si une entrée est NULL, l'autre est utilisée ; si une entrée est {}, le résultat est {}. RB_AND_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_OR_NULL2EMPTY ROARING BITMAP, ROARING BITMAP ROARING BITMAP Opération OR avec gestion sécurisée des valeurs nulles : les entrées NULL sont traitées comme {}. RB_OR_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_ANDNOT_NULL2EMPTY ROARING BITMAP, ROARING BITMAP ROARING BITMAP Opération ANDNOT avec gestion sécurisée des valeurs nulles : les entrées NULL sont traitées comme {}. RB_ANDNOT_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_AND_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat AND. RB_AND_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_AND_NULL2EMPTY_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat AND ; les entrées NULL sont traitées comme {}. RB_AND_NULL2EMPTY_CARDINALITY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_OR_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat OR. RB_OR_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_OR_NULL2EMPTY_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat OR ; les entrées NULL sont traitées comme {}. RB_OR_NULL2EMPTY_CARDINALITY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_XOR_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat XOR. RB_XOR_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_ANDNOT_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat ANDNOT. RB_ANDNOT_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_ANDNOT_NULL2EMPTY_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Renvoie la cardinalité du résultat ANDNOT ; les entrées NULL sont traitées comme {}. RB_ANDNOT_NULL2EMPTY_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_IS_EMPTY ROARING BITMAP BOOLEAN Renvoie true si le bitmap est vide. RB_IS_EMPTY(RB_BUILD(ARRAY[]))
RB_CLEAR ROARING BITMAP, BIGINT, BIGINT ROARING BITMAP Supprime les éléments dans la plage spécifiée : début (inclus) à fin (exclus). RB_CLEAR(RB_BUILD('{1,2,3}'), 2, 3)
RB_FLIP ROARING BITMAP, INT, INT ou ROARING BITMAP, BIGINT, BIGINT ROARING BITMAP Inverse les bits dans la plage de décalage spécifiée. RB_FLIP(RB_BUILD(ARRAY[1,2,3,4,5]), 2, 5)
RB_MINIMUM ROARING BITMAP INT ou BIGINT Renvoie le plus petit élément. Renvoie une erreur si le bitmap est vide. RB_MINIMUM(RB_BUILD(ARRAY[1,2,3]))
RB_MAXIMUM ROARING BITMAP INT ou BIGINT Renvoie le plus grand élément. Renvoie une erreur si le bitmap est vide. RB_MAXIMUM(RB_BUILD(ARRAY[1,2,3]))
RB_RANK ROARING BITMAP, INT ou ROARING BITMAP, BIGINT BIGINT Renvoie le nombre d'éléments inférieurs ou égaux au décalage spécifié. RB_RANK(RB_BUILD(ARRAY[1,2,3]), 2)
RB_TO_ARRAY ROARING BITMAP ARRAY(INT) Renvoie les éléments sous forme de tableau INT. RB_TO_ARRAY(RB_BUILD(ARRAY[1,2,3]))
RB_TO_LONG_ARRAY ROARING BITMAP ARRAY(BIGINT) Renvoie les éléments sous forme de tableau BIGINT. RB_TO_LONG_ARRAY(RB_BUILD(ARRAY[4,5,6]))
RB_TO_VARBINARY ROARING BITMAP VARBINARY Renvoie le bitmap sérialisé au format VARBINARY. RB_TO_VARBINARY(RB_BUILD(ARRAY[1,2,3]))
RB_RANGE_CARDINALITY ROARING BITMAP, INT, INT ou ROARING BITMAP, BIGINT, BIGINT BIGINT Renvoie la cardinalité des éléments aux positions début (inclus) à fin (exclus). La position est basée sur 1. Nécessite la version 3.1.10.0 ou ultérieure. RB_RANGE_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), 2, 3)
RB_SELECT ROARING BITMAP, BIGINT, BIGINT ROARING BITMAP Renvoie les éléments aux positions début (inclus) à fin (exclus). La position est basée sur 1. Nécessite la version 3.1.10.0 ou ultérieure. RB_SELECT(RB_BUILD(ARRAY[1,3,4,5,7,9]), 2, 3)

Fonctions d'agrégation

Fonction Type d'entrée Type de sortie Description Exemple
RB_BUILD_AGG INT ou BIGINT ROARING BITMAP Agrège les valeurs entières de plusieurs lignes dans un bitmap. RB_CARDINALITY(RB_BUILD_AGG(1))
RB_OR_AGG ROARING BITMAP ROARING BITMAP Effectue une agrégation OR sur plusieurs bitmaps. RB_CARDINALITY(RB_OR_AGG(RB_BUILD(ARRAY[1,2,3])))
RB_AND_AGG ROARING BITMAP ROARING BITMAP Effectue une agrégation AND sur plusieurs bitmaps. RB_CARDINALITY(RB_AND_AGG(RB_BUILD(ARRAY[1,2,3])))
RB_XOR_AGG ROARING BITMAP ROARING BITMAP Effectue une agrégation XOR sur plusieurs bitmaps. RB_CARDINALITY(RB_XOR_AGG(RB_BUILD(ARRAY[1,2,3])))
RB_OR_CARDINALITY_AGG ROARING BITMAP INT ou BIGINT Effectue une agrégation OR et renvoie la cardinalité. RB_OR_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3]))
RB_AND_CARDINALITY_AGG ROARING BITMAP INT ou BIGINT Effectue une agrégation AND et renvoie la cardinalité. RB_AND_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3]))
RB_XOR_CARDINALITY_AGG ROARING BITMAP INT ou BIGINT Effectue une agrégation XOR et renvoie la cardinalité. RB_XOR_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3]))

Utilisation de base

Ces exemples montrent comment créer une table, insérer des données de bitmap et exécuter des requêtes scalaires et d'agrégation.

Table interne

  1. Créez une table interne avec une colonne ROARINGBITMAP.

    CREATE TABLE `test_rb` (
      `id` INT,
      `rb` ROARINGBITMAP
    );
  2. Insérez des données de bitmap.

    INSERT INTO test_rb VALUES (1, '[1, 2, 3]');
    INSERT INTO test_rb VALUES (2, '[2, 3, 4, 5, 6]');
  3. Obtenez la cardinalité de chaque ligne.

    SELECT id, RB_CARDINALITY(rb) FROM test_rb;
    +------+--------------------+
    | id   | rb_cardinality(rb) |
    +------+--------------------+
    |    2 |                  5 |
    |    1 |                  3 |
    +------+--------------------+
  4. Obtenez la cardinalité de l'union sur toutes les lignes.

    SELECT RB_OR_CARDINALITY_AGG(rb) FROM test_rb;
    +---------------------------+
    | rb_or_cardinality_agg(rb) |
    +---------------------------+
    |                         6 |
    +---------------------------+

Table externe

  1. Créez une table externe OSS avec une colonne ROARINGBITMAP.

    CREATE TABLE `test_rb` (
      `id` INT,
      `rb` ROARINGBITMAP
    ) engine = 'oss'
    TABLE_PROPERTIES = '{
      "endpoint": "oss-cn-zhangjiakou.aliyuncs.com",
      "accessid": "************",
      "accesskey": "************",
      "url": "oss://testBucketName/roaringbitmap/test_for_user/",
      "format": "parquet"
    }';

    Pour connaître les paramètres des tables externes, consultez la rubrique Table externe OSS non partitionnée.

  2. Insérez des données de bitmap.

    Important

    L'instruction INSERT INTO est inefficace pour les écritures à grande échelle. Pour les grands ensembles de données, générez des fichiers Parquet à l'aide d'un outil ETL et téléchargez-les sur le chemin OSS avant de créer la table externe.

    INSERT INTO test_rb SELECT 1, rb_build(ARRAY[1,2,3]);
    INSERT INTO test_rb SELECT 2, rb_build(ARRAY[2,3,4,5]);
  3. Obtenez la cardinalité de chaque ligne.

    SELECT id, RB_CARDINALITY(rb) FROM test_rb;
    +------+--------------------+
    | id   | rb_cardinality(rb) |
    +------+--------------------+
    |    2 |                  4 |
    |    1 |                  3 |
    +------+--------------------+
  4. Obtenez la cardinalité de l'union sur toutes les lignes.

    SELECT RB_OR_CARDINALITY_AGG(rb) FROM test_rb;
    +---------------------------+
    | rb_or_cardinality_agg(rb) |
    +---------------------------+
    |                         5 |
    +---------------------------+

Tutoriel de profilage des utilisateurs

Ce tutoriel détaille un flux de travail complet de profilage des utilisateurs : création d'une table de tags à partir des données brutes des utilisateurs, conversion au format bitmap pour des opérations ensemblistes efficaces et exécution d'analyses multidimensionnelles.

Workflow overview: original label table converted to Roaring Bitmap label table for computations

Étape 1 : Préparer la table de tags source

  1. Créez la table source users_base.

    CREATE TABLE users_base (
      uid  INT,
      tag1 STRING,  -- Valid values: x, y, z
      tag2 STRING,  -- Valid values: a, b
      tag3 INT      -- Valid values: 1 to 10
    );
  2. Générez 100 millions de lignes de données de test aléatoires à l'aide d'une jointure croisée de deux plages de bitmap (10 000 × 10 000 = 100 000 000 lignes).

    SUBMIT JOB
    INSERT OVERWRITE users_base
    SELECT
      CAST(ROW_NUMBER() OVER (ORDER BY c1) AS INT) AS uid,
      SUBSTRING('xyz', FLOOR(RAND() * 3) + 1, 1) AS tag1,
      SUBSTRING('ab',  FLOOR(RAND() * 2) + 1, 1) AS tag2,
      CAST(FLOOR(RAND() * 10) + 1 AS INT)         AS tag3
    FROM (
      SELECT A.c1 FROM
        UNNEST(RB_BUILD_RANGE(0, 10000)) AS A(c1)
        JOIN (SELECT c1 FROM UNNEST(RB_BUILD_RANGE(0, 10000)) AS B(c1))
    );
  3. Vérifiez les données.

    SELECT * FROM users_base LIMIT 10;
    +--------+------+------+------+
    | uid    | tag1 | tag2 | tag3 |
    +--------+------+------+------+
    |  74526 | y    | b    |    3 |
    |  75611 | z    | b    |   10 |
    |  80850 | x    | b    |    5 |
    |  81656 | z    | b    |    7 |
    | 163845 | x    | b    |    2 |
    | 167007 | y    | b    |    4 |
    | 170541 | y    | b    |    9 |
    | 213108 | x    | a    |   10 |
    |  66056 | y    | b    |    4 |
    |  67761 | z    | a    |    2 |
    +--------+------+------+------+

Étape 2 : Ajouter des champs de regroupement

Les opérations de bitmap dans un moteur distribué s'exécutent en parallèle sur les groupes. Ajoutez un champ user_group pour partitionner les UID entre les groupes, ainsi qu'un champ offset pour encoder la position de l'UID au sein de chaque groupe.

Cet exemple utilise 16 groupes avec la formule uid = 16 × offset + user_group :

  • user_group = uid % 16 — le groupe auquel appartient l'UID

  • offset = uid / 16 — la position de l'UID au sein du groupe

Dimensionnement de vos groupes : Chaque bitmap de groupe doit contenir moins de 100 millions d'entrées. Pour un espace d'UID de 10 milliards, utilisez 100 groupes de 100 millions chacun. Ajustez le nombre de groupes en fonction des ACU de votre cluster et de l'espace total des UID.

Remarque

La formule de regroupement ci-dessus est fournie à titre illustratif uniquement. Concevez votre propre fonction de regroupement en fonction de la distribution de vos données.

  1. Créez la table users avec les champs de regroupement.

    CREATE TABLE users (
      uid        INT,
      tag1       STRING,
      tag2       STRING,
      tag3       INT,
      user_group INT,  -- Grouping field: uid % 16
      offset     INT   -- Offset field: uid / 16
    );
  2. Remplissez la table users à partir de la table users_base.

    SUBMIT JOB INSERT OVERWRITE users
    SELECT
      uid, tag1, tag2, tag3,
      CAST(uid % 16 AS INT),
      CAST(FLOOR(uid / 16) AS INT)
    FROM users_base;
  3. Vérifiez les données.

    SELECT * FROM users LIMIT 10;
    +---------+------+------+------+------------+--------+
    | uid     | tag1 | tag2 | tag3 | user_group | offset |
    +---------+------+------+------+------------+--------+
    |  377194 | z    | b    |   10 |         10 |  23574 |
    |  309440 | x    | a    |    1 |          0 |  19340 |
    |  601745 | z    | a    |    7 |          1 |  37609 |
    |  753751 | z    | b    |    3 |          7 |  47109 |
    |  988186 | y    | a    |   10 |         10 |  61761 |
    |  883822 | x    | a    |    9 |         14 |  55238 |
    |  325065 | x    | b    |    6 |          9 |  20316 |
    | 1042875 | z    | a    |   10 |         11 |  65179 |
    |  928606 | y    | b    |    5 |         14 |  58037 |
    |  990858 | z    | a    |    8 |         10 |  61928 |
    +---------+------+------+------+------------+--------+

Étape 3 : Créer des tables de tags bitmap

Pour chaque dimension de tag, créez une table de tags bitmap où chaque ligne stocke un bitmap par paire (tag_value, user_group). Le bitmap encode les décalages de tous les utilisateurs correspondants dans ce groupe.

Table interne

  1. Créez et remplissez la table de tags bitmap pour tag1.

    CREATE TABLE `tag_tbl_1` (
      `tag1`       STRING,
      `rb`         ROARINGBITMAP,
      `user_group` INT
    );
    
    INSERT OVERWRITE tag_tbl_1
    SELECT tag1, RB_BUILD_AGG(offset), user_group
    FROM users
    GROUP BY tag1, user_group;
  2. Vérifiez la table de tags.

    SELECT tag1, user_group, RB_CARDINALITY(rb) FROM tag_tbl_1;
    +------+------------+--------------------+
    | tag1 | user_group | rb_cardinality(rb) |
    +------+------------+--------------------+
    | y    |         13 |             563654 |
    | x    |         11 |             565013 |
    | z    |          2 |             564428 |
    | x    |          4 |             564377 |
    ...
    | z    |          5 |             564333 |
    | x    |          8 |             564808 |
    | x    |          0 |             564228 |
    | y    |          3 |             563325 |
    +------+------------+--------------------+
  3. Créez et remplissez la table de tags bitmap pour tag2.

    CREATE TABLE `tag_tbl_2` (
      `tag2`       STRING,
      `rb`         ROARINGBITMAP,
      `user_group` INT
    );
    
    INSERT OVERWRITE tag_tbl_2
    SELECT tag2, RB_BUILD_AGG(offset), user_group
    FROM users
    GROUP BY tag2, user_group;
  4. Vérifiez la table de tags.

    SELECT tag2, user_group, RB_CARDINALITY(rb) FROM tag_tbl_2;
    +------+------------+--------------------+
    | tag2 | user_group | rb_cardinality(rb) |
    +------+------------+--------------------+
    | a    |          9 |            3123039 |
    | a    |          5 |            3123973 |
    | a    |         12 |            3122414 |
    | a    |          7 |            3127218 |
    | a    |         15 |            3125403 |
    ...
    | a    |         10 |            3122698 |
    | b    |          4 |            3126091 |
    | b    |          3 |            3124626 |
    | b    |          9 |            3126961 |
    | b    |         14 |            3125351 |
    +------+------------+--------------------+

Table externe

  1. Créez et remplissez la table de tags bitmap pour tag1 dans OSS.

    CREATE TABLE `tag_tbl_1` (
      `tag1`       STRING,
      `rb`         ROARINGBITMAP,
      `user_group` INT
    ) engine = 'oss'
    TABLE_PROPERTIES = '{
      "endpoint":  "oss-cn-zhangjiakou.aliyuncs.com",
      "accessid":  "************",
      "accesskey": "************",
      "url":       "oss://testBucketName/roaringbitmap/tag_tbl_1/",
      "format":    "parquet"
    }';
    
    INSERT OVERWRITE tag_tbl_1
    SELECT tag1, RB_BUILD_AGG(offset), user_group
    FROM users
    GROUP BY tag1, user_group;
  2. Vérifiez la table de tags.

    SELECT tag1, user_group, RB_CARDINALITY(rb) FROM tag_tbl_1;
    +------+------------+--------------------+
    | tag1 | user_group | rb_cardinality(rb) |
    +------+------------+--------------------+
    | z    |          7 |            2082608 |
    | x    |         10 |            2082953 |
    | y    |          7 |            2084730 |
    | x    |         14 |            2084856 |
    ...
    | z    |         15 |            2084535 |
    | z    |          5 |            2083204 |
    | x    |         11 |            2085239 |
    | z    |          1 |            2084879 |
    +------+------------+--------------------+
  3. Créez et remplissez la table de tags bitmap pour tag2 dans OSS.

    CREATE TABLE `tag_tbl_2` (
      `tag2`       STRING,
      `rb`         ROARINGBITMAP,
      `user_group` INT
    ) engine = 'oss'
    TABLE_PROPERTIES = '{
      "endpoint":  "oss-cn-zhangjiakou.aliyuncs.com",
      "accessid":  "************",
      "accesskey": "************",
      "url":       "oss://testBucketName/roaringbitmap/tag_tbl_2/",
      "format":    "parquet"
    }';
    
    INSERT OVERWRITE tag_tbl_2
    SELECT tag2, RB_BUILD_AGG(offset), user_group
    FROM users
    GROUP BY tag2, user_group;
  4. Vérifiez la table de tags.

    SELECT tag2, user_group, RB_CARDINALITY(rb) FROM tag_tbl_2;
    +------+------------+--------------------+
    | tag2 | user_group | rb_cardinality(rb) |
    +------+------------+--------------------+
    | b    |         11 |            3121361 |
    | a    |          6 |            3124750 |
    | a    |          1 |            3125433 |
    ...
    | b    |          2 |            3126523 |
    | b    |         12 |            3123452 |
    | a    |          4 |            3126111 |
    | a    |         13 |            3123316 |
    | a    |          2 |            3123477 |
    +------+------------+--------------------+

Étape 4 : Analyser avec les tables de tags bitmap

Les scénarios suivants présentent des modèles d'analyse courants utilisant les tables de tags bitmap créées à l'étape 3.

Scénario 1 : Filtrer et regrouper

Comptez les utilisateurs où tag1 IN ('x', 'y'), regroupés par tag2.

Toutes les requêtes suivent le même schéma : joignez les tables de tags bitmap sur user_group, appliquez les opérations ensemblistes par groupe, puis agrégez les résultats sur tous les groupes.

  1. Inspectez les résultats intermédiaires par groupe.

    SELECT
      tag2,
      t1.user_group AS user_group,
      RB_CARDINALITY(RB_AND(t2.rb, rb1)) AS rb
    FROM tag_tbl_2 AS t2
    JOIN (
      SELECT user_group, rb AS rb1
      FROM tag_tbl_1
      WHERE tag1 IN ('x', 'y')
    ) AS t1 ON t1.user_group = t2.user_group;
    +------+------------+---------+
    | tag2 | user_group | rb      |
    +------+------------+---------+
    | b    |          3 | 1041828 |
    | a    |         15 | 1039859 |
    | a    |          9 | 1039140 |
    | b    |          1 | 1041524 |
    | a    |          4 | 1041599 |
    | b    |          1 | 1041381 |
    | b    |         10 | 1041026 |
    | b    |          6 | 1042289 |
    +------+------------+---------+
  2. Additionnez les comptes par groupe pour obtenir les totaux finaux.

    SELECT tag2, SUM(cnt) FROM (
      SELECT
        tag2,
        t1.user_group AS user_group,
        RB_CARDINALITY(RB_AND(t2.rb, rb1)) AS cnt
      FROM tag_tbl_2 AS t2
      JOIN (
        SELECT user_group, rb AS rb1
        FROM tag_tbl_1
        WHERE tag1 IN ('x', 'y')
      ) AS t1 ON t1.user_group = t2.user_group
    ) GROUP BY tag2;
    +------+----------+
    | tag2 | sum(cnt) |
    +------+----------+
    | a    | 33327868 |
    | b    | 33335220 |
    +------+----------+

Scénario 2 : Intersection entre deux tables de tags bitmap

Recherchez les utilisateurs où (tag1 = 'x' OR tag1 = 'y') AND tag2 = 'b'.

Les deux entrées proviennent de tables de tags bitmap. Effectuez d'abord une agrégation OR au sein de chaque table de tags, puis appliquez l'opération AND sur les résultats des deux tables.

SELECT user_group, RB_CARDINALITY(rb) FROM (
  SELECT
    t1.user_group AS user_group,
    RB_AND(rb1, rb2) AS rb
  FROM (
    SELECT user_group, RB_OR_AGG(rb) AS rb1
    FROM tag_tbl_1
    WHERE tag1 = 'x' OR tag1 = 'y'
    GROUP BY user_group
  ) AS t1
  JOIN (
    SELECT user_group, RB_OR_AGG(rb) AS rb2
    FROM tag_tbl_2
    WHERE tag2 = 'b'
    GROUP BY user_group
  ) AS t2 ON t1.user_group = t2.user_group
  GROUP BY user_group
);
+------------+--------------------+
| user_group | rb_cardinality(rb) |
+------------+--------------------+
|         10 |            2083679 |
|          3 |            2082370 |
|          9 |            2082847 |
|          2 |            2086511 |
...
|          1 |            2082291 |
|          4 |            2083290 |
|         14 |            2083581 |
|         15 |            2084110 |
+------------+--------------------+

Scénario 3 : Intersection entre une table de tags bitmap et la table source

Recherchez les utilisateurs où (tag1 = 'x' OR tag1 = 'y') AND tag2 = 'b', la seconde condition étant filtrée à partir de la table brute users plutôt que d'une table de tags bitmap préconstruite.

Utilisez RB_BUILD_AGG pour construire un bitmap à la volée à partir de la table users, puis appliquez l'opération AND avec le bitmap préconstruit de tag_tbl_1.

SELECT user_group, RB_CARDINALITY(rb) FROM (
  SELECT
    t1.user_group AS user_group,
    RB_AND(rb1, rb2) AS rb
  FROM (
    SELECT user_group, RB_OR_AGG(rb) AS rb1
    FROM tag_tbl_1
    WHERE tag1 = 'x' OR tag1 = 'y'
    GROUP BY user_group
  ) AS t1
  JOIN (
    SELECT user_group, RB_BUILD_AGG(offset) AS rb2
    FROM users
    WHERE tag2 = 'b'
    GROUP BY user_group
  ) AS t2 ON t1.user_group = t2.user_group
  GROUP BY user_group
);
+------------+--------------------+
| user_group | rb_cardinality(rb) |
+------------+--------------------+
|          3 |            2082370 |
|          1 |            2082291 |
|          0 |            2082383 |
|          4 |            2083290 |
|         11 |            2081662 |
|         13 |            2085280 |
...
|         14 |            2083581 |
|         15 |            2084110 |
|          9 |            2082847 |
|          8 |            2084860 |
|          5 |            2083056 |
|          7 |            2083275 |
+------------+--------------------+

Scénario 4 : Exporter les résultats bitmap vers OSS

Enregistrez les résultats bitmap du scénario 2 dans une table externe OSS pour une utilisation en aval.

  1. Créez la table de sortie.

    CREATE TABLE `tag_tbl_3` (
      `user_group` INT,
      `rb`         ROARINGBITMAP
    ) engine = 'oss'
    TABLE_PROPERTIES = '{
      "endpoint":  "oss-cn-zhangjiakou.aliyuncs.com",
      "accessid":  "************",
      "accesskey": "************",
      "url":       "oss://testBucketName/roaringbitmap/tag_tbl_3/",
      "format":    "parquet"
    }';
  2. Écrivez les résultats du scénario 2 dans tag_tbl_3.

    INSERT OVERWRITE tag_tbl_3
    SELECT
      t1.user_group AS user_group,
      RB_AND(rb1, rb2) AS rb
    FROM (
      SELECT user_group, RB_OR_AGG(rb) AS rb1
      FROM tag_tbl_1
      WHERE tag1 = 'x' OR tag1 = 'y'
      GROUP BY user_group
    ) AS t1
    JOIN (
      SELECT user_group, RB_OR_AGG(rb) AS rb2
      FROM tag_tbl_2
      WHERE tag2 = 'b'
      GROUP BY user_group
    ) AS t2 ON t1.user_group = t2.user_group;

    Une fois la requête terminée, le résultat est stocké au format Parquet à l'emplacement oss://testBucketName/roaringbitmap/tag_tbl_3/.

Scénario 5 : Accélérer les requêtes avec une table de cache interne (pour les tables externes)

Importez les données bitmap d'une table externe OSS dans une table interne pour accélérer les requêtes répétées. Étant donné que les tables internes antérieures à la version V3.2.1.0 ne prennent pas en charge nativement le type ROARINGBITMAP, stockez les bitmaps au format VARBINARY et convertissez-les lors de l'exécution de la requête.

  1. Créez la table de cache interne avec une colonne VARBINARY pour le bitmap.

    CREATE TABLE `tag_tbl_1_cstore` (
      `tag1`       VARCHAR,
      `rb`         VARBINARY,
      `user_group` INT
    );
  2. Importez depuis la table OSS en sérialisant chaque bitmap au format VARBINARY.

    INSERT INTO tag_tbl_1_cstore
    SELECT tag1, RB_TO_VARBINARY(rb), user_group
    FROM tag_tbl_1;
  3. Interrogez la table de cache en désérialisant le format VARBINARY vers des bitmaps lors de l'exécution de la requête.

    SELECT
      tag1,
      user_group,
      RB_CARDINALITY(RB_OR_AGG(RB_BUILD_VARBINARY(rb)))
    FROM tag_tbl_1_cstore
    GROUP BY tag1, user_group;
    +------+------------+---------------------------------------------------+
    | tag1 | user_group | rb_cardinality(rb_or_agg(rb_build_varbinary(rb))) |
    +------+------------+---------------------------------------------------+
    | y    |          3 |                                           2082919 |
    | x    |          9 |                                           2083085 |
    | x    |          3 |                                           2082140 |
    | y    |         11 |                                           2082268 |
    | z    |          4 |                                           2082451 |
    ...
    | z    |          2 |                                           2081560 |
    | y    |          6 |                                           2082194 |
    | z    |          7 |                                           2082608 |
    +------+------------+---------------------------------------------------+