HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

1.上传tar包
这里我上传的是apache-hive-1.2.1-bin.tar.gz

2.解压

        mkdir -p /home/tuzq/software/hive/

tar -zxvf apache-hive-1.2.1-bin.tar.gz  -C /home/tuzq/software/hive/
3.安装mysql数据库(切换到root用户)(装在哪里没有限制,只有能联通hadoop集群的节点)

       mysql安装可以参考:http://blog.csdn.net/tototuzuoquan/article/details/52711808


mysql安装仅供参考,不同版本mysql有各自的安装流程

rpm -qa | grep mysql
rpm -e mysql-libs-5.1.66-2.el6_3.i686 --nodeps
rpm -ivh MySQL-server-5.1.73-1.glibc23.i386.rpm 
rpm -ivh MySQL-client-5.1.73-1.glibc23.i386.rpm 
修改mysql的密码
/usr/bin/mysql_secure_installation
(注意:删除匿名用户,允许用户远程连接)
登陆mysql
mysql -u root -p


4.配置hive

(a)配置HIVE_HOME环境变量

vim /etc/profile

export JAVA_HOME=/usr/local/jdk1.8.0_73
export HADOOP_HOME=/home/tuzq/software/hadoop-2.8.0
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HIVE_HOME=/home/tuzq/software/hive/apache-hive-1.2.1-bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
source /etc/profile

将hadoop集群中的其它的环境变量也配置成这种,如我的hadoop集群是hadoop1,hadoop2,hadoop3,hadoop4,hadoop5。这些我都配置成了上面的同样的环境变量


 [root@hadoop1 conf]# cd $HIVE_HOME/conf

 [root@hadoop1 conf]# mv hive-env.sh.template hive-env.sh

 [root@hadoop1 conf]# vi $HIVE_HOME/conf/hive-env.sh

配置其中的$hadoop_home

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

(b)配置元数据库信息   

在$HIVE_HOME/conf文件加下,创建hive-site.xml文件,文件内容如下:

vi  hive-site.xml 

添加如下内容:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://hadoop10:3306/hive?createDatabaseIfNotExist=true</value>
        <description>JDBC connect string for a JDBC metastore</description>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.jdbc.Driver</value>
        <description>Driver class name for a JDBC metastore</description>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionUserName</name>
        <value>root</value>
        <description>username to use against metastore database</description>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>root</value>
        <description>password to use against metastore database</description>
    </property>
</configuration>



5.安装hive和mysq完成后,将mysql的连接jar包拷贝到$HIVE_HOME/lib目录下

       HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令


如果出现没有权限的问题,在mysql授权(在安装mysql的机器上执行)
mysql -uroot -p
#(执行下面的语句  *.*:所有库下的所有表   %:任何IP地址或主机都可以连接)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;


6. 如果hadoop使用的是2.6.4版本的,会存在Jline包版本不一致的问题,需要拷贝hive的lib目录中jline.2.12.jar的jar包替换掉hadoop中的 

/home/hadoop/app/hadoop-2.6.4/share/hadoop/yarn/lib/jline-0.9.94.jar


如果是hadoop-2.8.0版本的,发现在/home/tuzq/software/hadoop-2.8.0/share/hadoop/yarn/lib下没有jline-2.12.jar


下面的命令是查看HIVE中的jline的版本号的方式:

[root@hadoop1 lib]# cd $HIVE_HOME/lib
[root@hadoop1 lib]# ls jline-2.12.jar 
jline-2.12.jar
[root@hadoop1 lib]#


将创建好的hive远程拷贝到hadoop2,hadoop3,hadoop4,hadoop5服务器上的相同位置

scp -r /home/tuzq/software/hive* root@hadoop2:/home/tuzq/software/

scp -r /home/tuzq/software/hive* root@hadoop3:/home/tuzq/software/

scp -r /home/tuzq/software/hive* root@hadoop4:/home/tuzq/software/

scp -r /home/tuzq/software/hive* root@hadoop5:/home/tuzq/software/


启动hive
bin/hive

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

执行完成之后,到mysql中进行查看,发现现象如下:

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令


另外:通过Hive beeline也可以访问hive:

---Beeline要与HiveServer2配合使用,支持嵌入式模式和远程模式

--启动HiverServer2 ,./bin/hiveserver2

命令模式:

hive --service hiveserver2 --hiveconf hive.server2.thrift.port=10001

