① 列式数据库有哪些
列式数据库是以列相关存储架构进行数据存储的数据库,主要适合与批量数据处理和即席查询。相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合与小批量的数据处理,常用于联机事务型数据处理。
不读取无效数据:降低 I/O 开销,同时提高每次 I/O 的效率,从而大大提高查询性能。查询语句只从磁盘上读取所需要的列,其他列的数据是不需要读取的。例如,有两张表,每张表100GB 且有100 列,大多数查询只关注几个列,采用列存储,不需要像行存数据库一样,将整行数据取出,只取出需要的列。磁盘 I/0 是行存储的 1/10或更少,查询响应时间提高 10 倍以上。
高压缩比:压缩比可以达到 5 ~ 20 倍以上,数据占有空间降低到传统数据库的1/10 ,节省了存储设备的开销。
当数据库的大小与数据库服务器内存大小之比达到或超过 2:1 (典型的大型系统配置值)时,列存的 I/O 优势就显得更加明显;
GBase 8a 分析型数据库的独特列存储格式,对每列数据再细分为“数据包”。这样可以达到很高的可扩展性:无论一个表有多大,数据库只操作相关的数据包,性能不会随着数据量的增加而下降。通过以数据包为单位进行 I/O 操作提升数据吞吐量,从而进一步提高I/O效率。
由于采用列存储技术,还可以实现高效的透明压缩。
由于数据按列包存储,每个数据包内都是同构数据,内容相关性很高,这使得GBase 8a 更易于实现压缩,压缩比通常能够达到 1:10 甚至更优。这使得能够同时在磁盘 I/O 和 Cache I/O 上都提升数据库的性能,使 GBase 8a 在某些场景下的运算性能比传统数据库快 100 倍以上。
GBase 8a 允许用户根据需要设置配置文件,选择是否进行压缩。在启用压缩的情况下GBase 8a 根据数据的不同特性以及不同的分布状况,自动采用相应的压缩算法,如:
行程编码(适用于大量连续重复的数据,特别是排序数据);
基于数据的差值编码(适用于重复率低,但彼此差值较小的数据列);
基于位置的差值编码(适用于重复率高,但分布比较随机的数据列)。
② HBase的列式存储在查询时如何读取
hbase的region是按行划分,而非按列,如果你读取指定一行的所有列数据,regionServer虽然无法保证你的所有数据都在一个HFile中,但是至少是在一个Region中。但是具体的HFile所在的hdfs的节点那就不是HBase关心的事了,因为HBase的存储是依赖与hdfs,所以底层存储读取的事会由NameNode操心,NameNode会考虑就近原则,而提供最高效的数据读取策略。
你的数据传输是必然,但是HBase不会计算,计算是发生在你将想要的数据获取到之后再自行进行计算的。你读取大量数据必然会有大量数据传输,HBase只是将提供了一种高效的数据读取策略,尽量减小数据传输量
③ 浅析Dremel中嵌套数据记录的列式存储
嵌套数据举例如下,
图1包含一个名为Document的数据结构的结构定义,即schema,以及两个实例,r1和r2。定义数据结构的schema有三种修饰符,如下:
● required:表示有且仅有一个值
● optional:表示可选,0到1个值
● repeated:表示重复,0到N个值
所谓嵌套数据记录其实是一种树状结构,图2是数据记录r1的树形表示,其中叶子节点含有真正的值,字段可以用完整路径表示。图1所示的例子Document总共有六个字段,路径分别为:
● DocId
● Links.Backward
● Links.Forward
● Name.Language.Code
● Name.Language.Country
● Name.Url
记录按列存储主要有正向拆解和反向构造两个过程:
● 正向拆解:按照不同字段对记录进行拆解,相同字段的值集中存储为一列
● 反向构造:选择任意字段子集,重新构造为一个数据记录
因为嵌套数据记录的字段有重复,对于重复字段(repeated修饰)的多个值,在反向构造的时候,需要知道这些值是来自不同的记录,还是来自相同记录的重复字段。最简单的方式是引入一个“标志位”:0表示该值来自一个新的记录,1表示相同记录的重复字段。
然而重复字段是嵌套的,所以“相同记录的重复字段”包含多种情况,如图1所示record1,Code(en)(表示value为en的Code字段,下同)和Code(en-gb)都是记录r1的重复字段,它们在记录中的位置还需进一步加以区分。考虑到字段是用形如x.y.z…的路径表示,所以重复字段在记录中的“位置”,可以表示为“该重复字段出现在路径哪一级”。如果记录用树表示,那么所谓“路径哪一级”指的就是树的深度(levels)。需注意,路径中非repeated修饰的字段不参与深度计算。
比如Code字段的路径表示为Name.Language.Code,Name和Language都是重复字段,如果在记录中第一次出现,levels为0,如果在Name处重复出现,levels为1,在Language处重复出现levels为2。如Code(en)在Language处重复,所以levels为2;Code(en-gb)在Name出重复,所以levels为1。
又比如Forward字段路径为Links.Forward中,Links是optional的,不参与深度计算,Forward是repeated的,所以,如果在Forward处重复出现,levels为1(注意:不为2)。
这所谓的levels在Dremel中就是repetition levels,其定义如下:
“… at what repeated field in the field’s path the
value has repeated.”
意思是“在路径中的什么重复字段,此值重复了”,通俗来说就是“在哪一级重复”。
逐个读取列存储中的repetition
levels,就能够初步还原value在原有数据中的位置,以字段Name.Language.Code为例:
1)第1个value是en-us,repetition levels=0表示没有任何重复,表明这是一个新的record的开始,也表明en-us处在第1个Name的第1个Language。
2)第2个value是en,repetition levels=2表示en在Language重复,也就是说不在Name处重复,表明和上一个值en-us处在同一个Name,即en处在第1个Name的第2个Language
3)第3个value是NULL,repetition levels=1表示NULL在Name处重复,表明NULL处在一个新的Name,第2个Name。之所以要插入一个NULL值,为了计算出第4个value‘en-gb’出现在第3个Name,否则的话就会被认为处在第2个Name
4)第4个value是en-gb,repetition levels=1表示en-gb处在一个新的Name,即第3个Name
5)第5个value是NULL,repetition levels=0表明这是一个新的记录的开始
如果value不为NULL,通过repetition levels就能够确定其所在位置。但如果value为NULL,仅有repetition levels还无法完全确定其所在位置。
以Name.Language.Country字段为例,第3个value是NULL,repetition
levels=1表明当前NULL处在第2个Name(需要结合前面两个value的repetition
levels计算得出)。但由于Name下面有两级定义,Language和Country,Language是repeated类型的,重复次数可能为0,即可能没有定义,Country是optional可选类型,也可能没有定义,既然都有可能没定义,仅有NULL就无法知道是在Language这一级NULL还是在Country这一级NULL。
因此,对于optional或repeated类型字段,需要一个标示显示的表明NULL型value定义在哪一级,这就是Dremel中的definition levels,定义如下:
“...how many fields in path that could be undefined (because they are
optional or repeated) are actually present in the record”
即“在路径中有多少个可选字段或重复字段实际上是有值的”。
以图3所示Name.Language.Country为例进行说明:
● 第1个NULL value的definition levels为2,表示Name和Language有定义,Country没有定义
● 第2个NULL value的definition levels为1,表示Name有定义,Language就没有定义了
进一步看非NULL的value。Country为us和gb的value,其definition
levels为都3,表示Name、Language和Country都有定义。Name.Language.Code字段,Code为required类型,Name和Language是repeated类型,所以Code字段的definition levels取值1或2,value en-us、en、en-gb等definition levels为2,NULL value的defition为1。
不难发现,非NULL的value,其definition levels为路径深度的最大值。NULL的value,其definition levels都小于路径深度最大值。基于该特点,可以不用保存NULL value,仅保存其definition levels即可。
[1] Dremel论文
④ 列式数据库的举例
下面以GBase 8a分析型数据库为例,描述列存储对数据存储与管理的作用。
面对海量数据分析的 I/O 瓶颈,GBase 8a 把表数据按列的方式存储,其优势体现在以下几个方面。
不读取无效数据:降低 I/O 开销,同时提高每次 I/O 的效率,从而大大提高查询性能。查询语句只从磁盘上读取所需要的列,其他列的数据是不需要读取的。例如,有两张表,每张表100GB 且有100 列,大多数查询只关注几个列,采用列存储,不需要像行存数据库一样,将整行数据取出,只取出需要的列。磁盘 I/0 是行存储的 1/10或更少,查询响应时间提高 10 倍以上。
高压缩比:压缩比可以达到 5 ~ 20 倍以上,数据占有空间降低到传统数据库的1/10 ,节省了存储设备的开销。
当数据库的大小与数据库服务器内存大小之比达到或超过 2:1 (典型的大型系统配置值)时,列存的 I/O 优势就显得更加明显;
GBase 8a 分析型数据库的独特列存储格式,对每列数据再细分为“数据包”。这样可以达到很高的可扩展性:无论一个表有多大,数据库只操作相关的数据包,性能不会随着数据量的增加而下降。通过以数据包为单位进行 I/O 操作提升数据吞吐量,从而进一步提高I/O效率。
由于采用列存储技术,还可以实现高效的透明压缩。
由于数据按列包存储,每个数据包内都是同构数据,内容相关性很高,这使得GBase 8a 更易于实现压缩,压缩比通常能够达到 1:10 甚至更优。这使得能够同时在磁盘 I/O 和 Cache I/O 上都提升数据库的性能,使 GBase 8a 在某些场景下的运算性能比传统数据库快 100 倍以上。
GBase 8a 允许用户根据需要设置配置文件,选择是否进行压缩。在启用压缩的情况下GBase 8a 根据数据的不同特性以及不同的分布状况,自动采用相应的压缩算法,如:
行程编码(适用于大量连续重复的数据,特别是排序数据);
基于数据的差值编码(适用于重复率低,但彼此差值较小的数据列);
基于位置的差值编码(适用于重复率高,但分布比较随机的数据列)。
⑤ 什么是数据库列存储,原理是怎样的
数据库列存储不同于传统的关系型数据库,其数据在表中是按行存储的,列方式所带来的重要好处之一就是,由于查询中的选择规则是通过列来定义的,因 此整个数据库是自动索引化的。
按列存储每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量,一个字段的数据聚集存储,那就 更容易为这种聚集存储设计更好的压缩/解压算法。这张图讲述了传统的行存储和列存储的区别:
⑥ 行式数据库和列式数据库的优缺点是什么,行式数据库和列式数据库的执行效率比较一下
传统的行式数据库,是按照行存储的,维护大量的索引和物化视图无论是在时间(处理)还是空间(存储)方面成本都很高。而列式数据库恰恰相反,列式数据库的数据是按照列存储,每一列单独存放,数据即是索引。只访问查询涉及的列,大大降低了系统I/O,每一列由一个线来处理,而且由于数据类型一致,数据特征相似,极大方便压缩。行式数据库擅长随机读操作,列式数据库则更擅长大批量数据量查询
⑦ hdfs 列式存储和行式存储的区别
列式数据库是将同一个数据列的各个值存放在一起。插入某个数据行时,该行的各个数据列的值也会存放到不同的地方。
列式存储: 每一列单独存放,数据即是索引。
只访问涉及得列,如果我们想访问单独一列(比如NAME)会相当迅捷。
一行数据包含一个列或者多个列,每个列一单独一个cell来存储数据。而行式存储,则是把一行数据作为一个整体来存储。
在HANA的世界中,并不是只存在列式存储,行式存储也是存在的。
各自的优缺点:
⑧ pandas中查看数据类型的几种方式
在获得数据之后、分析数据之前,我们一般需要对数据总体进行一个概览,如有哪些字段,每个字段的类型,值是否缺失等,以下列出了几种方法,供我们方便快捷的查看dataframe的数据类型。
1、维度查看:df.shape
返回结果如下如所示,说明此表格一共有20w+行,16列:
2、数据表基本信息(维度、列名称、数据格式、所占空间等):df.info()
返回结果如图,可见,用info方法可以非常全面的看出表格的各项属性,包括:
1.表格的维度:203401行 * 16列,RangeIndex:0-203400
2.表格的列名,是否为空值和列字段类型dtype(后面我会给出pandas的数据类型和Python数据类型的匹配关系图!!!)
3.表格所占空间:24.8M+
3、每一列数据的格式:df.dtypes
这个功能与df.info()类似,如果只想查看每一列存储的是什么数据格式,那么可以直接使用df.dtypes
返回结果如图,可以看到,这个结果基本就是df.info()的简化版,指明了各列的数据类型。
4、某一列格式:df['B'].dtype
分析过程中,由于字段繁多,所以用到某字段时需要适时查看,同样可以运用dtype,此处不再赘述。
由上文可见,float64,int64,object都是pandas专有的数据格式,同理,Python,numpy都有自己的一套数据格式,它们之间的对应关系可参考下面的表格:
这里需要强调的是object类型实际上可以包括多种不同的类型,比如一列数据里,既有整型、浮点型,也有字符串类型,这些在pandas中都会被标识为‘object’,所以在处理数据时,可能需要额外的一些方法提前将这些字段做清洗,str.replace(),float(),int(),astype(),apply()等等。
如果觉得有用,给我点个赞吧,你的支持就是对我最大的鼓励!ღ( ´・ᴗ・` )❥
⑨ hive存储parquet表
parquet格式的表在生产环境中经常被使用到,具有列式存储和压缩等特点,我们怎么在hive中存储parquet格式的表呢。
这里使用oracle的emp表
加载本地数据到hive表
执行查询
发现报错
emp使用parquet格式存储,其中imputFormat和outputFormat都是parquet的相关的,也就是我的imputFormat是parquent的,但是你传过来的是text,我不认识
我们看一下emp的相关信息,可以看到这里的都是parquet的format的,这是导致这次错误的原因。
这就导致了我们需要每次都先把text文件转化为parquet的文件,然后parquent表进行加载才可以,下面介绍官方推荐的使用方法。
查看emp_tmp的表的信息,这里可以看到,默认的是TextImputFormat和TextOutputFormat的。
然后加载数据到emp_tmp,查看数据,是正常显示的
然后现在把之前的emp里面的数据给删除
然后把emp_tmp表里面的数据加载到emp
查询一下,数据正常显示,这个方式使用起来还行,就是每次都需要对临时表进行操作,还是比较麻烦的。
感觉这个问题是经常出现,为什么会这样呢。这个和hive的版本有一定的关系。
可以看出hive官方将inputformat和outputformat进行了整合,这样使用起来也是比较方便的。
但是可能有人想,那我修改inputformat不就行了,下面我介绍一下,看是否可以
创建emp2表,是parquet的存储格式的
修改inputformat 和serde,这里inputFormat是TextInputFormat,SEDE使用的是LazySimpleSerDe,Outputformat任然是Parquet的,这里需要带上。
查看emp2表的信息,如下图表示修改成功
加载数据到emp2
查询数据,执行成功
到这里,修改inputformat和serde的方法也介绍完成了,我们以为成功了,但是上hdfs上一看,文件还是txt格式的,所以通过修改inputformat和serde的方法不行。
肯定有人想使用这个方法
这个方法我也尝试了,但是返回的值全都是null
在仅仅使用hive的时候,如果想把txt文件里面的数据保存到parquet表里面的话,可以使用建立临时表的方法,这个方法也是比较好操作的。
但是其实如果使用spark,flink等分布式计算引擎的话,是可以直接的读取txt数据保存到parquet表里面的,框架帮我们做了转化。这种方式也是我们在工作中经常使用的。
上面也介绍了修改inputformat和ser的方式,秀给inputformat是可以让txt文件里面的数据被读进来的,如果同时还修改了serde为lazysimpleserde的话,这个是把数据保存为text格式的,已经完全和parquet没有关系了,保存的文件还是txt格式的。仅修改inputformat,但是使用的serde是parquet的,但是数据进出不一致,也是有问题的。
⑩ 什么是列式存储数据库
列式数据库是以列相关存储架构进行数据存储的数据库,主要适合与批量数据处理和即席查询。
GBase 8a 分析型数据库的独特列存储格式,对每列数据再细分为“数据包”。这样可以达到很高的可扩展性:无论一个表有多大,数据库只操作相关的数据包,性能不会随着数据量的增加而下降。通过以数据包为单位进行 I/O 操作提升数据吞吐量,从而进一步提高I/O效率。
由于采用列存储技术,还可以实现高效的透明压缩。