All Products
Search
Document Center

AnalyticDB:Fungsi segmentasi pengguna (Roaring Bitmap)

Last Updated:May 14, 2026

Roaring Bitmap adalah format bitmap terkompresi yang dioptimalkan untuk operasi himpunan berkinerja tinggi. Gunakan fitur ini di AnalyticDB for MySQL untuk deduplikasi, penyaringan pengguna berbasis tag, dan perhitungan time-series pada set data besar.

Kapan menggunakan Roaring Bitmap

Roaring Bitmap mengungguli kueri COUNT(DISTINCT ...) standar ketika setiap kelompok dalam bitmap berisi kurang dari 100 juta entri. Untuk ruang UID yang lebih besar, tingkatkan jumlah kelompok secara proporsional (misalnya, ruang UID sebesar 10 miliar memerlukan minimal 100 kelompok).

Persyaratan versi

Jenis tabel Versi minimum
Tabel eksternal OSS 3.1.6.4
Tabel internal 3.2.1.0

Versi V3.2.8.0 dan yang lebih baru mendukung data BIGINT dalam Roaring Bitmap (memperluas rentang nilai hingga bilangan bulat 64-bit). Hubungi dukungan teknis untuk mengaktifkan kemampuan ini. Setelah diaktifkan, fungsi tertentu menerima input BIGINT dan tipe kembalian berubah dari INTEGER menjadi BIGINT. Untuk detailnya, lihat Fungsi.

Untuk melihat atau memperbarui versi kluster Anda, buka bagian Configuration Information pada halaman Cluster Information di Konsol AnalyticDB for MySQL.

Batasan

  • Tidak ada SELECT langsung pada kolom ROARINGBITMAP. Gunakan UNNEST untuk melihat elemen-elemennya:

    SELECT * FROM unnest(RB_BUILD(ARRAY[1,2,3]));
  • Kluster dengan versi sebelum V3.2.1.0 hanya mendukung ROARINGBITMAP pada tabel eksternal OSS. Untuk menggunakan operasi bitmap pada tabel internal di versi tersebut, simpan bitmap sebagai VARBINARY dan konversi saat kueri menggunakan RB_BUILD_VARBINARY:

    -- Definisikan tabel internal dengan VARBINARY
    CREATE TABLE test_rb_cstore (id INT, rb VARBINARY);
    
    -- Kueri menggunakan fungsi bitmap
    SELECT RB_CARDINALITY(RB_BUILD_VARBINARY(rb)) FROM test_rb_cstore;

Membuat Roaring Bitmap

Tiga fungsi membangun Roaring Bitmap, masing-masing untuk sumber input yang berbeda:

Fungsi Input Gunakan saat
RB_BUILD(array) Array integer Membangun bitmap dari array literal
RB_BUILD_AGG(integer) Integer (agregat) Mengagregasi integer tingkat baris ke dalam bitmap
RB_BUILD_VARBINARY(varbinary) VARBINARY Membaca bitmap yang disimpan sebagai VARBINARY dalam tabel internal

Fungsi

Fungsi skalar

