一 存储处理器介绍

通过HIVE存储处理器,不但可以让hive基于hbase实现,还可以支持cassandra JDBC MongoDB 以及 Google Spreadsheets

HIVE存储器的实现原理基于HIVE以及Hadoop的可扩展性实现:

输入格式化(input formats)

输出格式化(output formats)

序列化/反序列化包(serialization/deserialization librarises)

除了依据以上可扩展性,存储处理器还需要实现新的元数据钩子接口,这个接口允许使用HIVE的DDL语句来定义和管理hive自己的元数据以及其它系统的目录(此目录个人理解为其它系统的元数据目录)

一些术语:

HIVE本身有的概念:

被管理的表即内部表(managed):元数据由hive管理,并且数据也存储在hive的体系里面

外部表(external table):表的定义被外部的元数据目录所管理,数据也存储在外部系统中

hive存储处理器的概念:

本地(native)表:hive不需要借助存储处理器就可以直接管理和访问的表

非本地(non-native)表:需要通过存储处理器才能管理和访问的表

内部表 外部表 和 本地表 非本地表 形成交叉,就有了下面四种形式的概念定义:

被管理的本地表(managed native):通过CREATE TABLE创建的表

外部本地表(external native):通过CREATE EXTERNAL TABLE创建,但是没有带STORED BY子句

被管理的非本地表()managed non-native):通过CREATE TABLE 创建,同时有STORED BY子句,hive在元数据中存储表定义,但是不创建任何文件(我的理解是存放数据的目录文件,hive在定义好表结构后会创建对应的目录来存储对应的数据),hive存储处理器向存储数据的系统发出一个请求来创建一个一致的对象结构;

外部非本地(external non-native):通过CREATE EXTERNAL TABLE创建,并且带有STORED BY子句;hive在自己的元数据中注册表的定义信息,并且通过调用存储处理器来检查这些注册在hive中的信息是否与其它系统中原来定义的信息一致

通过hive创建表结构的DDL语句:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

[(col_name data_type [COMMENT col_comment], ...)]

[COMMENT table_comment]

[PARTITIONED BY (col_name data_type [col_comment], col_name data_type [COMMENT col_comment], ...)]

[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name, ...)] INTO num_buckets BUCKETS]

[

[ROW FORMAT row_format] [STORED AS file_format]

| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]

]

[LOCATION hdfs_path]

[AS select_statement]

具体的使用样例,会在下面详细说明

二 Hive与Hbase的整合

hive和Hbase的整合通过Hbase handler jar包实现,它的形式为hive-hbase-x.y.z.jar ,这个处理器需要依赖hadoop0.20以上版本,并且只在hadoop-0.20.x hbase-0.92.0 和zookeeper-3.3.4 上进行过测试。如果hbase版本不是0.92则需要基于你使用的版本重新编译对应的hive存储处理器。

为了创建一张可以被hive管理的hbase的表,需要在hive的ddl语句CREATE TABLE 后面加入语句STORED BY

CREATE TABLE hbase_table_1(key int, value string)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val")

TBLPROPERTIES ("hbase.table.name" = "xyz");

Hbase.table.name属性是可选的,用它来指定此表在hbase中的名字,这就是说,允许同一个表在hive和hbase中有不同的名字。上述语句中,在hive中的表名叫hbase_talbe_1,在hbase中,此表名叫xyz。如果不指定,两个名字则会是相同的。

当执行完命令后,就可以在HBase的shell中看到一张新的空表,如下:

$ hbase shell

HBase Shell; enter 'help<RETURN>' for list of supported commands.

Version: 0.20.3, r902334, Mon Jan 25 13:13:08 PST 2010

hbase(main):001:0> list

xyz

1 row(s) in 0.0530 seconds

hbase(main):002:0> describe "xyz"

DESCRIPTION                                                             ENABLED

{NAME => 'xyz', FAMILIES => [{NAME => 'cf1', COMPRESSION => 'NONE', VE true

RSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY =>

'false', BLOCKCACHE => 'true'}]}

1 row(s) in 0.0220 seconds

hbase(main):003:0> scan "xyz"

