Todos os produtos
Search
Central de documentação

PolarDB:Protobuf legível

Última atualização: Jun 28, 2026

Na indústria de jogos, o código da aplicação geralmente serializa dados usando Protobuf — às vezes com compressão zlib adicional — e os grava em colunas BLOB. Ler esses dados via SQL normalmente exige componentes externos de ETL ou desserialização na camada da aplicação, o que dificulta a depuração e o desenvolvimento de software. O recurso de Protobuf legível do PolarDB for MySQL elimina ambas as necessidades. Use a função PROTO_TO_JSON() para converter dados BLOB em JSON diretamente na consulta e utilize as funções JSON padrão do MySQL (JSON_EXTRACT(), JSON_UNQUOTE()) para filtrar, indexar ou criar colunas virtuais sobre esses dados — tudo em SQL.

Pré-requisitos

Antes de começar, verifique se você tem:

  • Um cluster PolarDB for MySQL 8.0 executando a versão de revisão 8.0.2.2.5 ou posterior. Para verificar sua versão, consulte Consultar a versão do mecanismo.

Como funciona

A função PROTO_TO_JSON(blob_field) recebe uma coluna BLOB com dados serializados em Protobuf e retorna uma string JSON. Ela processa automaticamente bytes Protobuf brutos e comprimidos com zlib, sem necessidade de alterar a consulta entre os dois casos.

Após converter os dados BLOB para JSON, use as funções JSON padrão do MySQL para consultar campos, criar índices ou gerar colunas virtuais sobre os dados Protobuf.

Configurar um schema Protobuf para uma coluna

Antes de chamar PROTO_TO_JSON(), associe um schema Protobuf à coluna BLOB usando ALTER TABLE ... ALTER COLUMN. Essa etapa define como o PolarDB for MySQL interpreta os dados binários nessa coluna.

Syntax:

ALTER TABLE table_name ALTER COLUMN column_name
  [PROTO_NAME = 'protobuf_schema_name']
  PROTO_TEXT = 'protobuf_schema_definition'
  PROTO_MESSAGE = 'protobuf_message'
  [COMPRESSION = 'zlib']

Parameters:

Parâmetro

Obrigatório

Descrição

PROTO_NAME

Não

Nome do schema Protobuf.

PROTO_TEXT

Sim

Definição completa do schema Protobuf.

PROTO_MESSAGE

Sim

Tipo de mensagem Protobuf de nível superior a desserializar.

COMPRESSION

Não

Defina como zlib se os dados foram comprimidos com zlib antes da gravação na coluna. Omita este parâmetro para dados não comprimidos.

Também é possível descomprimir manualmente dados com zlib usando UNCOMPRESS() , que retorna os bytes brutos em hexadecimal.

Remover um schema Protobuf de uma coluna

Para remover o schema, defina todos os parâmetros correspondentes como strings vazias:

ALTER TABLE table_name ALTER COLUMN column_name
  PROTO_NAME=""
  PROTO_TEXT=""
  PROTO_MESSAGE='';
Importante

Antes de remover o schema, certifique-se de que nenhum índice ou coluna virtual referencie a coluna.

Visualizar o schema Protobuf de uma coluna

  1. Ative a exibição do schema para a sessão:

    SET display_readable_proto_info = true;
  2. Exiba as definições das colunas:

    SHOW columns FROM table_name;

Exemplos

Os exemplos a seguir usam o schema addressbook.proto da comunidade Protobuf para demonstrar um fluxo de trabalho completo: criação de tabela, configuração de schema, inserção de dados e consulta.

Schema usado em todos os exemplos:

syntax = "proto2";

package tutorial;

