码迷,mamicode.com
首页 > 其他好文 > 详细

Parquet的Repetition Level和Definition Level

时间:2019-12-12 14:55:03      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:需要   font   填充   idt   图片   lan   完全   width   name   

如下的 schema 定义了每行是一个组合类型Document:(required表示必须有,optional表示可选,repeated表示可重复的,即数组(数组长度可以是0)。group类似于struct)

message Document {

    required int64 DocId;

    optional group Links {

        repeated int64 Backward;

        repeated int64 Forward;

    }

    repeated group Name {

        repeated group Language {

            required string Code;

            optional string Country;

        }

        optional string Url;

    }

}

 

假设有两行数据如下:

DocId: 10

Links

    Forward: 20

    Forward: 40

    Forward: 60

Name

    Language

        Code: ‘en-us‘

        Country: ‘us‘

    Language

        Code: ‘en‘

    Url: ‘http://A‘

Name

    Url: ‘http://B‘

Name

    Language

        Code: ‘en-gb‘

        Country: ‘gb‘

DocId: 20

Links

    Backward: 10

    Backward: 30

    Forward: 80

Name

    Url: ‘http://C‘

 

如果是关系型数据,而不是嵌套的结构。存储的时候,我们可以将每一列的值直接排列下来,不用引入其他的概念,也不会丢失数据。对于嵌套的结构,我们 还需要两个变量R (Repetition Level) ,D (Definition Level) 才能存储其完整的信息。

在Parquet中我们只需定义和存储schema的叶子节点所在列的Repetition Level和Definition Level

   先对repeated或optional的类型没有值的列用null填充(不填充会导致反解析时错位),如下:

DocId: 10

Links

    Backward: null

    Forward: 20

    Forward: 40

    Forward: 60

Name

    Language

        Code: ‘en-us‘

        Country: ‘us‘

    Language

        Code: ‘en‘

        Country: null

    Url: ‘http://A‘

Name

Language

    Code: null

    Country: null

    Url: ‘http://B‘

Name

    Language

        Code: ‘en-gb‘

        Country: ‘gb‘

    Url: null

DocId: 20

Links

    Backward: 10

    Backward: 30

    Forward: 80

Name

Language

    Code: null

    Country: null

    Url: ‘http://C‘

 

 技术图片

 

 

Repetition Level是记录该列的值是在某行的哪一个级别上重复的。比如对于Name.Language.Code,一共有5条记录。

  1. en-us,出现在第一个Name的第一个Lanuage里面。在此之前,这三个元素是没有重复过的,都是第一个。所以其R为0。
  2. en,   出现在第一个Name的第二个Lanuage里面。也就是说Lanague是重复的元素。Name.Language.Code中Lanague排第二个,所以其R为2.
  3. null, 出现在第二个Name的第一个Language里面,Name是重复元素,排第一个,R为1
  4. en-gb,出现在第三个Name的第一个Language里面,Name是重复元素,排第一个,所以其R为1。
  5. null, 出现在第一个Name的第一个Lanuage里面。在此之前,这三个元素是没有重复过的,都是第一个。所以其R为0。

从Repetition Level的定义上可以看出,每次R=0表示新的一行开始了。只有repeated类型的field需要Repetition Level,optional和required类型的不需要。

    另外,按我的理解,比较 Links.Forward(是repeated类型)和Name.Language.Code(不是repeated类型)。

  1. 对于repeated类型的Repetition Level,是指这个值和上一值同属于哪一层元素。
  2. 对于非repeated类型的Repetition Level,是指这个值和上一值在哪一层元素上重复

不知道对不对,后续验证。

 

Definition Level是定义的深度,用来记录该列是否是”想象”出来的。所以对于非NULL的记录,是没有意义的,其值必然为相同。例如Name.Language.Country,一共有5条记录。

  1. us,真实存在的,D为3.
  2. null,到Language这层是真实存在的,D为2.
  3. null,到Name这层是真实存在的, D为1
  4. gb,真实存在的,D为3
  5. null,到Name这层是真实存在的,D为1

如果路径中有required,可以将其减去,因为required必然会define,记录其数量没有意义,比如Name.Language.Code的Definition Level。

 

 

接下来如果可以根据scheme和结构图反推为原始数据,那说明对这个Repetition Level和Definition Level已经完全理解。

message Document {

    required int64 DocId;

    optional group Links {

        repeated int64 Backward;

        repeated int64 Forward;

    }

    repeated group Name {

        repeated group Language {

            required string Code;

            optional string Country;

        }

        optional string Url;

    }

}

 技术图片

 

 

以第一行为例

1)    DocId

10

2)    Links. Forward

 技术图片

第一行有三个值,r分别是0,1,1,后面两个1表示是在第一个元素里面重复,也就是Links,得到:

DocId: 10

Links

    Forward: 20

    Forward: 40

    Forward: 60

 

3)    Links. Backward

 技术图片

 

 第一行只有一个NULL值,d=1表示在Links这层有定义,得到

DocId: 10

Links

    Forward: 20

    Forward: 40

    Forward: 60

    Backward: null

实际上和上一步得到的结果是一样的,红色字体是空值,只是为了理解方便。

4)    Name.Url

 技术图片

第一行有三个值。由于Url不是repeated类型的,所以和Links.Forward是不一样的。Url是在Name这一层重复。

DocId: 10

Links

    Forward: 20

    Forward: 40

    Forward: 60

    Backward: null

Name

    Url: ‘http://A‘

Name

    Url: ‘http://B‘

Name

    Url: null

5)    Name.Language.Code

 技术图片

 

 

第一个en-us在第一个Name的第一个Language下。

第二个en,和第一个在第2个元素上重复,由于Code不是repeated类型,所以和第一个在不同的Language下,但是在同一个Name下。

第三个null,和第二个在第1个元素上重复,而定义层次d是1,也就是只在Name上有定义,Language开始就没定义

第四个en-gb,和第三个在第1个元素上重复,所以属于第三个Name的Language下。

 

DocId: 10

Links

    Forward: 20

    Forward: 40

    Forward: 60

    Backward: null

Name

    Url: ‘http://A‘

    Language

        Code: en-us

    Language

        Code: en

Name

    Url: ‘http://B‘

    Language

        Code: null

Name

    Language

        Code: en-gb

    Url: null

 

6)    Name.Language. Country

 技术图片

 

 

第一个us在第一个Name的第一个Language下。

第二个null,和第一个在第2个元素上重复,由于Country不是repeated类型,所以和第一个在不同的Language下,但是在同一个Name下。而定义层次d是2,也就是Language那层有定义。

第三个null,和第二个在第1个元素上重复,而定义层次d是1,也就是只在Name上有定义,Language开始就没定义

第四个gb,和第三个在第1个元素上重复,所以属于第三个Name的Language下。

 

DocId: 10

Links

    Forward: 20

    Forward: 40

    Forward: 60

    Backward: null

Name

    Url: ‘http://A‘

    Language

        Code: en-us

        Country: us

    Language

        Code: en

        Country: null

Name

    Url: ‘http://B‘

    Language

        Code: null

        Country: null

Name

    Language

        Code: en-gb

        Country: gb

    Url: null

Parquet的Repetition Level和Definition Level

标签:需要   font   填充   idt   图片   lan   完全   width   name   

原文地址:https://www.cnblogs.com/tenyearboyue/p/12028913.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!