ROW                          COLUMN+CELL

0 row(s) in 0.0060 seconds

上面的输出中没有列val的信息,虽然在建表语句中已经指定了这个列名。这是因为在hbase中只有列族的名字才会被定义在表级的元数据中,列族中的列只定义在行级别的元数据中。

下面的语句是定义怎么把数据从hive中加载进入HBase的表,表pokes是hive中已经存在的一个表,并且表中有数据。

INSERT OVERWRITE TABLE hbase_table_1 SELECT * FROM pokes WHERE foo=98;

然后,在Hbase shell中验证数据是否已经加载:

hbase(main):009:0> scan "xyz"

ROW                          COLUMN+CELL

98                          column=cf1:val, timestamp=1267737987733, value=val_98

1 row(s) in 0.0110 seconds

通过hive的语句查询表的结果如下:

hive> select * from hbase_table_1;

Total MapReduce jobs = 1

Launching Job 1 out of 1

...

OK

98        val_98

Time taken: 4.582 seconds

Inserting large amounts of data may be slow due to WAL overhead; if you would like to disable this, make sure you have HIVE-1383 (as of Hive 0.6), and then issue this command before the INSERT:

set hive.hbase.wal.enabled=false;

Warning: disabling WAL may lead to data loss if an HBase failure occurs, so only use this if you have some other recovery strategy available.

如果想基于已经存在的hbase表创建hive可访问的表,则需要用CREATE EXTERNAL TABLE,如下:

CREATE EXTERNAL TABLE hbase_table_2(key int, value string)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES ("hbase.columns.mapping" = "cf1:val")

TBLPROPERTIES("hbase.table.name" = "some_existing_table");

hbase.columns.mapping属性项是必须存在的,它代表的是hbase表的列族以及列的定义信息。

hive与hbase的列匹配

有两种SERDEPROPERTIES配置信息来控制HBase列到HIve的映射

1.hbase.columns,mapping

2.hbase.table.default.storage.type

这个属性可以有String和二进制两种类型的值,默认是String;这个选项只有在hive0.9这个版本可用,     并且在早期的版本中,只有String类型可用

当前列匹配使用起来显得有点笨重和憋手:

1.每个hive的列,都需要在参数hbase.columns.mapping中指定一个对应的条目(比如:a:b或者:key就叫一个条目),多个列之间的条目通过逗号分隔;也就是说,如果某个表有n个列,则参数hbase.columns.mapping的值中就有n个以逗号分隔的条目。比如:

"hbase.columns.mapping" = ":key,a:b,a:c,d:e" 代表有两个列族,一个是a一个是d,a列族中有两列,分别为b和c

注意,hbase.columns.mapping的值中是不允许出现空格的

2.每个匹配条目的形式必须是:key或者列族名:[列名][#(binary|string)](前面带有#标识的是在hive0.9才添加的,早期的版本把所有都当作String类型)

1)如果没有给列或者列族指定类型,hbase.table.default.storage.type的值会被当作这些列或者列族的类  型

2)表示类型的值(binary|string)的任何前缀都可以被用来表示这个类型,比如#b就代表了#binary

3)如果指定列的类型为二进制(binary)字节,则在HBase的单元格的存储类型也必须为二进制字节

3.必须窜至一个:key的形式匹配条目(不支持复合key的形式)

4.在hive0.6版本以前,是通过第一个条目来作为关键字(key)字段,从0.6以后,都需要直接通过:key的方式来指定

5.当前没有办法可以访问到HBase的时间撮属性,并且查询总是访问到最新的数据(这条主要是因为hbase单元格数据存储是有版本的,根据时间撮)

6. 因为HBase的列定义没有包含有数据类型信息,所以在存储的时候,会把所有的其它类型都转换为string 代表;所以,列数据类型不支持自定义

7. 没有必要对HBase的所有列族都进行映射,但是没有被映射的列族不能通过访问Hive表读取到数据;可以把多个Hive表映射到同一个HBase的表

下面的章节提供更加详细的例子,来说明当前各种不同的列映射

多个列和列族

