在protobuf消息或嵌套消息中有多个字段是最好的吗?

时间:2018-04-05 10:40:37

标签: database-design protocol-buffers data-modeling protobuf-net

我试图在网上找到一些建议,但找不到任何相关内容。

让我们说我正在创建一个包含很多字段(50+)的协议缓冲消息。最好是将所有字段保持在同一级别还是将它们组织在子消息中?这种或那种方式对表演有影响吗?

示例:

message myMessage{
 string field1 = 1;
 string field2 = 2;
 ....
 string fieldn = n;
}

VS

message myMessage{
 SubMessage1 groupedfieldsbasedonsomebusinesslogic1 = 1;
 SubMessage2 groupedfieldsbasedonsomebusinesslogic2 = 2;

 message SubMessage1{
  string field1 = 1;
  string field2 = 2;
  ... 
  string fieldx = x;
 } 

 message SubMessage2{
  string fieldxplus1 = x+1;
  ... 
  string fieldn = n;
 }
}

我在这里不太考虑可读性,因为在反序列化以获得平坦数据或嵌套数据时有利有弊。我的问题是真正关注技术影响。

1 个答案:

答案 0 :(得分:6)

没有最好的" - 一切都是上下文的,只有你拥有大部分背景。

然而!关于表现的一些小想法:

  • 嵌套方法需要更多对象;通常这很好,除非你的数量巨大
  • 嵌套方法可以更容易理解对象模型以及数据某些部分之间的关​​系
  • 平坦的方法需要更大的场数;字段编号1-15采用单字节头;字段编号16-2047需要2个字节的标题(依此类推);实际上,这几个字段的额外字节不太可能对您造成太大影响,并且会被替代(嵌套)方法的开销所抵消:
  • 嵌套方法需要每个子对象的长度前缀,或者开始/结束标记("组"在协议中);这在额外的尺寸方面并不多,但是:
    • length-prefixe要求序列化程序事先知道长度,这意味着要么进行双重处理(a"计算长度"扫描),要么缓冲;在大多数情况下,这不是一个大问题,但对于非常大的子图可能会有问题
    • 开始/结束令牌是谷歌一直试图杀死的东西,并没有在所有图书馆中得到很好的支持(而且IIRC它并不存在于" proto3"架构中);我仍然非常喜欢它,在某些情况下:) protobuf-net(来自标签)支持将任意子数据编码为组的能力,但如果你需要稍后x-plat它可能会很尴尬

在所有这些事情中,如果是我,那么我会关注的是第二个

也许从看起来可用的东西开始,并测量它以获得真实的数据量;它的表现是否可以接受?