message Person {
  optional string name = 1;
  optional int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    optional string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

Etapa 1: Criar a tabela

CREATE TABLE t1 (c1 INT, c2 BLOB);

A coluna c2 armazena dados serializados em Protobuf.

Etapa 2: Associar o schema à coluna

Escolha a instrução adequada ao tipo de compressão dos seus dados.

Sem compressão zlib:

ALTER TABLE t1 ALTER COLUMN c2
  PROTO_NAME="AddressBook"
  PROTO_TEXT="syntax = \"proto2\";\n\npackage tutorial;\n\nmessage Person {\n  optional string name = 1;\n  optional int32 id = 2;\n  optional string email = 3;\n\n  enum PhoneType {\n    MOBILE = 0;\n    HOME = 1;\n    WORK = 2;\n  }\n\n  message PhoneNumber {\n    optional string number = 1;\n    optional PhoneType type = 2 [default = HOME];\n  }\n\n  repeated PhoneNumber phones = 4;\n}\n\nmessage AddressBook {\n  repeated Person people = 1;\n}"
  PROTO_MESSAGE='AddressBook';

Com compressão zlib:

ALTER TABLE t1 ALTER COLUMN c2
  PROTO_NAME="AddressBook"
  PROTO_TEXT="syntax = \"proto2\";\n\npackage tutorial;\n\nmessage Person {\n  optional string name = 1;\n  optional int32 id = 2;\n  optional string email = 3;\n\n  enum PhoneType {\n    MOBILE = 0;\n    HOME = 1;\n    WORK = 2;\n  }\n\n  message PhoneNumber {\n    optional string number = 1;\n    optional PhoneType type = 2 [default = HOME];\n  }\n\n  repeated PhoneNumber phones = 4;\n}\n\nmessage AddressBook {\n  repeated Person people = 1;\n}"
  PROTO_MESSAGE='AddressBook'
  COMPRESSION='zlib';

Etapa 3: Inserir dados

Sem compressão zlib:

INSERT INTO t1 VALUES(1, X'0a380a0b56697375616c50726f746f10011a1776697375616c70726f746f40706f6c617264622e636f6d220e0a0a313233343536373839301002');

Com compressão zlib:

INSERT INTO t1 VALUES(1, X'3C000000785ee3b2e0e20ecb2c2e4dcc0928ca2fc9176094122f03730b405c8782fc9cc4a29424bde4fc5c253e2e2e432363135333730b4b03012600183d10de');

Para verificar os bytes comprimidos, descomprima-os com UNCOMPRESS():

SELECT HEX(UNCOMPRESS(X'3C000000785ee3b2e0e20ecb2c2e4dcc0928ca2fc9176094122f03730b405c8782fc9cc4a29424bde4fc5c253e2e2e432363135333730b4b03012600183d10de')) AS UNCOMPRESS_DATA;

Resultado:

+----------------------------------------------------------------------------------------------------------------------+
| UNCOMPRESS_DATA                                                                                                      |
+----------------------------------------------------------------------------------------------------------------------+
| 0A380A0B56697375616C50726F746F10011A1776697375616C70726F746F40706F6C617264622E636F6D220E0A0A313233343536373839301002 |
+----------------------------------------------------------------------------------------------------------------------+

Etapa 4: Ler e consultar os dados

Ler dados BLOB sem PROTO_TO_JSON()

Sem o recurso de Protobuf legível, consultar diretamente a coluna c2 retorna dados binários ilegíveis:

Sem compressão zlib:

SELECT c2 FROM t1\G

Resultado:

*************************** 1. row ***************************
c2:
8
VisualProtovisualproto@polardb.com"
1234567890

Com compressão zlib:

SELECT c2 FROM t1\G

Resultado:

*************************** 1. row ***************************
c2: <   x^...

A saída comprimida consiste em dados binários ilegíveis.

Ler dados BLOB como JSON

A função PROTO_TO_JSON() funciona tanto para dados comprimidos quanto não comprimidos, sem exigir alterações na consulta:

SELECT PROTO_TO_JSON(c2) FROM t1;

Resultado:

+------------------------------------------------------------------------------------------------------------------------------------------+
| PROTO_TO_JSON(c2)                                                                                                                        |
+------------------------------------------------------------------------------------------------------------------------------------------+
| {"people": [{"id": 1, "name": "VisualProto", "email": "visualproto@polardb.com", "phones": [{"type": "WORK", "number": "1234567890"}]}]} |
+------------------------------------------------------------------------------------------------------------------------------------------+
A função PROTO_TO_JSON() lê dados comprimidos com zlib e não comprimidos.

Extrair um campo específico

Use JSON_EXTRACT() para obter campos individuais da saída JSON:

SELECT JSON_EXTRACT(PROTO_TO_JSON(c2), '$.people[0].name') FROM t1;

Resultado:

+-----------------------------------------------------+
| json_extract(PROTO_TO_JSON(c2), '$.people[0].name') |
+-----------------------------------------------------+
| "VisualProto"                                       |
+-----------------------------------------------------+

Criar um índice em um campo Protobuf

Crie um índice funcional no campo de e-mail:

CREATE INDEX i_email ON t1 ((CAST(JSON_UNQUOTE(JSON_EXTRACT(PROTO_TO_JSON(c2), '$.people[0].email')) AS CHAR(100))));

Verifique o uso do índice executando EXPLAIN:

EXPLAIN SELECT * FROM t1 WHERE CAST(JSON_UNQUOTE(JSON_EXTRACT(PROTO_TO_JSON(c2), '$.people[0].email')) AS CHAR(100)) = 'visualproto@polardb.com';

Resultado:

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

Criar uma coluna virtual

Gere uma coluna virtual que exponha um campo Protobuf como coluna regular:

ALTER TABLE t1 ADD COLUMN c3 VARCHAR(100) AS (JSON_EXTRACT(PROTO_TO_JSON(`c2`), _utf8mb4'$.people[0].email'));

Verifique o schema:

DESC t1;

Resultado:

+-------+--------------+------+-----+---------+-------------------+
| Field | Type         | Null | Key | Default | Extra             |
+-------+--------------+------+-----+---------+-------------------+
| c1    | int(11)      | YES  |     | NULL    |                   |
| c2    | blob         | YES  |     | NULL    |                   |
| c3    | varchar(100) | YES  |     | NULL    | VIRTUAL GENERATED |
+-------+--------------+------+-----+---------+-------------------+

A coluna c3 é uma coluna virtual gerada com base nos dados Protobuf em c2.