下面的例子包含三个Hive表的列以及两个HBase表的列族,其中一个列族包括两个列

CREATE TABLE hbase_table_1(key int, value1 string, value2 int, value3 int)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key,a:b,a:c,d:e"

);

INSERT OVERWRITE TABLE hbase_table_1 SELECT foo, bar, foo+1, foo+2

FROM pokes WHERE foo=98 OR foo=100;

上面的例子中,hive拥有除去可以外的列为三个,value1 value2 value3,对应的HBase表为两个列族,分别为a和d,其中a包括两列(b和c);值的对应关系从左到右一一对应,a列族中的b列对应value1,c列对应value2,d列族的e列对应value3

下面是从HBase中查看的结果:

hbase(main):014:0> describe "hbase_table_1"

DESCRIPTION                                                             ENABLED

{NAME => 'hbase_table_1', FAMILIES => [{NAME => 'a', COMPRESSION => 'N true

ONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_M

EMORY => 'false', BLOCKCACHE => 'true'}, {NAME => 'd', COMPRESSION =>

'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN

_MEMORY => 'false', BLOCKCACHE => 'true'}]}

1 row(s) in 0.0170 seconds

hbase(main):015:0> scan "hbase_table_1"

ROW                          COLUMN+CELL

100                         column=a:b, timestamp=1267740457648, value=val_100

100                         column=a:c, timestamp=1267740457648, value=101

100                         column=d:e, timestamp=1267740457648, value=102

98                          column=a:b, timestamp=1267740457648, value=val_98

98                          column=a:c, timestamp=1267740457648, value=99

98                          column=d:e, timestamp=1267740457648, value=100

2 row(s) in 0.0240 seconds

同一张表在Hive中的查询结果是:

hive> select * from hbase_table_1;

Total MapReduce jobs = 1

Launching Job 1 out of 1

...

OK

100        val_100        101        102

98        val_98        99        100

Time taken: 4.054 seconds

Hive MAP(集合)与Hbase 列族的映射

下面是Hive的MAP数据类型与Hbase列族的映射例子。每行都可以包含不同的列组合,列名与map的可以对应,values与列值对应。

CREATE TABLE hbase_table_1(value map<string,int>, row_key int)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = "cf:,:key"

);

INSERT OVERWRITE TABLE hbase_table_1 SELECT map(bar, foo), foo FROM pokes

WHERE foo=98 OR foo=100;

其中cf表示列族,冒号后面为空,它与Hive表的列value对应,即value的key为cf列族的列,可以通过下面HBase的查询来理解key为列名,value为值的用法。

hbase(main):012:0> scan "hbase_table_1"

ROW                          COLUMN+CELL

100                         column=cf:val_100, timestamp=1267739509194, value=100

98                          column=cf:val_98, timestamp=1267739509194, value=98

2 row(s) in 0.0080 seconds

cf为列族名,val_100为hive表中MAP(集合)的key,100为MAP(集合)中的val_100的值

下面是对应的hive的查询显示结果:

hive> select * from hbase_table_1;

Total MapReduce jobs = 1

Launching Job 1 out of 1

...

OK

{"val_100":100}        100

{"val_98":98}        98

Time taken: 3.808 seconds

注意:MAP(集合)的key必须是string类型,否则会失败,因为key是HBase列的名字;如下的定义将会失败

CREATE TABLE hbase_table_1(key int, value map<int,int>)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key,cf:"

);

FAILED: Error in metadata: java.lang.RuntimeException: MetaException(message:org.apache.hadoop.hive.serde2.SerDeException org.apache.hadoop.hive.hbase.HBaseSerDe: hbase column family 'cf:' should be mapped to map<string,?> but is mapped to map<int,int>)

注意:当hbase.columns.mapping中有“:key,cf:”这样的值,即列族冒号后面为空时,表示Hive中对应的类型为集合map,如果不是,则创建表会失败

CREATE TABLE hbase_table_1(key int, value string)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key,cf:"

);

FAILED: Error in metadata: java.lang.RuntimeException: MetaException(message:org.apache.hadoop.hive.serde2.SerDeException

org.apache.hadoop.hive.hbase.HBaseSerDe: hbase column family 'cf:' should be mapped to map<string,?> but is mapped to string)

