Google Dremel和parquet的复杂嵌套数据结构表征方法解析

news2024/9/24 5:11:26

转载请注明出处。作者:archimekai
核心参考文献: Dremel: Interactive Analysis of Web-Scale Datasets

文章目录

  • 引言
  • 复杂嵌套数据结构的无损表征问题
  • Dremel论文中提出的表征方法
  • parquet
  • 备注

引言

Dremel是Google的交互式分析系统。Google大量采用protobuf格式,因此Dremel必须支持protobuf这种复杂嵌套格式的分析。众多工作已经论证了列式存储格式对分析系统(AP, analytical processing)的重要性,因此Dremel需要把复杂嵌套格式存储为列存。本文接下来重点分析Dremel是如何把复杂嵌套格式转换为每一列单独存储的。

我们的目标是:没有蛀牙(划掉)把相同字段的所有值连续存储。因此需要设计一种能够适用于任意protobuf/json格式的,无损的数据表征方式。

复杂嵌套数据结构的无损表征问题

不同的数据,其表征难度是不同的。最简单的是完全没有嵌套,平铺直叙的数据。这种数据只要将每一个字段的名称取出,放在数据库中作为一列即可。
数据样例如下:

{"Code": "en-us", "Country": "us"}

一种表征方式如下:

CodeCountry
en-usus

如果数据中有嵌套,但是没有列表,也比较简单。只需要用某个分隔符(例如 . )把嵌套的字段名称连接起来即可。以下面的数据为例:

{"DocId": 10, "Links": {"Forward": 20}}

其一种表征方式如下:

DocIdLinks.Forward
1020

如果数据中存在列表,就比较复杂了。这里的难点在于,列表的长度无法提前预知,所以一般不能把列表中的每一个元素都作为一列存储。例如

{"Links": {"Backward": [10,30], "Forward": [80]}}

不能表征为

Links.Backward[0]Links.Backward[1]Links.Forward[0]
103080

如果将来Backward中有10000个元素就很难处理。

这个问题其实有一个简单场景,即列表中的元素都是相同的基本数据类型。这里的基本数据类型可以简单理解为数据库有原生数组类型支持的数据类型,例如 int ( int[] ),float ( float[] )等,因此,上述数据可以表征为下表。Hologres就是采用了这样的方案。

Links.BackwardLinks.Forward
[10.30][80]

通过上面的方案,笔者认为已经可以搞定80%以上的场景了。但是如果列表中的元素不是基本数据类型,上面的的方案就又搞不定了。考虑下面的数据:

{"Name": [{"url": "http://C", "long_data": "data"}]}

在这个例子中,数组里面的元素是{"url": "http://C"},并不是一种基本数据类型,如何存储才能支撑对Name.url的高效查询呢?。除了上面的例子,还有更为复杂的数组套数组的例子:

{"Name": [{"Language":[{"Code": "en-us", "Country": "us"}, {"Code": "en"}]}]}

那么,有没有一种方法可以一劳永逸地搞定所有protobuf/强类型json(强类型json指每个字段的类型是确定的)能够表达的所有数据呢?还真有,这就是Google的天才工程师们在Dremel论文中提出的方案。下面笔者重点介绍这个方案。

Dremel论文中提出的表征方法

还是看上面数组套数组的例子,主要的困难点是,读取数据时如何确定内层元素(例如{"Code": "en"})的位置?这需要准确表达内层元素在当前数组(也即Language)和父数组(也即Name)中的位置,才能在读取时把数据结构还原回来。这提示我们,至少需要增加两个位置信息才行。
Google的工程师们也是这么想的,他们定义了两个变量来表示上述信息,这两个变量也是理解Dremel数据表征算法的关键:

  • 第一个变量是repetition level,简称r,其表示对于给定的字段,其当前在哪一个级别重复。这个概念比较抽象,请结合下面的例子仔细阅读备注进行理解。
  • 第二个变量是definition level,简称d,其表示对于给定的字段,其前面有多少个字段是存在的。例如,r3中的DocId,d=0,也即DocId更上层没有字段了,r3中的Links.Forward字段,d=1,也即Links这个字段是存在的。

可以看到,r和d并非直接表示当前数组和父数组的位置,而是以一种类似增量(在当前级别重复还是在哪个级别重复)的方式进行编码。

一个加料版的例子(r3,基于论文中的r1修改而来)。数据schema如下

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; }} 

数据如下(简称r3)

