文档章节

​《hive编程指南》之hive的数据类型,创建表,外部表,分区,文件类型,字段分割格式。

lixiyuan
 lixiyuan
发布于 2014/03/22 19:48
字数 3499
阅读 3951
收藏 7

hive编程指南》之hive的数据类型,创建表,外部表,分区,文件类型,字段分割格式。

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

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

  [COMMENT table_comment]

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

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

  [ROW FORMAT row_format]

  [STORED AS file_format]

  [LOCATION hdfs_path]

  [TBLPROPERTIES (property_name=property_value, ...)] 

  [AS select_statement] 

 

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

  LIKE existing_table_name

  [LOCATION hdfs_path]

 

data_type

  : primitive_type

  | array_type

  | map_type

  | struct_type

 

primitive_type

  : TINYINT

  | SMALLINT

  | INT

  | BIGINT

  | BOOLEAN

  | FLOAT

  | DOUBLE

  | STRING

 

array_type

  : ARRAY < data_type >

 

map_type

  : MAP < primitive_type, data_type >

 

struct_type

  : STRUCT < col_name : data_type [COMMENT col_comment], ...>

 

row_format

  : DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]

        [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

  | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

 

file_format:

  : SEQUENCEFILE

  | TEXTFILE

  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

这个是我从hivedocs里面复制出来的,因为我感觉我怎么写也没人家写得好。我最多无非就是在下面举几个例子,说明一下使用的方法。

在任意的地方写比如hive -e ‘show databases’

会执行单引号里面的命令,然后执完以后会退出,

hive -e ‘show databases’ -S

加了-S会不会有额外的输出。

首先先看一下数据类型:

TINYINT SMALLINT INT BIGINT当然了都是int类型的,只是范围不一样。

BOOLEAN

FLOAT

DOUBLE

STRING

BINARY

TIMESTAMP

后两种都是在hive0.8版本后才有的。当然了还有一些其他的类型,我们后面用到再说。

 hadoop fs -ls /user/hive/warehouse这个下面保存的是我们表的实际的数据,这个目录是我们默认的目录。然后表的结构之类的是保存在metadata当中。而metadata又保存在我们的MySQL当中。

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name  [LOCATION hdfs_path]

create external table tab_name location /tmp/ext/tab_name;

EXTERNAL:作用是可以指定其他目录保存在hdfs中,不然的话就只能保存在默认的位置了。

hdfs_path:是一个已经存在的目录。不能直接是一个目录,还得有上级的这么一个目录。

然后我们只要往tab_nameput我们的文件,我们执行

select * from tab_name就会看到数据了.

 

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name

[(col_name data_type [COMMENT col_comment], ...)] //列名:数据类型:列的注释

[COMMENT table_comment]//整个表的注释

[PARTITIONED BY//接着解释一下

举个例子

drop table tab_name;

create table tab_name (id int , name string) partitioned by (aa string) row format delimited fields terminated by ,location /tmp/ext/tab_name;

load data local inpath /a.txt into table tab_name partition(aa=1);

load data local inpath '/b.txt' into table  user partition (aa="2");

然后注意观察dfs -ls /tmp/ext/tab_name下有什么?

我们发现有一个叫aa=1目录,整个目录下存着刚刚我们load的文件a.txt;

然后我们写select * from tab_name where aa=1;

就会查出来该目录下的数据

如果是select * from tab_name where aa=2;

那么查出来的就是对应的目录的下的数据

那么如果是select * from tab_name不写的话

会把这个表的所有的数据都会查出来。

CLUSTERED BY

这个会是什么作用呢?

我们数据还是使用我们话单业务产生的数据,

drop table tab_cdr;

create table tab_cdr(oaddr string,oareacode string,daddr string,dareacode string,ts string,type string) row format delimited fields teminated by ,;

load data local inpath /var/www/hadoop/test/output/xx.txt into table tab_cdr;(加进去了十万条数据)

接着我们创建

set hive.enforce.bucketing=true;//强制使用

create table tab_cdr_buc (oaddr string,oareacode string,daddr string,dareacode string,ts string,type string) clustered by (oaddr ) into 10 buckets;

 

然后我做一个操作

insert into table tab_cdr_buc select * from tab_cdr;

然后我们观察

/tmp/ext/tab_cdr_buc

它下面会有十个文件,规则是根据oaddr的。

这样做的目的就是为了提高mapreduce的效率。

 

总之我们大体的思路是:把描述信息存到mysql中,这样我们随时随地在不同主机上也可以访问hive表,然后我们把文件要存到hdfs上,这样就利用到了集群的威力。这些才是我们的目的。

Hive其实跟hibernate很像的,一个表最主要的就是表的描述信息,表的描述信息存在metadata里面,而我们的metadata存储在MySQL的数据库里面,这个数据库的名字会在配置的时候配置。

比如我此次的数据库的名字叫lixiyuanhive,然后路径就是(/var/lib/mysql/lixiyuanhive/)我们表的描述信息室在这儿的。

前面说的我们把文件存储在HDFS上,其有默认的路径是/user/hive/warehouse;当然了我们在建表的时候也可以自己指定路径。

 

data_type :

primitive_type //基本数据类型

array_type

map_type

struct_type primitive_type ://基本数据类型有

TINYINT

SMALLINT

INT

BIGINT

BOOLEAN

FLOAT

DOUBLE

STRING

BINARY

TIMESTAMP

 

array_type : ARRAY < data_type > //它的意思是array里面可以放data_type类型

那么data_type的类型有哪些呢,上面有。

map_type : MAP < primitive_type, data_type >//看出来这个需要我们定义key value

 

struct_type : STRUCT < col_name : data_type [COMMENT col_comment], ...>

union_type:UNIONTYPE<data_type,data_type,....>

那么接着我们看array怎么使用:

drop table tab_array;

create table tab_array(a array<string> , b array<int>)

row format delimited fields terminated by \t

collection items terminated by ,;

然后看看我们准备的数据array.txt

Rob,bob,stever    1,2,3

Amy,ady 11,22

Jac 11,22,33,44,55

 

load data local inpath /home/robby/array.txt into table tab_array;

当然了我们可以select * from tab_array一下

存储的方式跟我们在文本里面的时候差不多

如果我们要想访问集合那么

select a[0] from tab_array;

Rob,bob,stever    1,2,3//0 1 2

Amy,ady 11,22 //0 1

Jac 11,22,33,44,55//0

我们select a[0] from tab_array;的结果就是查到0

Rob

Amy

Jac

那么hive也提供了一些函数来给我们使用

select * from tab_array where array_contains(b,22);

//我们查找b列中包含22字段的行。

那么结果应该是后两行

insert into table tab_array select array(oaddr,daddr), array(0) from tab_cdr;

//这句话主要是从其他表中获取数据然后插到我们的表中,array(oaddr,daddr)那么我们的a字段是string,然后我们选用了tab_cdr的两个字段,然后tab_cdr里面没有int类型的,所以我们就填0

我们查看一下:

select * from tab_cdr limit 10;

接下来我们看看map是这样使用的

drop table tab_map;

create table tab_map(name string,info map<string,string>)

row format delimited fields terminated by \t

collection items terminated by ,

map keys terminated by :;

那么我们有一个map.txt的文件为:

Rob age:30,tel:4234323

Amy age:22,tel:43243

Bob age:33,tel:432434,addr:shanghai

接着:

load data local inpath /home/robby/map.txt into table tab_map;

那么我们怎么访问map的字段呢?

select info[age] from tab_map;

我们如何从其它表中读取数据到map表中?

insert into table tab_map select oaddr,map(oareacode,oareacode,daddr,daddr) from tab_cdr;

结论:map里面是可以填任意多个的,不管你当时定义的几个

接下来我们看看struct是怎么使用?(个人感觉用的多)

drop table tab_st;

create table tab_st(name string,info struct<age:int,tel:string,addr:string>)

row format delimited fields terminated by \t

collection items terminated by ,;

那么我们有准备好了的struts.txt数据为:

Rob 30,432423

Amy 17,432423,beijing

Bob 28,213243,shanghai

然后加载数据:

load data local inpath /home/robby/struts.txt into table tab_st;

那么我们怎么访问struct里面的数据:

select info.age from tab_st;

insert into table tab_st select oaddr,name_struct(age,0,tel,daddr,addr,dareacode) from tab_cdr;

结论:跟map不一样,当时strust内定义了几个就得插入几个,当然了没有的可以为null

四中文件类型:

SEQUENCEFILE :压缩后可以进行mapreduce任务计算的

TEXTFILE:普通的文件

RCFILEfacebook弄出来的,针对hive的,性能比SEQUENCEFILE 还要好

INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname:自定义的类型。

举个例子:

我们有一个a.txt的文件,里面存了内容,然后我们用gzip命令压缩一下,然后产生一个叫

a.txt.gz的文件.

然后我们在hive里面创建表

drop table tab_name;

create table tab_name(id int,name string) row format delimited fields terminated by ,;

创建好后:

load data local inpath /home/robby/a.txt.gz into table tab_name;

接着我们观察一下:

hive下输入:

dfs -ls /user/hive/warehouse/tab_name;

我们发现,他直接存储了我们的压缩文件a.txt.gz;

那么我们直接可以用sql语句访问我们的表(因为hive会做解压的工作)

select * from tab_name;

我们普通文件的压缩后不能直接进行mapreduce任务。这个不好的地方。

所以我们不能用压缩的文本文件做为hive的存储。同时呢我们最好也不要用文本文件作为文件的存储,因为它占的地方大。

因此呢,我们就引出了上面的两种格式

blog.cdsn.net/wh62592855/atricle/details/6409680

一种是:SEQUENCEFILE SEQUENCEFILE跟普通的文本文件的压缩的区别是,普通的文本文件的压缩是针对整个文件的压缩,SEQUENCEFILE针对的是每一部分的压缩。那么是按行来分的。

一种是:RCFILE,那么RCFILE也是针对每一部分的压缩,那么是按行分和按列分的混合体,先水平,再垂直。(一般我们用的压缩算法是LOZO)

LOZO的安装

1, sudo apt-get install liblzo2-dev 

 

2, sudo apt-get install lzop 

 

3, https://github.com/kevinweil/hadoop-lzo

        a, git clone https://github.com/kevinweil/hadoop-lzo  (不会可以不 用这种)

        b, download *.tar.gz

 

4, 修改 build.xml

    搜索javah

    加上<classpath refid="classpath"/>

              <javah classpath="${build.classes}"

           destdir="${build.native}/src/com/hadoop/compression/lzo"

           force="yes"

           verbose="yes">

      <class name="com.hadoop.compression.lzo.LzoCompressor" />

      <class name="com.hadoop.compression.lzo.LzoDecompressor" />

      <classpath refid="classpath"/>

    </javah>

 

5, export CFLAGS=-m32

   export CXXFLAGS=-m32  

   ant compile-native tar

 

6, 拷贝 build/hadoop-lzo-0.4.15.jar $HADOOP_HOME/lib

 

7, 修改core-site.xm

    <property>  

           <name>io.compression.codecs</name> 

           <value>

org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.GzipCodec,org.       apache.hadoop.io.compress.BZip2Codec,com.hadoop.compression.lzo.LzopCodec

      </value>

    </property>

     

    <property> 

           <name>io.compression.codec.lzo.class</name> 

           <value>com.hadoop.compression.lzo.LzoCodec</value> 

    </property>

 

8, cp build/native/Linux-i386-32/lib/libgplcompression.so $HADOOP_HOME/lib/native/Linux-i386-32/

然后重启hadoop就可以了。

接着,我们举例看上面讲的几个文件类型是怎么使用的,首先要准备数据

那么数据我们还是用话单例子的数据。

1:首先我们创建一个普通文本文件类型存储的表

drop table tab_cdr;

create table tab_cdr(oaddr string,oareacode string,daddr string,dareacode string,ts string,type string) row format delimited fields teminated by ,;

load data local inpath /var/www/hadoop/test/output/b.txt into table tab_cdr;(加进去了二十万条数据)

当然了,我们可以观察一下:

hive> dfs -ls /user/hive/warehouse/tab_cdr/

那么我们看到大小为9800000

2:我们用SEQUENCEFILE来存储

首先我们设置一下参数:

set hive.exec.compress.output=true;

set mapred.output.compress=true;

set mapred.output.copression.type=BLOCK://压缩的方式有三种,按份压缩,按行压缩,按block压缩

set mapred.output.compression.codec=org.apache.hadoop.io.compress.LzoCodec;

drop table tab_cdr_seq;

create table tab_cdr_seq(oaddr string,oareacode string,daddr string,dareacode string,ts string,type string) row format delimited fields teminated by , stored  as sequencefile;

insert overwrite table tab_cdr_seq select * from tab_cdr;(会启mapreduce任务的)

用了overwrite会把原来的数据线清空。

然后我们观察:

hive> dfs -ls /user/hive/warehouse/tab_cdr_seq/

我们看到这个文件的大小变为:4379300

当然了这样的压缩比没有我们直接压缩文本好,但是好处就是我们能直接对压缩后的文件进行mapreduce任务。

3:怎样使用RCFILE

set hive.exec.compress.output=true;

set mapred.output.compress=true;

set mapred.output.copression.type=BLOCK:

set mapred.output.compression.codec=org.apache.hadoop.io.compress.LzoCodec;

drop table tab_cdr_rc;

create table tab_cdr_rc(oaddr string,oareacode string,daddr string,dareacode string,ts string,type string) row format delimited fields teminated by , stored  as rcfile;

insert overwrite table tab_cdr_rc select * from tab_cdr;(会启mapreduce任务的)

那么这个跟我们的上面那个是非常像的。

观察:

hive> dfs -ls /user/hive/warehouse/tab_cdr_rc/

我们看到文件的大小为:3605100

 

如果从压缩比上看的话,sequencefile的差别不会太大,但是执行mapreduce的话,从总体上看,rcfile的要好一些,所以如果项目开发的话,我们应该可以优先使用rcfile

此外:比如我们写这样的语句

Select oaddr from tab_cdr where ofd=xxxx

就是说我们有这样的语句只是查到部分字段的,那么我们如果用的是rcfile存储的话,我们这个语句的mapreduce会跳过不相关的列,这样的话我们的效率很高。

join

举例:当然了这个例子跟我们话单的业务表示联合起来的,我们当时话单业务的表里面,也有归属地这一栏,但是当时我们只是显示了010等之类的数字,并没有对应起来。

drop table tab_areaname;

create table tab_areaname(areacode string,cityname string)

row format delimited fields terminated by ',';

准备文件/usr/local/areaname.txt内容为:

010,beijing

021,shanghai

020,guangzhou

加载数据:

load data local inpath '/usr/local/areaname.txt' overwrite into table tab_areaname;

然后我们创建一个表,这个表的目的是用来存查询得到的结果的。

drop table tab_res1;

create table tab_res1(oaddr string,cityname string);

那么我们开始来做这个操作:

insert overwrite table tab_res1

select b.oaddr , a.cityname from tab_areaname a

join tab_cdr b

on a.areacode=b.oarecode;

//上面一共是一条语句,注意的是,我们做连表查询的时候,我们把数据量小的那张表写到join的左边,这样是为了效率好(原因是在做mapreduce的时候,在reduce阶段hive会把join左边的表加载到我们的内存中)

接下来咱们可以查找一下:

select * from tab_res1 limit 100;

当然了也可以看每个城市有多少个话单

select cityname,count(*) from tab_res1 group by cityname;

map join

insert overwrite table tab_res1

select /*+  MAPJOIN*/ b.oaddr , a.cityname from tab_areaname a

join tab_cdr b

on a.areacode=b.oarecode;

那么顾名思义,我们做这个连表是在map任务的时候就连了,没有经过reduce的计算;

这样的话,效率会高一些,当然了会有使用的限制的,得某一张表的数据量要小。

 

多余两张表的联合

drop table tab_user;

create table tab_user(addr string);

insert overwrite table tab_user select distinct(oaddr) from tab_cdr limit 100;

//插入的数据是从tab_cdr里面选择的不重复的100个主机号码

insert overwrite table tab_res1

select b.oaddr , a.cityname from tab_areaname a

join tab_cdr b

on a.areacode=b.oarecode

join tab_user c

on b.oaddr=c.addr;

比较这两句的话,后面这句的效率更高一些

我们做怎样的操作?比如我们想查询tab_cdr里面的一些字段,但是我不想操作所有的

我只是想查找部分用户的,而这部分用户保存在tab_user里面,那么我们要像后面那样写。

select oaddr,oareacode from tab_cdr a join tab_user b on a.oaddr=b.addr;

select oaddr,oareacode from tab_cdr a left semi  join tab_user b on a.oaddr=b.addr;

 

 

 

 

 

 

 

 

 

 

 


© 著作权归作者所有

lixiyuan
粉丝 55
博文 13
码字总数 21543
作品 0
昌平
程序员
私信 提问
HAWQ技术解析(九) —— 外部数据

HAWQ不但可以读写自身系统中的表,而且能够访问HDFS、Hive、HBase等外部系统的数据。这是通过一个名为PXF的扩展框架实现的。大部分外部数据是以HAWQ外部表的形式进行访问的,但对于Hive,除外...

wzy0623
2017/03/23
0
0
【Hive】Hive基本操作及示例

1、数据库操作 (1)创建数据库 (2)查看数据库 (3)使用数据库 (4)查看数据库字段格式 (5)删除数据库 2、表操作 (1)创建表 (2)加载数据到表 LOCAL:从本地文件加载数据到hive表;...

gongxifacai_believe
2018/04/29
0
0
Hadoop学习笔记:数据分析引擎Hive

概述 Hive是一个构建在Hadoop之上的数据仓库,和传统的数据仓库一样主要用来访问和管理数据,提供了类SQL查询语言;和传统数据仓库不一样的是可以处理超大规模的数据,可扩展性和容错性非常强...

GaryBigPig
01/16
0
0
Hadoop实战:Hive操作使用

Hive表类型测试 内部表 数据准备,先在HDFS上准备文本文件,逗号分割,并上传到/test目录,然后在Hive里创建表,表名和文件名要相同。 $ cat /tmp/table_test.csv1,user1,10002,user2,20003...

问题终结者
01/14
15
0
《Hadoop权威指南》书摘-关于Hive

转载请注明出处 独立博客:http://wangnan.tech 简书:http://www.jianshu.com/u/244399b1d776** 知乎:https://zhuanlan.zhihu.com/ghoststories 简介 hive是一个构建在hadoop上的数据仓框架...

GhostStories
2018/08/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Replugin借助“UI进程”来快速释放Dex

public static boolean preload(PluginInfo pi) { if (pi == null) { return false; } // 借助“UI进程”来快速释放Dex(见PluginFastInstallProviderProxy的说明) return PluginFastInsta......

Gemini-Lin
今天
4
0
Hibernate 5 的模块/包(modules/artifacts)

Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。 模块名称 说明 hibernate-core 这个是 Hibernate 的主要(main (core))模块。定义...

honeymoose
今天
4
0
CSS--属性

一、溢出 当内容多,元素区域小的时候,就会产生溢出效果,默认是纵向溢出 横向溢出:在内容和容器之间再套一层容器,并且内部容器要比外部容器宽 属性:overflow/overflow-x/overflow-y 取值...

wytao1995
今天
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
7
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部