Fungsi Tipe input Tipe output Deskripsi Contoh
RB_BUILD ARRAY(INT) atau ARRAY(BIGINT) ROARING BITMAP Membangun Roaring Bitmap dari array integer. RB_BUILD(ARRAY[1,2,3])
RB_BUILD_RANGE INT, INT atau BIGINT, BIGINT ROARING BITMAP Membangun Roaring Bitmap dari rentang: awal (inklusif) hingga akhir (eksklusif). RB_BUILD_RANGE(0, 10000)
RB_BUILD_VARBINARY VARBINARY ROARING BITMAP Membangun Roaring Bitmap dari data VARBINARY. RB_BUILD_VARBINARY(RB_TO_VARBINARY(RB_BUILD(ARRAY[1,2,3])))
RB_CARDINALITY ROARING BITMAP BIGINT Mengembalikan jumlah elemen dalam bitmap. RB_CARDINALITY(RB_BUILD(ARRAY[1,2,3]))
RB_CONTAINS ROARING BITMAP, INT atau ROARING BITMAP, BIGINT BOOLEAN Mengembalikan true jika bitmap berisi integer yang ditentukan. RB_CONTAINS(RB_BUILD(ARRAY[1,2,3]), 3)
RB_CONTAINS ROARING BITMAP, ROARING BITMAP BOOLEAN Mengembalikan true jika bitmap pertama berisi semua elemen bitmap kedua. RB_CONTAINS(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3]))
RB_AND ROARING BITMAP, ROARING BITMAP ROARING BITMAP Mengembalikan irisan (AND) dua bitmap. RB_AND(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4]))
RB_OR ROARING BITMAP, ROARING BITMAP ROARING BITMAP Mengembalikan gabungan (OR) dua bitmap. RB_OR(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4]))
RB_XOR ROARING BITMAP, ROARING BITMAP ROARING BITMAP Mengembalikan XOR eksklusif (XOR) dua bitmap. RB_XOR(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4]))
RB_AND_NULL2EMPTY ROARING BITMAP, ROARING BITMAP ROARING BITMAP Operasi AND dengan penanganan null-safe: jika salah satu input NULL, input lainnya digunakan; jika salah satu input {}, hasilnya {}. RB_AND_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_OR_NULL2EMPTY ROARING BITMAP, ROARING BITMAP ROARING BITMAP Operasi OR dengan penanganan null-safe: input NULL diperlakukan sebagai {}. RB_OR_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_ANDNOT_NULL2EMPTY ROARING BITMAP, ROARING BITMAP ROARING BITMAP Operasi ANDNOT dengan penanganan null-safe: input NULL diperlakukan sebagai {}. RB_ANDNOT_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_AND_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Mengembalikan kardinalitas hasil 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 Mengembalikan kardinalitas hasil AND; input NULL diperlakukan sebagai {}. RB_AND_NULL2EMPTY_CARDINALITY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_OR_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Mengembalikan kardinalitas hasil 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 Mengembalikan kardinalitas hasil OR; input NULL diperlakukan sebagai {}. RB_OR_NULL2EMPTY_CARDINALITY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5]))
RB_XOR_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Mengembalikan kardinalitas hasil XOR. RB_XOR_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_ANDNOT_CARDINALITY ROARING BITMAP, ROARING BITMAP BIGINT Mengembalikan kardinalitas hasil 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 Mengembalikan kardinalitas hasil ANDNOT; input NULL diperlakukan sebagai {}. RB_ANDNOT_NULL2EMPTY_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5]))
RB_IS_EMPTY ROARING BITMAP BOOLEAN Mengembalikan true jika bitmap kosong. RB_IS_EMPTY(RB_BUILD(ARRAY[]))
RB_CLEAR ROARING BITMAP, BIGINT, BIGINT ROARING BITMAP Menghapus elemen dalam rentang yang ditentukan: awal (inklusif) hingga akhir (eksklusif). RB_CLEAR(RB_BUILD('{1,2,3}'), 2, 3)
RB_FLIP ROARING BITMAP, INT, INT atau ROARING BITMAP, BIGINT, BIGINT ROARING BITMAP Membalik bit dalam rentang offset yang ditentukan. RB_FLIP(RB_BUILD(ARRAY[1,2,3,4,5]), 2, 5)
RB_MINIMUM ROARING BITMAP INT atau BIGINT Mengembalikan elemen terkecil. Mengembalikan error jika bitmap kosong. RB_MINIMUM(RB_BUILD(ARRAY[1,2,3]))
RB_MAXIMUM ROARING BITMAP INT atau BIGINT Mengembalikan elemen terbesar. Mengembalikan error jika bitmap kosong. RB_MAXIMUM(RB_BUILD(ARRAY[1,2,3]))
RB_RANK ROARING BITMAP, INT atau ROARING BITMAP, BIGINT BIGINT Mengembalikan jumlah elemen yang kurang dari atau sama dengan offset yang ditentukan. RB_RANK(RB_BUILD(ARRAY[1,2,3]), 2)
RB_TO_ARRAY ROARING BITMAP ARRAY(INT) Mengembalikan elemen sebagai array INT. RB_TO_ARRAY(RB_BUILD(ARRAY[1,2,3]))
RB_TO_LONG_ARRAY ROARING BITMAP ARRAY(BIGINT) Mengembalikan elemen sebagai array BIGINT. RB_TO_LONG_ARRAY(RB_BUILD(ARRAY[4,5,6]))
RB_TO_VARBINARY ROARING BITMAP VARBINARY Mengembalikan bitmap yang telah diserialisasi sebagai VARBINARY. RB_TO_VARBINARY(RB_BUILD(ARRAY[1,2,3]))
RB_RANGE_CARDINALITY ROARING BITMAP, INT, INT atau ROARING BITMAP, BIGINT, BIGINT BIGINT Mengembalikan kardinalitas untuk elemen pada posisi awal (inklusif) hingga akhir (eksklusif). Posisi dimulai dari 1. Memerlukan versi 3.1.10.0 atau lebih baru. RB_RANGE_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), 2, 3)
RB_SELECT ROARING BITMAP, BIGINT, BIGINT ROARING BITMAP Mengembalikan elemen pada posisi awal (inklusif) hingga akhir (eksklusif). Posisi dimulai dari 1. Memerlukan versi 3.1.10.0 atau lebih baru. RB_SELECT(RB_BUILD(ARRAY[1,3,4,5,7,9]), 2, 3)

Fungsi agregat

