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

转载请注明出处。作者: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.mzph.cn/news/717914.shtml

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

相关文章

全量知识系统问题及SmartChat给出的答复 之17 知识系统中的两个特权类(超类和欠类) :脚本和场景

Q.45 知识系统中的两个特权类 :脚本和场景 知识系统中的两个特权类(也是集合论中两个特权集合):脚本script和场景scene 。 一个$Demonstrate类型的脚本script: 表示“值val”( 形式上是应用程序的实用工…

如何学习openfoam

学习OpenFOAM的详细步骤、流程、学习网站、练习案例以及B站学习资源推荐如下: 一、详细步骤和流程 安装OpenFOAM:首先,你需要在你的计算机上安装OpenFOAM。你可以从OpenFOAM的官方网站下载适合你的操作系统的安装包,然后按照官方提…

搭建服务器及跨域处理

使用内置的模块搭建服务器 自己电脑: 域名:localhost ip:127.0.0.1 http模块搭建服务器 const http = require(http)// 创建一个http对应的服务器,每次改完服务器的代码后都需要重新启动下服务器 /*方式一: const server = http.createServer((request,response)=>{…

对简单工厂模式、工厂方法模式的思考

目录 1 背景1.1 题目描述1.2 输入描述1.3 输出描述1.4 输入示例1.5 输出示例 2 简单工厂模式3 工厂方法模式4 思考4.1 改进工厂方法模式 1 背景 题目源自:【设计模式专题之工厂方法模式】2.积木工厂 1.1 题目描述 小明家有两个工厂,一个用于生产圆形积木…

铁路关基保护新规发布!铁路软件供应链安全洞察与治理思路

近日,国家铁路局发布《铁路关键信息基础设施安全保护管理办法》,《办法》第十四条提到:“运营者应当加强铁路关键信息基础设施供应链安全保护,优先采购安全可信的网络产品和服务。运营者采购网络产品和服务,应当预判该…

Intel FPGA IP之LVDS SerDes IP学习

FPGA 视频数据输入输出直通工程: 屏:13.2吋8bit色深,屏幕分辨率为1440*192060,具有两个Port,每个Port有4个差分数据对与1个差分时钟对,差分对均支持LVDS协议芯片:Cyclone V系列FPGA目的&#x…

标签转格式问题之——xml_2_txt.py

import xml.etree.ElementTree as ET#xml 是python自带的package import osclasses[walnut]#写自己的分类名 pre_dirF:/2023walnut/labels#xml文件所在文件夹 target_dirF:/2023walnut/yolo#想要存储txt文件的文件夹 pathos.listdir(pre_dir)for path1 in path: # path1rC:\Use…

[变压器故障诊断分类及预测】基于Elman神经网络

课题名称:基于Elman神经网络的变压器故障诊断分类及预测 版本日期:2024-02-10 运行方式:直接运行Elman0507.m文件 代码获取方式:私信博主或QQ:491052175 模型描述: 对变压器油中溶解气体进行分析是变压…

Noise Conditional Score Networks(NCSN)学习

参考: [1] https://zhuanlan.zhihu.com/p/597490389 [2] https://www.zhangzhenhu.com/aigc/Score-Based_Generative_Models.html TOC 1 基于分数的生成模型1.1 简介和动机1.2 Score Matching及其改进1.2.1 Score Matching1.2.2 Sliced score matching(不…

XSS_lab(level1-level5)

level1 直接输入页面没有发现输入框&#xff0c;观察url发现有传参 尝试修改传参为&#xff1a;<script>alert(1)</script> 过啦&#xff01; level2 页面中有输入框&#xff0c;尝试构建语句&#xff1a;<script>alert(1)</script>,传输后查看源代…

国际心理学导师-叶子文JeffreyYip的《意识地图》

“物质就是能量。” ---爱因斯坦 “時常保持觉知&#xff0c;有意识地发现情绪起伏 你随时都能翻转人生 做自己人生的导演 当你频率高时&#xff0c;万事万物为你而来” ---大卫霍金斯 叶子文-《意识地图》&#xff1a;高阶心理学课程 宇宙间万物的本质是能量。一切都靠能量…

Java基础---lambda表达式

一、为什么要引入lambda表达式 lambda 表达式是一个可传递的代码块 &#xff0c; 可以在以后执行一次或多次 。 在介绍lambda表达式之前&#xff0c;我们看一下&#xff0c;以前&#xff0c;我们对于一个问题的通常写法。 假设你已经了解了如何按指定时间间隔完成工作&#xf…

js字符串转json的3种方法

1.eval方式解析 function strToJson(str){var json eval("(" str ")");return json;}console.log(strToJson("{int:1, string:demo}")); 运行截图&#xff1a; 注&#xff1a; 记得别忘了str两旁的小括号。 永远不要使用 eval !!! eval() 是一…

611. 有效三角形的个数 - 力扣

1. 题目 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 2. 示例 3. 分析 利用已升序了的数组通过 a b > c 这条公式找出符合要求的三元组&#xff0c;利用这个公式的前提是三条边为从小到大&#xff0c;再利用单调性快速统计…

STM32 (1)

1.基本信息 stm32是由ST公司生产的一种32位微控制器&#xff08;单片机&#xff09;。 1.1 各种型号 stm32是32位单片机的总称&#xff0c;有多种不同的系列。 32即用32个比特位表示一个地址&#xff0c;寻址范围&#xff1a;0x00000000 --0xffffffff (4GB) 1.2 存储密度 …

Mysql事务的两段式提交

binlog和redo log区别 为了满足Mysql的事物ACID特性&#xff0c;InnoDB引入了redo log和 undo log日志文件。为了满足主从同步Mysql引入了binlog日志文件。redo log和binlog文件都保存的数据库对数据库的修改&#xff0c;但是binlog和redo log本质上是不一样的&#xff1a; r…

UE5中实现后处理深度描边

后处理深度描边可以通过取得边缘深度变化大的区域进行描边&#xff0c;一方面可以用来做角色的等距内描边&#xff0c;避免了菲尼尔边缘光不整齐的问题&#xff0c;另一方面可以结合场景扫描等特效使用&#xff0c;达到更丰富的效果&#xff1a; 后来解决了开启TAA十字线和锯齿…

XXL-Job的基本使用

一、市面上常见的任务调度产品 针对分布式任务调度的需求&#xff0c;市场上出现了很多的产品: 其中XXL-job 是我们经常使用的任务调度平台,XXL这三个英文字母.是以作者名许雪里命名的。 可以前往 Gitee 地址进行下载使用 https://gitee.com/xuxueli0323/xxl-job.git二、XXL-J…

使用`paddle.nn.Layer`自定义网络教程

文章目录 使用paddle.nn.Layer自定义网络教程1. 概念介绍2. 数据处理3. 搭建一个完整的深度学习网络4. 使用paddle.nn.Layer构建深度学习网络5. 利用paddle.nn.Layer进行子层的访问6. 修改paddle.nn.Layer层的成员变量7. 存储模型的参数8. 总结 使用paddle.nn.Layer自定义网络教…

LockBit病毒入侵揭秘:如何防范与应对

在数字时代&#xff0c;随着科技的飞速发展&#xff0c;网络安全问题愈发凸显。恶意软件和勒索软件等网络威胁正不断演变&#xff0c;其中一款备受关注的勒索软件就是LockBit。本文将深入介绍LockBit的特征、攻击手段、演进历程以及对网络安全的威胁。 01 主要特征 LockBit是…