varbitx は、標準 PostgreSQL varbit 拡張が提供する機能を拡張し、高度なビット列操作関数を追加する PolarDB for PostgreSQL 向け拡張です。リアルタイムのユーザープロファイルタグ付け、広告向けアクセスの制御、チケット販売システムなど、高性能なビット操作を必要とするシナリオでご利用ください。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
PostgreSQL 11 を実行中の PolarDB for PostgreSQL クラスター
拡張のインストール
CREATE EXTENSION varbitx;拡張を削除するには:
DROP EXTENSION varbitx;関数一覧
すべての関数は、標準 PostgreSQL varbit 値を引数として受け取り、同様の型を返します。ビット位置は 0 ベースのインデックスを使用します(左端のビットが位置 0)。
ビット抽出
| 関数 | 説明 | 例 |
|---|---|---|
get_bit(bits varbit, start int, count int) returns varbit | count ビット分を、位置 start から抽出して返します。 | get_bit('111110000011', 3, 5) → 11000 |
get_bit_array(bits varbit, start int, count int, value int) returns int[] | 位置 start から count ビット分を抽出し、その中で値が value(0 または 1)と等しいビットの位置を配列で返します。 | get_bit_array('111110000011', 3, 5, 1) → [3,4] |
get_bit_array(bits varbit, value int, positions int[]) returns int[] | 指定された positions の位置にあるビットのうち、値が value(0 または 1)と等しいものの位置を配列で返します。positions に含まれないビットは無視されます。 | get_bit_array('111110000011', 1, array[1,5,6,7,10,11]) → [1,10,11] |
ビット変更
| 関数 | 説明 | 例 |
|---|---|---|
set_bit_array(bits varbit, value int, fill int, positions int[]) returns varbit | 指定された positions の位置にあるビットを value(0 または 1)に設定します。必要に応じてビット列を拡張し、新規追加されるビットは fill(0 または 1)で埋められます。 | set_bit_array('111100001111', 0, 1, array[1,15]) → 1011000011111110 |
set_bit_array(bits varbit, value int, fill int, positions int[], limit int) returns varbit | 上記と同じ動作ですが、limit 個の位置処理後に終了します。 | set_bit_array('111100001111', 1, 0, array[4,5,6,7], 2) → 111111001111 |
set_bit_array_record(bits varbit, value int, fill int, positions int[]) returns (varbit, int[]) | 指定された positions の位置にあるビットを value(0 または 1)に設定し、必要に応じて fill でビット列を拡張したうえで、更新後のビット列および実際に変更された位置の配列を返します。 | set_bit_array_record('111100001111', 0, 1, array[1,15]) → 1011000011111110, [1,15] |
set_bit_array_record(bits varbit, value int, fill int, positions int[], limit int) returns (varbit, int[]) | 上記と同じ動作ですが、limit 個のビット変更後に終了します。更新後のビット列および実際に変更された位置の配列を返します。 | set_bit_array_record('111100001111', 1, 0, array[1,4,5,6,7], 2) → 111111001111, [4,5] |
ビット生成
| 関数 | 説明 | 例 |
|---|---|---|
bit_fill(value int, count int) returns varbit | count ビット分のビット列を生成し、すべてのビットを value(0 または 1)に設定して返します。 | bit_fill(0, 10) → 0000000000 |
bit_rand(count int, value int, ratio float) returns varbit | count ビット分のビット列を生成し、そのうち約 ratio の割合でビットを value(0 または 1)に設定します(ランダム分布)。 | bit_rand(10, 1, 0.3) の戻り値の例: 0101000001 |
ビット数カウント
| 関数 | 説明 | 例 |
|---|---|---|
bit_count(bits varbit, value int) returns int | value(0 または 1)と等しいビットの総数をカウントします。 | bit_count('1111000011110000', 1) → 8 |
bit_count(bits varbit, value int, start int, count int) returns int | 位置 start から count ビット分の範囲内で、value(0 または 1)と等しいビットをカウントします。ビット列の長さを超える位置はカウント対象外です。 | bit_count('1111000011110000', 1, 5, 4) → 1 |
bit_count_array(bits varbit, value int, positions int[]) returns int | 指定された positions の位置にあるビットのうち、value(0 または 1)と等しいものの個数をカウントします。 | bit_count_array('1111000011110000', 1, array[1,2,7,8]) → 3 |
位置検索
| 関数 | 説明 | 例 |
|---|---|---|
bit_posite(bits varbit, value int, ascending boolean) returns int[] | value(0 または 1)と等しいビットの位置をすべて配列で返します。true を指定すると昇順、false を指定すると降順で返されます。 | bit_posite('11110010011', 1, true) → [0,1,2,3,6,9,10];bit_posite('11110010011', 1, false) → [10,9,6,3,2,1,0] |
bit_posite(bits varbit, value int, limit int, ascending boolean) returns int[] | limit 個まで、value(0 または 1)と等しいビットの位置を配列で返します。true を指定すると昇順、false を指定すると降順で返されます。 | bit_posite('11110010011', 1, 3, true) → [0,1,2];bit_posite('11110010011', 1, 3, false) → [10,9,6] |
使用例
以下は、ユーザータグ付けシステムにおける典型的なワークフローの例です。まず varbit 型のカラムを持つテーブルを作成し、データを挿入して、varbitx 関数を用いてクエリを実行します。
varbit カラムを持つテーブルの作成
CREATE TABLE user_tags (
user_id integer,
tag_bits varbit
);varbit データの挿入
INSERT INTO user_tags VALUES (1, '1111000011110000');
INSERT INTO user_tags VALUES (2, '1011000011111110');
INSERT INTO user_tags VALUES (3, '0000111100001111');ユーザーごとの有効タグ数のカウント
各ユーザーについて、値が 1 に設定されたビット(有効なタグ)の数をカウントします。
SELECT user_id, bit_count(tag_bits, 1) AS active_tag_count
FROM user_tags;期待される出力:
user_id | active_tag_count
---------+------------------
1 | 8
2 | 10
3 | 8
(3 rows)タグ位置によるユーザーのフィルタリング
位置 0 のタグが有効(1)に設定されているユーザーを検索します。
SELECT user_id
FROM user_tags
WHERE get_bit(tag_bits, 0, 1) = B'1';特定のタグの有効化と変更内容の記録
set_bit_array_record 関数を用いて、指定された位置のタグを有効化し、実際に変更された位置を返すことができます。
SELECT user_id,
set_bit_array_record(tag_bits, 1, 0, array[1,4,5,6,7], 2)
FROM user_tags
WHERE user_id = 1;期待される出力:
user_id | set_bit_array_record
---------+----------------------
1 | (1111110011110000,"{4,5}")
(1 row)