{
  "DocId": 10, 
  "Links": {"Forward": [20,40,60]}, 
  "Name": [
    {
      "Language": [
        {"Code": "en-us", "Country": "us"},
        {"Code": "en"},
        {"Code": "zh-cn", "Country": "cn"}]
      "Url": "http://A"
    },
    {"Url": "http://B"},
    {"Language": [{"Code": "en-us", "Country": "gb"}]}
  ]
}

数据r3中的Name.Language.Country字段编码后如下。

valuerd备注
us02r=0表示r3这篇文档的第一个Country字段,d=2表示Name, Language两个字段都是存在的
null22r=2表示Language字段在第二级,也即Language数组这一级重复,null表示Country字段实际上未在Language这个数组的第二个元素{"Code": "en"}中出现。注意null在dremel的编码方式中是必须的
cn22r=2表示Language字段在第二级,也即Language数组这一级重复,出现在Language这个数组的第三个元素
null11r=1表示Language字段在第一级,也即Name数组这一级重复,null表示Country字段实际上为在Name这个数组的第二个元素{"Url": "http://B"}中出现。结合d=1可知,Name.Language.Country中只有头一个字段,也即Name存在,Language字段不存在。
gb12r=1表示Language字段在第一级,也即Name数组这一级重复,出现在Name数组的第三个元素

到了这里,相信读者已基本理解了r和d的含义。笔者将Dremel论文中的原图贴在这里,大家应该可以看懂了。
Dremel论文原文中的例子

parquet

parquet中对于嵌套数据的数据和Google Dremel基本一致。本篇文章不详细展开

备注

  • 为了方便理解,上述描述中省略了一些不重要的细节,感兴趣的读者可自行阅读论文原文。
  • 本篇文章只介绍了最核心的数据结构表征方式,Dremel论文中还有关于如何将各个字段拆分为列,如何使用有限状态自动机真正生成r和d值的描述,以后有机会再介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1486908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW石油钻机提升系统数字孪生技术

LabVIEW石油钻机提升系统数字孪生技术 随着数字化、信息化、智能化的发展,石油钻采过程中的石油钻机数字化技术提升成为了提高钻井效率、降低生产成本的重要途径。基于中石油云平台提供的数据,采用数字孪生技术,对石油钻机提升系统进行数字化…

设计模式(十三)抽象工厂模式

请直接看原文:设计模式(十三)抽象工厂模式_抽象工厂模式告诉我们,要针对接口而不是实现进行设计。( )-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- …

Some collections -- 2024.3

一、TensorFlow Android (dataset: Mnist) We used TensorFlow to define and train our machine learning model, which can recognize handwritten numbers, called a number classifier model in machine learning terminology. We transform the trained TensorFlow mod…

pytest-allure报告生成

pytest生成allure报告步骤: 下载allure,配置allure报告的环境变量:把allure-2.13.7\bin 配置到环境变量path路径 验证:在dos窗口和pycharm窗口分别验证:allure –version 2. 生成临时的json报告 在pytest.ini配置文…

挑战杯 基于深度学习的中文情感分类 - 卷积神经网络 情感分类 情感分析 情感识别 评论情感分类

文章目录 1 前言2 情感文本分类2.1 参考论文2.2 输入层2.3 第一层卷积层:2.4 池化层:2.5 全连接softmax层:2.6 训练方案 3 实现3.1 sentence部分3.2 filters部分3.3 featuremaps部分3.4 1max部分3.5 concat1max部分3.6 关键代码 4 实现效果4.…

【k8s管理--可视化界面】

1、可视化界面的软件 kubernetes的可视化软件有以下这些kubernetes dashboard:https://github.com/kubernetes/dashboardkubesphere官网: https://kubesphere.io/zh/rancher 官网: https://www.rancher.cn/kuboard 官网: https:/…

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘数码管模块概述TM1638键盘数码管…

Matlab 多项式插值(曲线拟合)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 由于对曲线拟合有些兴趣,这里就找了一些资料从最基本的方法来看一下曲线拟合的效果: 二、实现代码 % **********

【Git】深入理解 Git 分支合并操作:git merge dev 命令详解

深入理解 Git 合并操作:git merge dev 命令详解 摘要:本文将深入探讨 Git 中的合并操作,以及如何使用 git merge dev 命令将dev 分支的修改合并到当前分支(假设当前分支为main 分支)中。通过详细的解释和示意图&#x…

【笔记】【电子科大 离散数学】 3.谓词逻辑

