Google Dremel数据模型详解(下)

时间:2023-03-08 21:53:31

“神秘”的r和d

单从数据结构来看的话,我们可以这样解释r和d的含义。r代表着当前字段与前一字段的关系,是在哪一层合并的,即公共的父结点在哪?举例来说,假如我们重建到了Code='en',通过r=2可以知道是在Language那一层发生了重复。

Google Dremel数据模型详解(下)

为了保持原纪录的结构,我们会保存一些NULL数据,而d就是用于重建NULL字段。通过d的值,就能知道NULL的结构。例如下图,通过r=1知道应该合并到Name那一层。而通过d=1则知道路径上只有一个字段,即不仅仅是Code字段不存在,Language也不存在。这样就把NULL正确地重建出来了,那么接下来的Code='en-gb'的层级也就不会乱了。

Google Dremel数据模型详解(下)

然而这只是从静态的数据结构来解释,而r和d的深层次含义还是要看FSM是如何执行的。、60都是接在20字段下面的。Code字段也是同样道理。

Google Dremel数据模型详解(下)

Ø  Name.Language.Code到Name.Language.Country之间的线上为什么是0,1,2?因为Name.Language.Code是required不是repeated,读取后不管下一行的r值是多少都要去读Name.Language.Country。同理Name.Language.Country也是读完不管怎样都跳到下一字段。

Ø  最复杂的要属Name.Url了,因为它是schema里定义的最后一个字段。在Name.Url这要决定到底是继续下一文档如r2的处理,还是跳回到本文档的其他字段继续处理。具体分析一下:r=0说明当前文档中没有Name字段了。为什么这么说?因为如果文档后面真有Name字段,假如下面有Url,则当前表中的下一条应该是r=1;假如下面没有Url,则当前表的下一条应该是r=0的NULL。这里NULL又发挥用处了!所以中间部分的NULL能保持结构无损,而后面部分的NULL能提示文档是否结束

3.2 查询引擎

至此,我们已经彻底摸清Dremel数据模型以及FSM的基本运行方式了。现在终于可以分析Dremel是如何解析和执行类SQL查询的了。查询语言类似SQL,输出也是个嵌套式的记录,以及schema定义。

Google Dremel数据模型详解(下)

那么查询引擎如何执行呢?首先为查询语句中涉及到的每个字段都打开一个Reader来读取数据,然后就是根据WHERE中的条件过滤以及根据SELECT中的条件投影并聚合了。难点在于:重建出层次关系,再进行过滤和聚合。例如,过滤掉DocId=20很容易,但其实文档r2的所有记录都应被过滤。因为WHERE中两个条件是AND关系,同时DocId又是最底层的字段,所以相当于r2这一整棵树都被裁剪掉了。Code=en-gb也是由于所在的Name字段下没有满足http开头的Url字段,而被间接的过滤掉了。

聚合也是同样道理,有了层次关系,才能正确的聚合。例如Code=en-us,en和Url=http://A是同一个Name下的,COUNT和字符串拼接时会一起处理。而Url=http://B则是另一个Name下的,要分开处理。

Google Dremel数据模型详解(下)

参考资料

1 Dremel: Interactive Analysis of Web-Scale DataSets