Fungsi Tipe input Tipe output Deskripsi Contoh
RB_BUILD_AGG INT atau BIGINT ROARING BITMAP Mengagregasi nilai integer dari beberapa baris ke dalam bitmap. RB_CARDINALITY(RB_BUILD_AGG(1))
RB_OR_AGG ROARING BITMAP ROARING BITMAP Melakukan agregasi OR pada beberapa bitmap. RB_CARDINALITY(RB_OR_AGG(RB_BUILD(ARRAY[1,2,3])))
RB_AND_AGG ROARING BITMAP ROARING BITMAP Melakukan agregasi AND pada beberapa bitmap. RB_CARDINALITY(RB_AND_AGG(RB_BUILD(ARRAY[1,2,3])))
RB_XOR_AGG ROARING BITMAP ROARING BITMAP Melakukan agregasi XOR pada beberapa bitmap. RB_CARDINALITY(RB_XOR_AGG(RB_BUILD(ARRAY[1,2,3])))
RB_OR_CARDINALITY_AGG ROARING BITMAP INT atau BIGINT Melakukan agregasi OR dan mengembalikan kardinalitasnya. RB_OR_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3]))
RB_AND_CARDINALITY_AGG ROARING BITMAP INT atau BIGINT Melakukan agregasi AND dan mengembalikan kardinalitasnya. RB_AND_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3]))
RB_XOR_CARDINALITY_AGG ROARING BITMAP INT atau BIGINT Melakukan agregasi XOR dan mengembalikan kardinalitasnya. RB_XOR_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3]))

Penggunaan dasar

Contoh berikut menunjukkan cara membuat tabel, memasukkan data bitmap, serta menjalankan kueri skalar dan agregat.

Tabel internal

  1. Buat tabel internal dengan kolom ROARINGBITMAP.

    CREATE TABLE `test_rb` (
      `id` INT,
      `rb` ROARINGBITMAP
    );
  2. Masukkan data bitmap.

    INSERT INTO test_rb VALUES (1, '[1, 2, 3]');
    INSERT INTO test_rb VALUES (2, '[2, 3, 4, 5, 6]');
  3. Dapatkan kardinalitas setiap baris.

    SELECT id, RB_CARDINALITY(rb) FROM test_rb;
    +------+--------------------+
    | id   | rb_cardinality(rb) |
    +------+--------------------+
    |    2 |                  5 |
    |    1 |                  3 |
    +------+--------------------+
  4. Dapatkan kardinalitas gabungan dari semua baris.

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

Tabel eksternal

  1. Buat tabel eksternal OSS dengan kolom 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"
    }';

    Untuk parameter tabel eksternal, lihat Tabel eksternal OSS non-partisi.

  2. Masukkan data bitmap.

    Penting

    INSERT INTO tidak efisien untuk penulisan skala besar. Untuk set data besar, hasilkan file Parquet menggunakan alat ETL dan unggah ke path OSS sebelum membuat tabel eksternal.

    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. Dapatkan kardinalitas setiap baris.

    SELECT id, RB_CARDINALITY(rb) FROM test_rb;
    +------+--------------------+
    | id   | rb_cardinality(rb) |
    +------+--------------------+
    |    2 |                  4 |
    |    1 |                  3 |
    +------+--------------------+
  4. Dapatkan kardinalitas gabungan dari semua baris.

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

Tutorial profil pengguna

Tutorial ini memandu alur kerja lengkap profil pengguna: membangun tabel tag dari data pengguna mentah, mengonversinya ke format bitmap untuk operasi himpunan efisien, dan menjalankan analisis multidimensi.

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

Langkah 1: Siapkan tabel tag sumber

  1. Buat tabel sumber users_base.

    CREATE TABLE users_base (
      uid  INT,
      tag1 STRING,  -- Nilai valid: x, y, z
      tag2 STRING,  -- Nilai valid: a, b
      tag3 INT      -- Nilai valid: 1 hingga 10
    );
  2. Hasilkan 100 juta baris data uji acak menggunakan cross join dua rentang bitmap (10.000 × 10.000 = 100.000.000 baris).

    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. Verifikasi data.

    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 |
    +--------+------+------+------+

Langkah 2: Tambahkan bidang pengelompokan

Operasi bitmap dalam mesin terdistribusi berjalan paralel di seluruh kelompok. Tambahkan bidang user_group untuk mempartisi UID ke dalam kelompok, dan bidang offset untuk mengkodekan posisi UID dalam setiap kelompok.

Contoh ini menggunakan 16 kelompok dengan rumus uid = 16 × offset + user_group:

  • user_group = uid % 16 — kelompok tempat UID berada

  • offset = uid / 16 — posisi UID dalam kelompok