hbase.columns.mapping中值类型用法列举

如果没有指定值的类型,比如cf:val,则采用配置hbase.table.default.storage.type的值为数据类型

1.当不配置hbase.table.default.storage.type时,它默认是string,如果有二进制的数据类型,则如下定义:

CREATE TABLE hbase_table_1 (key int, value string, foobar double)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key#b,cf:val,cf:foo#b"

);

2.如果显示的指定hbase.table.default.storage.type为binary时,如果类型有string类型,则需要指定,如:

CREATE TABLE hbase_table_1 (key int, value string, foobar double)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key,cf:val#s,cf:foo",

"hbase.table.default.storage.type" = "binary"

);

cf:val#s 中的#s就表示类型为string,cf:foo没有配置类型,则采用hbase.table.default.storage.type的配置,为binary

添加时间戳

当用hive给HBase的表添加记录时,时间戳默认为当前时间,如果想改变这个值,可以通过设置SERDEPROPERIES属性的可选配置项hbase.put.timestamp,当这个配置项为-1的时候,就是默认策略,即添加记录为当前时间戳

CREATE TABLE hbase_table_1 (key int, value string, foobar double)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key,cf:val#s,cf:foo",

"hbase.table.default.storage.type" = "binary"

"hbase.put.timestamp" = "2013-03-17 09:04:30"

)

主键唯一性

HBase与Hive的表有一个细微的差别,就是HBase的表有一个主键,并且需要唯一,但是Hive没有;如果不能保证这个主键的唯一,则HBase存储的时候,只能存储其中一个,这会导致查询的时候,hive总能找到正确的值,而HBase出来的结果就不确定

如下,在hive中查询:

CREATE TABLE pokes2(foo INT, bar STRING);

INSERT OVERWRITE TABLE pokes2 SELECT * FROM pokes;

-- this will return 3

SELECT COUNT(1) FROM POKES WHERE foo=498;

-- this will also return 3

SELECT COUNT(1) FROM pokes2 WHERE foo=498;

同一张表在HBase中查询,就会出来不确定的结果:

CREATE TABLE pokes3(foo INT, bar STRING)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES (

"hbase.columns.mapping" = ":key,cf:bar"

);

INSERT OVERWRITE TABLE pokes3 SELECT * FROM pokes;

-- this will return 1 instead of 3

SELECT COUNT(1) FROM pokes3 WHERE foo=498;

覆盖(Overwrite)

当执行OVERWRITE时,HBase中已经存在的记录是不会被删除的;但是,如果存在的记录与新纪录的主键(key)是一样的,则老数据会被覆盖

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

二、Hive中的存储格式

样例:

stored as file_format

create table table_name(

.....)

row format...."\t"

stored as file_format;

创建一张表时,可以使用“stored as file_format”来指定该表数据的存储格式,hive中,表的默认存储格式为TextFile。

第一种方式:

