Parquet的Repetition Level和Definition Level

如下的 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

posted @ 2019-12-12 14:22  十年伯约  阅读(2536)  评论(1编辑  收藏  举报