Menentukan ukuran kelompok Anda: Setiap bitmap kelompok harus berisi kurang dari 100 juta entri. Untuk ruang UID sebesar 10 miliar, gunakan 100 kelompok masing-masing 100 juta. Sesuaikan jumlah kelompok berdasarkan ACU kluster dan total ruang UID Anda.

Catatan

Rumus pengelompokan di atas hanya untuk ilustrasi. Rancang fungsi pengelompokan Anda sendiri berdasarkan distribusi data Anda.

  1. Buat tabel users dengan bidang pengelompokan.

    CREATE TABLE users (
      uid        INT,
      tag1       STRING,
      tag2       STRING,
      tag3       INT,
      user_group INT,  -- Bidang pengelompokan: uid % 16
      offset     INT   -- Bidang offset: uid / 16
    );
  2. Isi users dari 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. Verifikasi data.

    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 |
    +---------+------+------+------+------------+--------+

Langkah 3: Bangun tabel tag bitmap

Untuk setiap dimensi tag, buat tabel tag bitmap tempat setiap baris menyimpan satu bitmap per pasangan (tag_value, user_group). Bitmap tersebut mengkodekan offset semua pengguna yang cocok dalam kelompok tersebut.

Tabel internal

  1. Buat dan isi tabel tag bitmap untuk 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. Verifikasi tabel tag.

    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. Buat dan isi tabel tag bitmap untuk 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. Verifikasi tabel tag.

    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 |
    +------+------------+--------------------+

Tabel eksternal

  1. Buat dan isi tabel tag bitmap untuk tag1 di 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. Verifikasi tabel tag.

    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. Buat dan isi tabel tag bitmap untuk tag2 di 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. Verifikasi tabel tag.

    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 |
    +------+------------+--------------------+

Langkah 4: Analisis dengan tabel tag bitmap

Skenario berikut menunjukkan pola analisis umum menggunakan tabel tag bitmap yang dibangun pada Langkah 3.

Skenario 1: Filter dan kelompokkan

Hitung jumlah pengguna dengan tag1 IN ('x', 'y'), dikelompokkan berdasarkan tag2.

Semua kueri mengikuti pola yang sama: gabungkan tabel tag bitmap berdasarkan user_group, terapkan operasi himpunan per kelompok, lalu agregasi di seluruh kelompok.

  1. Periksa hasil antara per kelompok.

    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. Jumlahkan hitungan per kelompok untuk mendapatkan total akhir.

    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 |
    +------+----------+

Skenario 2: Irisan antara dua tabel tag bitmap

Temukan pengguna dengan (tag1 = 'x' OR tag1 = 'y') DAN tag2 = 'b'.

Kedua input berasal dari tabel tag bitmap. Pertama, agregasi OR dalam setiap tabel tag, lalu AND-kan hasilnya di antara keduanya.

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 |
+------------+--------------------+

Skenario 3: Irisan antara tabel tag bitmap dan tabel sumber

Temukan pengguna dengan (tag1 = 'x' OR tag1 = 'y') DAN tag2 = 'b', dengan kondisi kedua difilter dari tabel users mentah, bukan dari tabel tag bitmap yang telah dibuat sebelumnya.

Gunakan RB_BUILD_AGG untuk membangun bitmap secara langsung dari tabel users, lalu AND-kan dengan bitmap yang telah dibuat sebelumnya dari 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 |
+------------+--------------------+

Skenario 4: Ekspor hasil bitmap ke OSS

Simpan hasil bitmap dari Skenario 2 ke tabel eksternal OSS untuk penggunaan downstream.

  1. Buat tabel output.

    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. Tulis hasil Skenario 2 ke 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;

    Setelah kueri selesai, hasilnya disimpan dalam format Parquet di oss://testBucketName/roaringbitmap/tag_tbl_3/.

Skenario 5: Percepat kueri dengan tabel cache internal (untuk tabel eksternal)

Impor data bitmap dari tabel eksternal OSS ke tabel internal untuk mempercepat kueri berulang. Karena tabel internal dengan versi sebelum V3.2.1.0 tidak mendukung tipe ROARINGBITMAP secara native, simpan bitmap sebagai VARBINARY dan konversi saat kueri.

  1. Buat tabel cache internal dengan kolom VARBINARY untuk bitmap.

    CREATE TABLE `tag_tbl_1_cstore` (
      `tag1`       VARCHAR,
      `rb`         VARBINARY,
      `user_group` INT
    );
  2. Impor dari tabel OSS, serialisasi setiap bitmap ke VARBINARY.

    INSERT INTO tag_tbl_1_cstore
    SELECT tag1, RB_TO_VARBINARY(rb), user_group
    FROM tag_tbl_1;
  3. Kueri tabel cache, deserialisasi VARBINARY kembali ke bitmap saat kueri.

    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 |
    +------+------------+---------------------------------------------------+