是否甚至可以仅使用 Mysql 从 Mysql blob 列将 Protobuf 二进制消息解码为人类可读视图?
Is that even possible to decode Protobuf binary message to human readable view from Mysql blob column using only Mysql?
我们使用以下方式存储 protobuf 消息:
...
payload.toByteArray(),
...
进入 longblob
列,通常我们在基于 Spring 的应用程序中读出它们并在那里进行处理。
但是,有一个非常简单的问题:是否可以只在 SQL 查询(可能使用存储过程)中读取那些 longblob 列值,从而避免将数据加载到应用程序中并在那里进行处理?
我们只需要一个特定消息类型结构的转换器:
message Entry
{
int64 time = 1;
repeated Point points = 2;
}
message Point
{
uint64 status = 1;
int64 value = 2;
google.protobuf.Timestamp timestamp = 3;
}
我个人在这里看不到任何可能的解决方案,但是,也许是因为我没有足够的 protobuf 经验。
MySQL 存储过程确实具有执行此操作所需的所有编程结构,因此理论上是可能的。但是,它将涉及相当多的编程,可能不值得在数据库端进行。
但是,这里是存储过程必须执行的操作的粗略描述。详见Protobuf encoding documentation。
- 创建一个存储过程
read_varint()
,它将从一个 blob 中读取第一个 varint
,returns 它作为整数和其余的 blob。
- 创建一个存储过程
decode_point()
,重复调用read_varint()
取一个标签,然后调用read_varint()
读取字段数据,并根据标签号赋值给变量。
- 为内置
google.protobuf.Timestamp
数据类型创建类似的 decode_timestamp()
并从 decode_point()
调用它作为时间戳字段。
- 创建一个存储过程
decode_entry()
,重复调用read_varint()
取一个标签,根据标签值直接解码time
或调用decode_point()
。
- 扩展所有这些过程以跳过具有未知标记号的字段。
有趣的是,您的消息类型只有 varint
个字段。因此,至少,您可以重复调用 read_varint()
以将所有变量添加到列表中。然后每个字段总是在一个特定的索引处。但是,我不推荐这样做,因为不可能扩展它来处理未来不同类型的字段。
我们使用以下方式存储 protobuf 消息:
...
payload.toByteArray(),
...
进入 longblob
列,通常我们在基于 Spring 的应用程序中读出它们并在那里进行处理。
但是,有一个非常简单的问题:是否可以只在 SQL 查询(可能使用存储过程)中读取那些 longblob 列值,从而避免将数据加载到应用程序中并在那里进行处理?
我们只需要一个特定消息类型结构的转换器:
message Entry
{
int64 time = 1;
repeated Point points = 2;
}
message Point
{
uint64 status = 1;
int64 value = 2;
google.protobuf.Timestamp timestamp = 3;
}
我个人在这里看不到任何可能的解决方案,但是,也许是因为我没有足够的 protobuf 经验。
MySQL 存储过程确实具有执行此操作所需的所有编程结构,因此理论上是可能的。但是,它将涉及相当多的编程,可能不值得在数据库端进行。
但是,这里是存储过程必须执行的操作的粗略描述。详见Protobuf encoding documentation。
- 创建一个存储过程
read_varint()
,它将从一个 blob 中读取第一个varint
,returns 它作为整数和其余的 blob。 - 创建一个存储过程
decode_point()
,重复调用read_varint()
取一个标签,然后调用read_varint()
读取字段数据,并根据标签号赋值给变量。 - 为内置
google.protobuf.Timestamp
数据类型创建类似的decode_timestamp()
并从decode_point()
调用它作为时间戳字段。 - 创建一个存储过程
decode_entry()
,重复调用read_varint()
取一个标签,根据标签值直接解码time
或调用decode_point()
。 - 扩展所有这些过程以跳过具有未知标记号的字段。
有趣的是,您的消息类型只有 varint
个字段。因此,至少,您可以重复调用 read_varint()
以将所有变量添加到列表中。然后每个字段总是在一个特定的索引处。但是,我不推荐这样做,因为不可能扩展它来处理未来不同类型的字段。