谓词引入 因为含变量的语句(例如x > 3)不是命题,无法进行逻辑推理。 为了研究简单命题句子内部的逻辑关系,我们需要对简单命题进行分解,利用个体词,谓词和量词来描述它们,并研究个体与总体…

django MTV 静态文件js的添加方式,以及怎么优化js的加载

django MTV 静态文件js的添加方式,以及怎么优化js的加载 1&#xff1a;怎么添加js 2&#xff1a;怎么优化js的加载 django MTV 需要用到的js时&#xff0c;使用以下方式 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF…

NACOS在Windows和Linux下的安装教程

目录 1、Windows安装 1.1、下载安装包 1.2、解压 1.3、端口配置 1.4、启动 1.5、访问 2、Linux安装 2.1、安装JDK 2.2、上传安装包 2.3、解压 2.4、端口配置 2.5、启动 3、Nacos的依赖 1、Windows安装 开发阶段采用单机安装即可。 1.1、下载安装包 在Nacos的Git…

LeetCode 面试题 08.09.括号

括号。设计一种算法&#xff0c;打印n对括号的所有合法的&#xff08;例如&#xff0c;开闭一一对应&#xff09;组合。 说明&#xff1a;解集不能包含重复的子集。 例如&#xff0c;给出 n 3&#xff0c;生成结果为&#xff1a; [ “((()))”, “(()())”, “(())()”, “…

【多模态融合】CRN 多视角相机与Radar融合 实现3D检测、目标跟踪、BEV分割 ICCV2023

前言 本文介绍使用雷达与多视角相机融合&#xff0c;实现3D目标检测、3D目标跟踪、道路环境BEV分割&#xff0c;它是来自ICCV2023的。 会讲解论文整体思路、输入数据分析、模型框架、设计理念、损失函数等。 论文地址&#xff1a;CRN: Camera Radar Net for Accurate, Robus…

重读 Java 设计模式: 探索经典之道与 Spring 框架的设计

写在开头 记得大学刚毕业那会儿&#xff0c;想学点东西&#xff0c;于是拿出了《Head First 设计模式》这本书&#xff0c;就开始了阅读&#xff0c;我曾对这些模式感到晦涩难懂。然而&#xff0c;随着工作岁月的增长&#xff0c;我逐渐领悟到设计模式的价值&#xff0c;尤其是…

鸿蒙实战项目开发:【短信服务】

概述 本示例展示了电话服务中发送短信的功能。 样例展示 涉及OpenHarmony技术特性 网络通信 难度级别 中级 基础信息 使用ohos.telephony.sms接口展示了电话服务中发送短信的功能。 效果预览 新建联系人首页短信页 使用说明&#xff1a; 首页点击创建联系人&am…

智能驾驶及相关零部件摄像头毫米波雷达激光雷达和芯片渗透率

一、总体情况 乘联会数据显示&#xff0c;1月1日至1月28日&#xff0c;全国乘用车厂商新能源车批发销量为56.7万辆&#xff0c;同比增长76%&#xff0c;环比下降38%&#xff1b;国内新能源车市场零售销量为59.6万辆&#xff0c;同比增长92%&#xff0c;环比下降24%。 二、销…

如何在手机上中恢复已删除的照片

市场上有大量用于恢复手机已删除照片的应用程序。您可以尝试任何合法的应用程序来恢复意外删除的视频。其中一些应用程序包括 奇客数据恢复、Disk Drill等。 恢复已删除的 Android 照片 如果您不小心从 Android 设备中删除了任何重要视频&#xff0c;无需惊慌。您可以按照这些…

java基础题库详解

目录 1 JDK和JRE有什么区别&#xff1f; 1.1、JRE 1.2、JDK 2、和equals的区别是什么? 3、比较 4、装箱&#xff0c;拆箱 4.1、什么是装箱&#xff1f;什么是拆箱&#xff1f; 4.2、装箱和拆箱的执行过程&#xff1f; 4.3、常见问题 5、hashCode()相同&#xff0c;e…

【ESP32 IDF】key按键与EXTI中断

文章目录 前言一、按键的使用1.1 按键的简介1.2 读取按键的高低电平1.3 读取按键具体代码 二、中断二、EXIT外部中断2.1 EXIT外部中断简介2.2 外部中断基础知识2.3 设置外部中断注册外部中断服务函数设置触发方式添加中断函数 2.4 示例代码 总结 前言 在嵌入式系统开发中&…