一 Hive 使用方式
1.1.Hive shell
直接在hive的安装目录下,然后输入hql语句就可以了
bin/hive
1.2.通过Hive thrift服务启动,启动后可以远程连接
启动为前台:
bin/hiveserver2
启动为后台:(1代表标准输出,2代表错误输出,标准输出和错误输出分别重定向到不同的日志文件)
nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &
启动后,连接
# 方式1
hive/bin/beeline 回车,进入beeline的命令界面
输入命令连接hiveserver2
beeline> !connect jdbc:hive2//master:10000
(master是hiveserver2所启动的那台主机名,端口默认是10000)
方式2
或者启动就连接:
bin/beeline -u jdbc:master://mini1:10000 -n hadoop
2.hive基本操作
2.1 DDL操作
2.1.1 创建表
基本的语法
项目实例
- 创建内表
- 创建外表
- 创建分区表
- 创建分桶表
建表语法
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]
说明:
1、 CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。
2、 EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
3、 LIKE 允许用户复制现有的表结构,但是不复制数据。
4、 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, …)]
用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive通过 SerDe 确定表的具体的列的数据。
5、 STORED AS
SEQUENCEFILE|TEXTFILE|RCFILE
如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
6、CLUSTERED BY
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
2.1.1.1创建内部表
use ods_freemud;
create table ods_freemud.ods_ext_csv_unc_dmp_freemud_active
(
active_product_no string comment "18位活动产品编号",
active_product_name string comment "产品名称" ,
active_type string comment "活动类型"
)
row format delimited fields terminated by ',' lines terminated by '\n'
stored as textfile
2.1.1.2 创建外部表
create external table ods_freemud.ods_ext_csv_unc_dmp_freemud_active
(
active_product_no string comment "18位活动产品编号",
active_product_name string comment "产品名称" ,
active_type string comment "活动类型"
)
row format delimited fields terminated by ',' lines terminated by '\n'
stored as textfile
LOCATION '/data/data_coe/data_asset/prod/db/ods_freemud/ods_ext_csv_unc_dmp_freemud_active/';
2.1.1.3 创建分区表
use ods_freemud;
create external table ods_freemud.ods_ext_csv_unc_dmp_freemud_active
(
active_product_no string comment "18位活动产品编号",
active_product_name string comment "产品名称" ,
active_type string comment "活动类型"
)
partitioned by (dt STRING)
row format delimited fields terminated by ',' lines terminated by '\n'
stored as textfile
LOCATION '/data/data_coe/data_asset/prod/db/ods_freemud/ods_ext_csv_unc_dmp_freemud_active/';
2.1.1.4 创建分桶表
use ods_freemud;
create table ods_freemud.ods_ext_csv_unc_dmp_freemud_active
(
active_product_no string comment "18位活动产品编号",
active_product_name string comment "产品名称" ,
active_type string comment "活动类型"
)
partitioned by (dt STRING)
clustered by(active_product_no) sorted by(active_product_name) into 2 buckets
row format delimited fields terminated by ',' lines terminated by '\n'
stored as textfile
hive 实例
- 求每个月每个顾客的消费总额
- 求每个月每个顾客的累积销售额
建表语句
use tmp;
create table tmp.ods_ext_csv_unc_tmp_customer_sale(
customer_name string,
sale_date string,
total_sale int
)
row format delimited fields terminated by ',' lines terminated by '\n'
stored as textfile;
数据样例
"A","2015-01-02",5
"A","2015-01-03",15
"B","2015-01-01",5
"A","2015-01-04",8
"B","2015-01-05",25
"A","2015-01-06",5
"A","2015-02-02",4
"A","2015-02-06",6
"B","2015-02-06",10
"B","2015-02-07",5
插入数据
insert into tmp.ods_ext_csv_unc_tmp_customer_sale(customer_name, sale_date, total_sale)
values ("A","2015-01-02",5),("A","2015-01-03",15),("B","2015-01-01",5),("A","2015-01-04",8),("B","2015-01-05",25),("A","2015-01-06",5),("A","2015-02-02",4),("A","2015-02-06",6),("B","2015-02-06",10),("B","2015-02-07",5);
每个顾客,每个月消费额
select customer_name,substring(sale_date,1, 7), sum(total_sale) from tmp.ods_ext_csv_unc_tmp_customer_sale group by customer_name, substring(sale_date,1, 7);
查询结果
A 2015-01 33
A 2015-02 10
B 2015-01 30
B 2015-02 15
每个顾客,每个月消费额和累计消费额
select left_table.customer_name, left_table.sale_date, left_table.month_count, sum(left_table.month_count) from
, sum(right_table.month_count) ,, left_table.month_count
select left_table.customer_name , left_table.sale_date ,max(left_table.month_count), sum(right_table.month_count) from
(select customer_name,substring(sale_date,1, 7) as sale_date, sum(total_sale) as month_count from tmp.ods_ext_csv_unc_tmp_customer_sale group by customer_name, substring(sale_date,1, 7)) as left_table
left join
(select customer_name,substring(sale_date,1, 7) as sale_date, sum(total_sale) as month_count from tmp.ods_ext_csv_unc_tmp_customer_sale group by customer_name, substring(sale_date,1, 7)) as right_table
on left_table.customer_name = right_table.customer_name
where left_table.sale_date >= right_table.sale_date
group by left_table.customer_name, left_table.sale_date;
查询结果
A 2015-01 33 33
A 2015-02 10 43
B 2015-01 30 30
B 2015-02 15 45