最后面的port可以更改,hiveserver2默认的端口号是10000。beeline的退出方式:!quit

[root@hadoop1 apache-hive-1.2.1-bin]# bin/beeline 
Beeline version 1.2.1 by Apache Hive
beeline> !connect jdbc:hive2://hadoop1:10000
Connecting to jdbc:hive2://hadoop1:10000
Enter username for jdbc:hive2://hadoop1:10000: 
Enter password for jdbc:hive2://hadoop1:10000: 
Connected to: Apache Hive (version 1.2.1)
Driver: Hive JDBC (version 1.2.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://hadoop1:10000> show databases;
+----------------+--+
| database_name  |
+----------------+--+
| default        |
| mydb           |
| userdb         |
| userdb2        |
| userdb3        |
+----------------+--+
5 rows selected (0.709 seconds)
0: jdbc:hive2://hadoop1:10000>


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


查看有哪些表:

[root@hadoop1 apache-hive-1.2.1-bin]# bin/hive
Logging initialized using configuration in jar:file:/home/tuzq/software/hive/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
hive> show databases;
OK
default
Time taken: 0.98 seconds, Fetched: 1 row(s)
hive> create database db1; #创建一个数据库
OK
Time taken: 0.239 seconds
hive> show databases; #显示所有的数据库
OK
db1
default
Time taken: 0.015 seconds, Fetched: 2 row(s)
hive>


然后进入hdfs上进行查看http://hadoop1:50070/ :

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令


6.建表(默认是内部表)

        use db1;

      

hive> create table trade_detail(id bigint,account string,income double,expense double,time string) row format delimited fields terminated by '\t';

进入hdfs进行查看:

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令



select nation, avg(size) from beauties group by nation order by avg(size);

        注意:如果在此过程中获取的结果是NULL的,说明创建表的时候需要加上:lines terminated by '\n' 


        如果想通过drop table if exists table_name删除表时删除不了,请换$HIVE_HOME/lib中的mysql-connector-java。比如我使用的是:mysql-5.7.15-linux-glibc2.5-x86_64.tar.gz,开始的时候使用的是mysql-connector-java-5.1.7.jar,最后换成mysql-connector-java-5.1.38.jar,发现就可以drop表了。


查看database,删除数据库

以下是使用CASCADE查询删除数据库。这意味着要全部删除相应的表在删除数据库之前:

hive> show databases;
OK
default
mydb
userdb
userdb2
userdb3

Time taken: 0.962 seconds, Fetched: 5 row(s)
hive> drop database IF EXISTS  userdb3 CASCADE;
OK
Time taken: 0.203 seconds

hive> show databases;
OK
default
mydb
userdb
userdb2

Time taken: 0.014 seconds, Fetched: 4 row(s)
hive>


修改表

Alter Table语句,它是在Hive中用来修改表的

语法:

ALTER TABLE name RENAME TO new_name
ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...])
ALTER TABLE name DROP [COLUMN] column_name
ALTER TABLE name CHANGE column_name new_name new_type
ALTER TABLE name REPLACE COLUMNS (col_spec[, col_spec ...])

hive> show tables;
OK
testhivedrivertable
Time taken: 0.029 seconds, Fetched: 1 row(s)
hive> ALTER TABLE testhivedrivertable RENAME To testHive;
OK
Time taken: 0.345 seconds
hive> show tables;
OK
testhive
Time taken: 0.031 seconds, Fetched: 1 row(s)


修改列中列的类型:

hive> desc testhive;
OK
key                 int                                    
value              string                                  
Time taken: 0.161 seconds, Fetched: 2 row(s)

hive> ALTER TABLE testhive CHANGE value value Double;
OK
Time taken: 0.251 seconds
hive> desc testhive;
OK
key                 int                                    
value               double                                  
Time taken: 0.126 seconds, Fetched: 2 row(s)
hive>


为表添加一列:

hive> ALTER TABLE testhive ADD COLUMNS (
    > dept STRING COMMENT 'Departname name');
OK
Time taken: 0.219 seconds
hive> desc testhive;
OK
key                 int                                    
value               double                                  
dept                 string               Departname name     
Time taken: 0.09 seconds, Fetched: 3 row(s)
hive>


删除表

删除表的语法是:

hive>DROP TABLE IF EXISTS testhive;


创建分区

Hive组织表到分区。它是将一个表到基于分区列,如日期,城市和部门的值相关方式。使用分区,很容易对数据进行部分查询。很容易对数据进行部分查询。