CREATE TABLE tt (
id int,
name string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

Hive的默认存储格式就是textfile,可以通过参数hive.default.fileformat进行更改。

第二种方式: 
CREATE TABLE tt2 (
id int,
name string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"

STORED AS TEXTFILE;

第三种方式:

CREATE TABLE tt3 (
id int,
name string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS 
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';

#以上三种方式存储的格式都是TEXTFILE。

file_format:

| SEQUENCEFILE

| TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)

| RCFILE      -- (Note: Available in Hive 0.6.0 and later)

| ORC         -- (Note: Available in Hive 0.11.0 and later)

| PARQUET     -- (Note: Available in Hive 0.13.0 and later)

| AVRO        -- (Note: Available in Hive 0.14.0 and later)

| INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

三、存储格式讲解

以下来详细介绍TEXTFILE、SEQUENCEFILE、RCFILE、ORC等四种储存格式及它们对于hive在存储数据和查询数据时性能的优劣。

TEXTFILE:

只是hive中表数据默认的存储格式,它将所有类型的数据都存储为String类型,不便于数据的解析,但它却比较通用。

不具备随机读写的能力。支持压缩。

SEQUENCEFILE:

这种储存格式比TEXTFILE格式多了头部、标识、信息长度等信息,这些信息使得其具备随机读写的能力。

支持压缩,但压缩的是value。(存储相同的数据,SEQUENCEFILE比TEXTFILE略大)

RCFILE(Record Columnar File):

现在水平上划分为很多个Row Group,每个Row Group默认大小4MB,Row Group内部

再按列存储信息。由facebook开源,比标准行式存储节约10%的空间。

ORC:

优化过后的RCFile,现在水平上划分为多个Stripes,再在Stripe中按列存储。每个Stripe由一个Index Data、一个Row Data、

一个Stripe Footer组成。每个Stripes的大小为250MB,每个Index Data记录的是整型数据最大值最小值、字符串数据前后

缀信息,每个列的位置等等诸如此类的信息。这就使得查询十分得高效,默认每一万行数据建立一个Index Data。ORC存储

大小为TEXTFILE的40%左右,使用压缩则可以进一步将这个数字降到10%~20%。

ORC这种文件格式可以作用于表或者表的分区,可以通过以下几种方式进行指定:

CREATE TABLE ... STORED AS ORC
ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
SET hive.default.fileformat=Orc
The parameters are all placed in the TBLPROPERTIES (see Create Table). They are:

Key

Default

Notes

orc.compress

ZLIB

high level compression (one of NONE, ZLIB, SNAPPY)

orc.compress.size

262,144

number of bytes in each compression chunk

orc.stripe.size

67,108,864

number of bytes in each stripe

orc.row.index.stride

10,000

number of rows between index entries (must be >= 1000)

orc.create.index

true

whether to create row indexes

orc.bloom.filter.columns    ""    comma separated list of column names for which bloom filter should be created
orc.bloom.filter.fpp    0.05    false positive probability for bloom filter (must >0.0 and <1.0)
示例:

create table page_views_orc_zlib
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS ORC 
TBLPROPERTIES("orc.compress"="ZLIB")
as select * from page_views;

For example, creating an ORC stored table without compression:

create table Addresses (
  name string,
  street string,
  city string,
  state string,
  zip int
) stored as orc tblproperties ("orc.compress"="NONE");

PARQUET:

存储大小为TEXTFILE的60%~70%,压缩后在20%~30%之间。

注意:

不同的存储格式不仅表现在存储空间上的不同,对于数据的查询,效率也不一样。因为对于不同的存储格式,执行相同的查询操作,他们访问的数据量大小是不一样的。

我做过一个实验:

数据量一样都是18.1MB的几张表,执行某个操作,使用TEXTFILE存储,访问的数据量19022700,使用RCfile存储,访问的数据量3725391,使用ORC存储,访问的数据量1810082,使用ORC存储并使用ZLIB格式压缩,访问的数据量1257539.

select count(1) from page_views where session_id='B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1';
19022700

select count(1) from page_views_rcfile where session_id='B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1';
3725391

select count(1) from page_views_orc where session_id='B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1';
1810082

select count(1) from page_views_orc_zlib where session_id='B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1';

1257539

不同格式存储相同数据的大小:

-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------

如果要使用TEXTFILE作为hive表数据的存储格式,则在必须先存在一张相同数据的存储格式为TEXTFILE的表table_t0,然后在建表时使用“insert into table table_stored_file_ORC select * from table_t0;”创建。或者使用"create table as select *from table_t0;"创建。

hive存储处理器(StorageHandlers)以及存储格式以及hive与hbase整合相关推荐

  1. Hive文件存储格式和hive数据压缩

    一.存储格式行存储和列存储 二.Hive文件存储格式 三.创建语句和压缩 一.存储格式行存储和列存储 行存储可以理解为一条记录存储一行,通过条件能够查询一整行数据. 列存储,以字段聚集存储,可以理解为 ...

  2. 存储格式在Hive的应用

    介绍 存储按存储方式的不同可分为两类,一是行式存储,二是列式存储,对相同的原文件使用不同的存储格式可以减少不等的存储空间,并且在读取相同的原文件时,拉取的数据量会有较大差别,这样会减少磁盘的IO,从而 ...

  3. CC00023.hadoop——|HadoopHive.V23|——|Hive.v23|Hive存储机制之行列存储及TextFile.v01|

    一.数据存储格式 ~~~ [Hive存储机制之行列存储及TextFile] ~~~ [Hive存储机制ORC] ~~~ [Hive存储机制之Parquet] ~~~ [Hive元数据之文件格式对比] ...

  4. Drill下配置Hive存储插件

    安装好Drill.Hive.Hadoop,且Hive以MySQL作为元数据库 启动hive metastore 必须先启动hive metastore,否则无法添加存储插件 a@DataServer: ...

  5. Hive学习之路 (一)Hive初识

    Hive 简介 什么是Hive 1.Hive 由 Facebook 实现并开源 2.是基于 Hadoop 的一个数据仓库工具 3.可以将结构化的数据映射为一张数据库表 4.并提供 HQL(Hive S ...

  6. hive遍历_从Hive中的stored as file_foramt看hive调优

    一.行式数据库和列式数据库的对比 1.存储比较 行式数据库存储在hdfs上式按行进行存储的,一个block存储一或多行数据.而列式数据库在hdfs上则是按照列进行存储,一个block可能有一列或多列数 ...

  7. Hive相关(概述、环境搭建、命令、API、JDBC、HBase整合等)

    Hive Apache Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的类sql查询功能,可以将sql语句转换为MapReduce任务进行运行.其优 ...

  8. Hive是什么?为什么要用Hive?

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程 Hive是建立在Hadoop上的数据仓库基础构架.对于有一定基础的大数据学习者来讲,Hiv ...

  9. hive相对于oracle的优点,【Hive】Hive面试题

    1.hive的join有几种方式,怎么实现join的? left join --以左表为基准,不符合的值以null值显示 --工作中以left join 居多,大表加载小表的形式 select emp ...

最新文章

  1. 用 nginx 代理 MailChimp API 并支持跨域
  2. 打印系列一:(套打解决方案(支持B/S和C/S))
  3. Java™ 教程(自动装箱和拆箱)
  4. ubuntu 部署 redis 主从节点配置
  5. SQLite数据库管理的相关命令
  6. 40个Android源码学习实例
  7. vue前端项目打包并且在服务器上部署过程
  8. ubuntu16.04 Detectron目标检测库配置(包含GPU驱动,Cuda,Caffee2等配置梳理)
  9. jquery将html转换word,将网页内容导出word文档jQuery插件
  10. Pillow和OpenCV转numpy数组
  11. ecshop 配置服务器文件夹,ECSHOP3.6安装教程【ECSHOP3.6安装教程步骤】ECSHOP3.6安装教程详细讲解-ECSHOP教程网...
  12. 电脑会员管理系统怎么弄,电脑会员卡管理系统怎么弄
  13. 微信小程序实现下拉刷新功能
  14. c语言标识符的开头字母能不能大写,C语言-标识符
  15. Android 6.0-13.0系统兼容
  16. Linux tar过滤文件
  17. 自己动手实现音乐播放器app
  18. java计算机毕业设计商店管理系统源码+数据库+系统+lw文档+mybatis+运行部署
  19. 《编外知识》之“幸存者偏差”
  20. 谷歌自动翻译-谷歌翻译api怎样能打开网页默认自动翻译

热门文章

  1. 电脑如何同时远程控制多台手机
  2. [谨记]女人面前莫谈年龄
  3. android 经典rpg,安卓TOP10:SE经典RPG游戏《最终幻想7》领衔
  4. 部编版三下《燕子》教学反思
  5. ASCII码对照表:
  6. OverlayFS 注册与挂载
  7. lol1月24服务器维护,《lol》1月24日停机到几点 1月24日停机维护内容一览
  8. 线程池的七个核心参数
  9. 一起卷吧,arduino/mixly语音识别模块,10元,可以自定义,提供自制的mixly库
  10. Pycharm2018.2破解版本闪退问题解决办法