Dremel存储格式解析

    Dremel是google推出的又一神器,paper中宣称能够在3s内分析1PB的数据,主要是面向交互式查询。这篇paper对嵌套类型的存储方式方面,思维确实有些跳跃,这篇文章主要讲讲这个,一方面是方便后来者理解,另一方面是让自己也整理下思路。

    首先Dremel使用的是列存模型,对于基本类型列存较容易做到;但是对于嵌套类型,Dremel也能做到将其拆解成基本类型并进行列存,这是值得我们研究的。

    直观看下嵌套类型按行存储和拆解后按列存储的对比效果:

Dremel存储格式解析_第1张图片

    然后对于嵌套数据类型,Dremel里面定义了里面三种类型的字段

    1,必须出现1次而且仅出现1次的字段:required

    2,可能出现1次或者0次的字段:optional

    3,可能出现0次或者N次字段:repeated

    下面以paper的例子来讲述吧:

Dremel存储格式解析_第2张图片

    其中DocId是required字段,因此在r1,r2中必须出现1次;url字段是optional字段,因此在r1的第三个Name里未出现,在r1的前两个Name里出现了1次;Backward字段是repeated字段,因此在r1的Links里未出现,在r2的Links里出现了2次。

    理解了上面这些,直接来看下Dremel是怎么来存它的吧:

Dremel存储格式解析_第3张图片

    上表中的每条记录都有两个属性,"r"代表repetition level,"d"代表definition level,定义如下:

    repetition level:what repeated field in the field’s path the value has repeated,记录该字段是在哪个repeated级别上重复的

    definition level:how many fields inpthat could be undefined (because they are optional or repeated) are actually present,记录该字段之上有多少个optional或者repeated字段实际是有值的(本来可以为null的)

    看到这里,各位可能已经在心里默念了:WTF!别急,可以结合一个例子来看:

先看repetition level(下面以r替代),以Name.Language.Code为例:

    1)对第1个出现的值,其r始终为0,因此'en-us'的r为0

    2)对于第2个值'en',其上一个值是'en-us',它们是在Language级别发生的重复,Name.Language是两级的repeated字段,因此r为2

    3)对于第3个值null,是为了记录'en-gb'是出现在第三个Name而非第二个Name里,特意占位用的。null的上一个值是'en',它们是在Name级别发生的重复,因此r是1

    4)对于第4个值'en-gb',其上一个值是null,它们也是在Name级别发生的重复,因此r是1

    5)对于第5个值null,其上一个值是'en-gb',它们出现在两个不同Document里,因此r是0

    总结下,看repetition level注意两点:1,只比较该值和上一个值;2,只需要看这两个值的重复位置上有几个repeated字段

再看definition level(下面以d替代),也以Name.Language.Code为例:

    1)对于'en-us',其上的Name,Language都出现了,因此d为2(其实对于非null值的字段,其上的optional或者repeated字段肯定是出现了,所以都是相同的,只是null字段的d值有差别)

    2)对于'en',同理d也为2

    3)对于null,其上只出现了Name,没有出现Language,因此d为1

    4)对于'en-gb',d也为2

    5)对于最后一个null,其上也只出现了Name,没有出现Language,因此d为1


    以上只是讲了dremel怎么去存嵌套类型,至于这种存法是怎么想出来的,真非我辈能理解的了。。。更多内容,请参考原著paper及网上解析。

你可能感兴趣的:(Dremel存储格式解析)