表或分区是细分成桶,以提供额外的结构,可以使用更搞笑的查询的数据。桶的工作是基于表的一些列的散列函数值。


添加分区,语法是:

ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec
[LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;
partition_spec:
:(p_column = p_col_value, p_column = p_col_value, ...)


先做准备工作,创建表:

CREATE TABLE IF NOT EXISTS employee (eid int, name String,
    destination String)
    partitioned by (salary String)
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '\t'
    LINES TERMINATED BY '\n'
    STORED AS TEXTFILE;

hive>desc employee;

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

经过上面步骤,表已经添加了一个分区


导入数据:

[root@hadoop1 hivedata]# cat /home/tuzq/software/hivedata/sample.txt 
1201 pal 45000 Technical manager
1202 Manisha 45000 Proof reader
[root@hadoop1 hivedata]#

将上面的数据导入到分区:

LOAD DATA LOCAL INPATH '/home/tuzq/software/hivedata/sample.txt' INTO TABLE employee PARTITION(salary = '45000');

注意上满的红字,表示将数据到如45000这个分区中。

在hdfs上的效果如下:

http://hadoop1:50070/explorer.html#/user/hive/warehouse/userdb.db/employee

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令


下面再次给表添加另外一个分区值:

ALTER TABLE employee ADD PARTITION (salary ='40000') location '/40000/part40000';

添加location之后,它在HDFS上的位置将会改变,将会到/40000/part40000中。效果图如下:

http://hadoop1:50070/explorer.html#/40000/part40000

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令


创建2个分区的方式:

双分区建表语句:create table table_name (id int, content string) partitioned by (dt string, hour string);双分区表,按天和小时分区,在表结构中新增加了dt和hour两列。
先以dt为文件夹,再以hour子文件夹区分


查看分区语句:

hive> show partitions employee;
OK
salary=40000
salary=45000
Time taken: 0.088 seconds, Fetched: 2 row(s)
hive>


再如:

建分区表
hive> create table td_part(id bigint,account string,income double,expenses double,time string) partitioned by (logdate string)row format delimited fields terminated by '\t';
       OK
       Time taken: 0.114 seconds
       hive> show tables;
       OK
       td_part
       trade_detail
       Time taken: 0.021 seconds, Fetched: 2 row(s)

       hive>


建外部表
create external table td_ext(id bigint, account string, income double, expenses double, time string) row format delimited fields terminated by '\t' location '/td_ext';


7.创建分区表
普通表和分区表区别:有大量数据增加的需要建分区表
hive> create table book(id bigint,name string) partitioned by (pubdate string) row format delimited fields terminated by '\t';
OK
Time taken: 0.108 seconds
hive> show tables;
OK
book
td_part-
trade_detail
Time taken: 0.02 seconds, Fetched: 3 row(s)
hive>



分区表加载数据
load data local inpath './book.txt' overwrite into table book partition (pubdate='2010-08-22');

load data local inpath '/root/data.am' into table beauty partition (nation="USA");


创建视图和索引

视图在Hive的用法和SQL视图用法相同。它是一个标准的RDBMS概念。我们可以在视图上执行DML操作。

创建视图的语法如下:

CREATE VIEW [IF NOT EXISTS] view_name [(column_name [COMMENT column_comment], ...) ]
[COMMENT table_comment]
AS SELECT ...


hive> desc employee;
OK
eid                 int                                    
name                 string                                  
destination         string                                  
salary               string                                  
 
# Partition Information  
# col_name             data_type           comment             
 
salary               string                                  
Time taken: 0.08 seconds, Fetched: 9 row(s)
hive> create VIEW emp_45000 AS
    > SELECT * FROM employee
    > WHERE salary = 45000;

删除一个视图的方式:

hive > DROP VIEW emp_45000;


创建索引:

创建索引的语法如下:

CREATE INDEX index_name
ON TABLE base_table_name (col_name, ...)
AS 'index.handler.class.name'
[WITH DEFERRED REBUILD]
[IDXPROPERTIES (property_name=property_value, ...)]
[IN TABLE index_table_name]
[PARTITIONED BY (col_name, ...)]
[
   [ ROW FORMAT ...] STORED AS ...
   | STORED BY ...
]
[LOCATION hdfs_path]
[TBLPROPERTIES (...)]




HIVE的四种数据导入方式:

HIVE的几种常见的数据导入方式,这里介绍四种:

(1)、从本地文件系统中导入数据到Hive表;

(2)、从HDFS上导入数据到Hive表

(3)、从别的表中查询出相应的数据并导入到Hive表中。

(4)、在创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中。

一、从本地文件系统中导入数据到Hive

先在Hive里面创建好表,如下:

hive> create table wyp(id int,name string,age int,tel string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' lines terminated by '\n' STORED AS TEXTFILE;

注意上面的:ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '      注意这个分割的字符,若是设置的不好,最后能够插入数据库,但是select出来的结果是NULL.


这个表很简单,只有四个字段。本地文件系统里有/home/tuzq/software/hive/apache-hive-1.2.1-bin/wyp.txt 文件,内容如下:
[root@hadoop1 apache-hive-1.2.1-bin]# pwd
/home/tuzq/software/hive/apache-hive-1.2.1-bin
[root@hadoop1 apache-hive-1.2.1-bin]# cat wyp.txt 
1 wyp 25 13188888888888
2 test 30 13888888888888
3 zs 34 899314121
[root@hadoop1 apache-hive-1.2.1-bin]#


wyp.txt文件中的数据列之间使用空格分割的,可以通过下面的语句将这个文件里面的数据导入到wyp表里面,操作如下:

hive> load data local inpath '/home/tuzq/software/hive/apache-hive-1.2.1-bin/wyp.txt' into table wyp;
Loading data to table default.wyp
Table default.wyp stats: [numFiles=1, totalSize=67]
OK
Time taken: 0.35 seconds
hive> select * from wyp;
OK
1 wyp 25 13188888888888
2 test 30 13888888888888
3 zs 34 899314121
Time taken: 0.086 seconds, Fetched: 3 row(s)
hive>


这样就将wyp.txt里面的内容导入到wyp表里面去了,可以到wyp表的数据目录下查看,http://hadoop1:50070/explorer.html#/user/hive/warehouse/db1.db:

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令

二、HDFS上导入数据到hive

    从本地文件系统中将数据导入到Hive表的过程中,其实是先将数据临时复制到HDFS的一个目录下(典型的情况是复制到上传用户的HDFS的目录下,比如/根目录下),然后在将数据从那个临时目录下移动(注意,这里说的是移动,不是复制)到对应的数据目录里面。既然如此,那么Hive肯定支持将数据直接从HDFS上的一个目录移动到相应Hive表的数据目录下,假设有这个文件/add.txt,具体的操作如下:

[root@hadoop1 apache-hive-1.2.1-bin]# ls

add.txt  bin  book.txt  conf  examples  hcatalog  lib  LICENSE  NOTICE  README.txt  RELEASE_NOTES.txt  scripts  wyp.txt

[root@hadoop1 apache-hive-1.2.1-bin]# vim add.txt

 [root@hadoop1 apache-hive-1.2.1-bin]# hdfs dfs -put add.txt /

[root@hadoop1 apache-hive-1.2.1-bin]# hdfs dfs -ls /

Found 4 items-rw-r--r--   3 root supergroup         67 2017-06-11 11:34 /add.txt

-rw-r--r--   3 root supergroup       3719 2017-06-10 12:11 /kms.sh

drwx-wx-wx   - root supergroup          0 2017-06-10 22:06 /tmp

drwxr-xr-x   - root supergroup          0 2017-06-10 22:27 /user

[root@hadoop1 apache-hive-1.2.1-bin]# hdfs dfs -cat /add.txt

4 wyp 

25 131888888888885 test 30 138888888888886 zs 34 899314121

[root@hadoop1 apache-hive-1.2.1-bin]#

上面是需要插入数据的内容,这个文件时存放在HDFS上/add.txt里面的(和一中提到的不同,一中提到的文件是存放在本地文件系统上,并且在load数据的时候加上了关键字local),我们可以同通过下面的命令将这个文件里面的内容导入到Hive表中,具体操作如下:

hive> select * from wyp;

OK1 wyp

25 131888888888882 test 30 138888888888883 zs 34 899314121

Time taken: 0.086 seconds, Fetched: 3 row(s)

hive> load data inpath '/add.txt' into table wyp;

Loading data to table default.wypTable default.wyp stats: [numFiles=2, totalSize=134]OKTime taken: 0.283 seconds

hive> select * from wyp;

OK4 wyp

25 131888888888885 test

30 138888888888886 zs

34 8993141211 wyp

25 131888888888882 test

30 138888888888883 zs

34 899314121

Time taken: 0.076 seconds, Fetched: 6 row(s)

hive> 

从上面的执行结果我们可以看到,数据的确导入到wyp表中了!请注意 load data inpath '/add.txt' into table wyp; 里面没有local这个单词,这个是和一中的区别。    

三、从别的表中查询出相应的数据并导入到Hive表中

假设Hive中有test表,其建表语句如下所示:

  1. hive> create table test(
  2.     > id int, name string
  3.     > ,tel string)
  4.     > partitioned by
  5.     > (age int)
  6.     > ROW FORMAT DELIMITED
  7.     > FIELDS TERMINATED BY '\t'
  8.     > STORED AS TEXTFILE;
  9. OK
  10. Time taken: 0.261 seconds
复制代码

大体和wyp表的建表语句类似,只不过test表里面用age作为了分区字段。对于分区,这里在做解释一下:
分区:在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如wyp表有dt和city两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse/dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。

下面语句就是将wyp表中的查询结果并插入到test表中:
  1. hive> insert into table test
  2.     > partition (age='25')
  3.     > select id, name, tel
  4.     > from wyp;
  5. #####################################################################
  6.            这里输出了一堆Mapreduce任务信息,这里省略
  7. #####################################################################
  8. Total MapReduce CPU Time Spent: 1 seconds 310 msec
  9. OK
  10. Time taken: 19.125 seconds

  11. hive> select * from test;
  12. OK
  13. 5       wyp1    131212121212    25
  14. 6       wyp2    134535353535    25
  15. 7       wyp3    132453535353    25
  16. 8       wyp4    154243434355    25
  17. 1       wyp     13188888888888  25
  18. 2       test    13888888888888  25
  19. 3       zs      899314121       25
  20. Time taken: 0.126 seconds, Fetched: 7 row(s)
复制代码
这里做一下说明:
我们知道我们传统数据块的形式insert into table values(字段1,字段2),这种形式hive是不支持的。

通过上面的输出,我们可以看到从wyp表中查询出来的东西已经成功插入到test表中去了!如果目标表(test)中不存在分区字段,可以去掉partition (age=’25′)语句。当然,我们也可以在select语句里面通过使用分区值来动态指明分区:
  1. hive> set hive.exec.dynamic.partition.mode=nonstrict;
  2. hive> insert into table test
  3.     > partition (age)
  4.     > select id, name,
  5.     > tel, age
  6.     > from wyp;
  7. #####################################################################
  8.            这里输出了一堆Mapreduce任务信息,这里省略
  9. #####################################################################
  10. Total MapReduce CPU Time Spent: 1 seconds 510 msec
  11. OK
  12. Time taken: 17.712 seconds


  13. hive> select * from test;
  14. OK
  15. 5       wyp1    131212121212    23
  16. 6       wyp2    134535353535    24
  17. 7       wyp3    132453535353    25
  18. 1       wyp     13188888888888  25
  19. 8       wyp4    154243434355    26
  20. 2       test    13888888888888  30
  21. 3       zs      899314121       34
  22. Time taken: 0.399 seconds, Fetched: 7 row(s)
复制代码

这种方法叫做动态分区插入,但是Hive中默认是关闭的,所以在使用前需要先把hive.exec.dynamic.partition.mode设置为nonstrict。当然,Hive也支持insert overwrite方式来插入数据,从字面我们就可以看出,overwrite是覆盖的意思,是的,执行完这条语句的时候,相应数据目录下的数据将会被覆盖!而insert into则不会,注意两者之间的区别。例子如下:

  1. hive> insert overwrite table test
  2.     > PARTITION (age)
  3.     > select id, name, tel, age
  4.     > from wyp;
复制代码

更可喜的是,Hive还支持多表插入,什么意思呢?在Hive中,我们可以把insert语句倒过来,把from放在最前面,它的执行效果和放在后面是一样的,如下:
  1. hive> show create table test3;
  2. OK
  3. CREATE  TABLE test3(
  4.   id int,
  5.   name string)
  6. Time taken: 0.277 seconds, Fetched: 18 row(s)

  7. hive> from wyp
  8.     > insert into table test
  9.     > partition(age)
  10.     > select id, name, tel, age
  11.     > insert into table test3
  12.     > select id, name
  13.     > where age>25;

  14. hive> select * from test3;
  15. OK
  16. 8       wyp4
  17. 2       test
  18. 3       zs
  19. Time taken: 4.308 seconds, Fetched: 3 row(s)
复制代码

可以在同一个查询中使用多个insert子句,这样的好处是我们只需要扫描一遍源表就可以生成多个不相交的输出。这个很酷吧!

四、在创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中

在实际情况中,表的输出结果可能太多,不适于显示在控制台上,这时候,将Hive的查询输出结果直接存在一个新的表中是非常方便的,我们称这种情况为CTAS(create table .. as select)如下:

  1. hive> create table test4
  2.     > as
  3.     > select id, name, tel
  4.     > from wyp;

  5. hive> select * from test4;
  6. OK
  7. 5       wyp1    131212121212
  8. 6       wyp2    134535353535
  9. 7       wyp3    132453535353
  10. 8       wyp4    154243434355
  11. 1       wyp     13188888888888
  12. 2       test    13888888888888
  13. 3       zs      899314121
  14. Time taken: 0.089 seconds, Fetched: 7 row(s)
复制代码

数据就插入到test4表中去了,CTAS操作是原子的,因此如果select查询由于某种原因而失败,新表是不会创建的!

Java远程调用hive

  使用java远程连接hive,在这个过程中需要先启动:hiveServer2.   (注意:org.apache.hive.jdbc.HiveDriver依赖的jar包是:hive-jdbc-1.2.1.jar)

package hive;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class HiveCreateDb {

	/*
	 * hiverserver 版本使用此驱动 private static String driverName =
	 * "org.apache.hadoop.hive.jdbc.HiveDriver";
	 */
	/*
	 * hiverserver2 版本使用此驱动
	 */
	private static String driverName = "org.apache.hive.jdbc.HiveDriver";

	public static void main(String[] args) throws Exception {

		Class.forName(driverName);

		/* hiverserver 版本jdbc url格式,主要体现在jdbc:hive:// */
		// Connection con =
		// DriverManager.getConnection("jdbc:hive://hadoop1:10000/default", "",
		// "");

		/* hiverserver2 版本jdbc url格式,主要体现在jdbc:hive2:// */
		Connection con = DriverManager.getConnection("jdbc:hive2://hadoop1:10000/default", "", "");
		Statement stmt = con.createStatement();

		// 下面的这一句如果在没有userdb数据库的情况下,可以放开。
		// stmt.executeQuery("CREATE DATABASE userdb");

		// 参数设置测试
		// boolean resHivePropertyTest = stmt
		// .execute("SET tez.runtime.io.sort.mb = 128");

		boolean resHivePropertyTest = stmt.execute("set hive.execution.engine=tez");
		System.out.println(resHivePropertyTest);

		stmt.execute("USE userdb");

		String tableName = "testHiveDriverTable";
		try {
			stmt.executeQuery("drop table " + tableName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		ResultSet res;
		try {
			res = stmt.executeQuery("create table " + tableName + " (key int, value string)");
		} catch (Exception e) {
			e.printStackTrace();
		}

		// show tables
		String sql = "show tables '" + tableName + "'";
		System.out.println("Running: " + sql);
		res = stmt.executeQuery(sql);
		if (res.next()) {
			System.out.println(res.getString(1));
		}

		// //describe table
		sql = "describe " + tableName;
		System.out.println("Running: " + sql);
		res = stmt.executeQuery(sql);
		while (res.next()) {
			System.out.println(res.getString(1) + "\t" + res.getString(2));
		}

		// load data into table
		// NOTE: filepath has to be local to the hive server
		// NOTE: /tmp/a.txt is a ctrl-A separated file with two fields per
		// line
		String filepath = "/tmp/a.txt";
		sql = "load data local inpath '" + filepath + "' into table " + tableName;
		System.out.println("Running: " + sql);
		res = stmt.executeQuery(sql);
		// select * query
		sql = "select * from " + tableName;
		System.out.println("Running: " + sql);
		res = stmt.executeQuery(sql);
		while (res.next()) {
			System.out.println(String.valueOf(res.getInt(1)) + "\t" + res.getString(2));
		}

		// regular hive query
		sql = "select count(1) from " + tableName;
		System.out.println("Running: " + sql);
		res = stmt.executeQuery(sql);
		while (res.next()) {
			System.out.println(res.getString(1));
		}

		stmt.close();
		con.close();
	}

}








上一篇:关于String对象的比较


下一篇:CSS总结