読み取り可能なProtobuf機能がPolarDB for MySQLに追加されました。 データベースに格納されているProtobufシリアル化されたBLOBタイプのフィールドの場合、Protobufスキーマを設定し、PROTO_TO_JSON(blob_field)
関数を使用してデータを読み取ることができます。 JSON_EXTRACT()
関数を使用して、データから一部の情報を抽出し、インデックスまたは仮想列を作成することもできます。
背景情報
ゲーム業界では、一部のデータはProtobufを使用してシリアル化され、データベースのBLOBタイプのフィールドに書き込まれる前にzlibを使用して圧縮されます。 データベース内のBLOBタイプのデータは直接読み取ることができず、ソフトウェアのデバッグや開発には不便です。 データ分析シナリオでも、追加のコンポーネントを使用してデータを読み取る必要があります。
PolarDB for MySQLが提供する読み取り可能なProtobuf関数は、追加のコンポーネントを使用せずに、Protobufを使用してシリアル化され、zlibを使用して圧縮されたデータを直接読み取る視覚機能を提供します。
前提条件
PolarDBクラスターはPolarDB for MySQL 8.0で、バージョン8.0.2.2.5以降を使用しています。 クラスターバージョンを確認する方法の詳細については、「エンジンバージョンの照会」をご参照ください。
Usage
- Protobufスキーマの設定構文
パラメータALTER TABLE table_name ALTER COLUMN column_name [PROTO_NAME = protobuf_schema_name] PROTO_TEXT = protobuf_schema_definition PROTO_MESSAGE = protobuf_message [COMPRESSION = compression_algorithm]
パラメーター 必須 説明 PROTO_NAME 任意 Protobufスキーマの名前。 PROTO_TEXT 可 Protobufスキーマの定義。 PROTO_MESSAGE 可 Protobufシリアル化メッセージ。 圧縮 任意 このパラメーターは、Protobufシリアル化メッセージデータをzlibで圧縮してからデータベースに書き込む場合にのみ必要です。 値をzlibに設定します。 説明 Zlib圧縮データは、UNCOMPRESS()
関数を使用して16進データに解凍できます。 - フィールドのProtobufスキーマ定義の削除PROTO_TEXTパラメーターを空のままにして、フィールドのProtobufスキーマ定義を削除できます。 次のステートメントを実行します。
ALTER TABLE table_name ALTER COLUMN column_name PROTO_NAME="" PROTO_TEXT="PROTO_MESSAGE=";
説明 フィールドのProtobufスキーマ定義を削除する前に、フィールドがインデックスおよび仮想列から関連付けられていないことを確認します。 - フィールドのProtobufスキーマ定義の表示
- 次のステートメントを実行して、display_readable_proto_infoパラメーターをtrueに設定します。
set display_readable_proto_info=true;
- 次のステートメントを実行して、フィールドのProtobufスキーマ定義を表示します。
SHOW columns FROM table_name
- 次のステートメントを実行して、display_readable_proto_infoパラメーターをtrueに設定します。
例
次の例では、読み取り可能なProtobuf機能の使用方法と、
PROTO_TO_JSON(blob_field)
関数を使用してデータから情報を抽出し、インデックスまたは仮想列を作成する方法について説明します。 t1
テーブルは、実施例において使用される。 t1
という名前のテーブルを作成します。 次のステートメントを実行します。CREATE TABLE t1(c1 INT, c2 BLOB);
c2
フィールドはBLOB型であり、Protobufによってシリアル化されています。c2
フィールドのProtobufスキーマ定義を追加します。Protobufコミュニティのaddressbook.protoが使用されている例:syntax = "proto2"; パッケージチュートリアル; message Person { オプションの文字列名=1; オプションのint32 id = 2; オプションの文字列email = 3; enum PhoneType { モバイル=0; ホーム=1; WORK = 2; } メッセージPhoneNumber { オプションの文字列番号=1; オプションのPhoneTypeタイプ=2 [default = HOME]; } 繰り返されるPhoneNumber電話=4; } メッセージAddressBook { 繰り返し人の人々=1; }
- zlibを使用してデータを圧縮しない例:
ALTER TABLE t1 ALTER COLUMN c2 PROTO_NAME="AddressBook" PROTO_TEXT="syntax = \" proto2\";\n\npackage tutorial;\n\nmessage Person {\nオプションの文字列name = 1;\nオプションのint32 id = 2;\nオプションの文字列email = 3;\n\n enum PhoneType;\n WORK = 2;\n}\nメッセージPhoneNumber {\nオプションの文字列番号=1;\nオプションのPhoneType=2 [default = HOME];\n}\n \repeated PhoneNumber phones = 4;\n}\n\nmessage AddressBook {\n repeated Person people = 1;\n}" PROTO_MESSAGE='Address';
- zlibを使用してデータを圧縮する例:
ALTER TABLE t1 ALTER COLUMN c2 PROTO_NAME="AddressBook" PROTO_TEXT="syntax = \" proto2\";\n\npackage tutorial;\n\nmessage Person {\nオプションの文字列name = 1;\nオプションのint32 id = 2;\nオプションの文字列email = 3;\n\n enum PhoneType;\n WORK = 2;\n}\nメッセージPhoneNumber {\nオプションの文字列番号=1;\nオプションのPhoneType=2 [default = HOME];\n}
- zlibを使用してデータを圧縮しない例:
- Protobufを使用してシリアル化されたデータを
t1
テーブルに書き込みます。- zlibを使用してデータを圧縮しない例:
INSERT INTO t1 VALUES(1, X'0a380a0b56697375616c50726f746f10011a1776697375616c70726f746f40706f6c617264622e636f6d220e0a0a313233343536373839301002');
- zlibを使用してデータを圧縮する例:
Zlib圧縮データは、INSERT INTO t1 VALUES(1, X'3C000000785ee3b2e0e20ecb2c2e4dcc0928ca2fc9176094122f03730b405c8782fc9cc4a29424bde4fc5c253e2e2e432363135333730b4b03012600183d10de');
UNCOMPRESS()
関数を使用して解凍できます。 zlibを使用してデータを圧縮する例:
解凍された16進データのサンプル結果:SELECT HEX(uncompress(X'3C000000785ee3b2e0e20ecb2c2e4dcc0928ca2fc9176094122f03730b405c8782fc9cc4a29424bde4fc5c253e2e2e432363135333730b4b03012600183d10de')) AS UNCOMPRESS_DATA;
+ ---------------------------------------------------------------------------------------------------------------------- + | UNCOMPRESS_DATA | + ---------------------------------------------------------------------------------------------------------------------- + | 0A380A0B56697375616C50726F746F10011A1776697375616C70726F746F40706F6C617264622E636F6D220E0A0A313233343536373839301002 | + ---------------------------------------------------------------------------------------------------------------------- +
- zlibを使用してデータを圧縮しない例:
c2
列のデータを読み取るか、c2
列からデータを抽出して、インデックスまたは仮想列を作成します。c2
列のデータを読み取ります。PROTO_TO_JSON(blob_field)
関数を使用しない場合は、c2
列のデータを読み取ります。- zlibを使用してデータが圧縮されていない場合は、次のステートメントを実行して
c2
列からデータを読み取ります。
読み取りデータのサンプル結果:SELECT c2 from t1\G
*************************** 1。 行 *************************** c2: 8 VisualProtovisualproto@polardb.com" 1234567890
- zlibを使用してデータを圧縮する場合は、次の文を実行して
c2
列のデータを読み取ります。
読み取りデータのサンプル結果:SELECT c2 FROM t1\G
*************************** 1。 行 *************************** c2: < x ^ .jp .jp .jp,. M.M (FindHotel /Omegle ''' '/s @ \���� $$��� \%> .. C#cS3s K& =ː
- zlibを使用してデータが圧縮されていない場合は、次のステートメントを実行して
PROTO_TO_JSON(blob_field)
関数が使用されている場合、c2
列のデータを読み取ります。
読み取りデータのサンプル結果:SELECT PROTO_TO_JSON(c2) FROM t1;
+ ------------------------------------------------------------------------------------------------------------------------------------------ + | PROTO_TO_JSON(c2) | + ------------------------------------------------------------------------------------------------------------------------------------------ + | {"people": [{"id": 1, "name": "VisualProto", "email": "visualproto@polardb.com", "phones": [{"type": "WORK", "number": "1234567890"}]} | + ------------------------------------------------- ---------------------------------------------------------------------- +
説明PROTO_TO_JSON(blob_field)
関数は、zlibを使用して圧縮されたデータとzlibを使用して圧縮されていないデータの両方を読み取ることができます。- JSON関数を使用して、
c2
列のデータを抽出します。 例:
FROM t1; 抽出されたデータのサンプル結果:SELECT json_extract(PROTO_TO_JSON(c2), '$.people[0].name')
+ ----------------------------------------------------- + | json_extract(PROTO_TO_JSON(c2) 、'$.people[0].name') | + ----------------------------------------------------- + | "VisualProto" | + ----------------------------------------------------- +
c2
列のデータを抽出してインデックスを作成します。 例:
AS char(100)) EXPLAINステートメントを実行して、前述のSQLステートメントの実行パフォーマンスを確認します。 例:CREATE INDEX i_email ON t1((cast(JSON_UNQUOTE(json_extract(PROTO_TO_JSON(c2), '$.people[0].email'))));
サンプル結果:EXPLAIN SELECT * FROM t1 WHERE (cast (json_extract(PROTO_TO_JSON(c2)) 、$.people[0].ema
------------------------------------------------------------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | ---- ----------- ------------------------------------------------------------------------------------------------------------------- | 1 | SIMPLE | t1 | NULL | ref | i_email | i_email | 403 | const | 1 | 100.00 | NULL | ---- ----------- ------------------------------------------------------------------------------------------------------------------
c2
列のデータを抽出して、仮想列を作成します。 例:
次のステートメントを実行して、ALTER TABLE t1 ADD COLUMN c3 varchar(100) AS (json_extract(proto_to_json ('c'), _utf8mb4'$.people[0].email'));
t1
テーブル:
のサンプルスキーマdesc t1;
t1
テーブル:------- ------------- ------------------------------------- ------------------- + | フィールド | タイプ | ヌル | キー | デフォルト | エクストラ | ------- ------------- ------------------------------------- ------------------- + | c1 | int(11) | YES | | NULL | | | c2 | blob | YES | | NULL | | | c3 | varchar(100) | YES | | NULL | 仮想生成済み | ------- ------------- ------------------------------------- ------------------- +
c3
は新しく作成された仮想列です。