Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
Command命令
命令 | 描述 |
---|---|
quit exit |
退出交互式命令行。 |
reset | 将配置重置为默认值,在hive命令行中使用set命令或-hiveconf参数设置的任何配置参数都将重置为默认值。 |
set <key>=<value> | 设置Hive运行时配置参数,优先级最高,相同key,后面的设置会覆盖前面的设置。 |
set | 打印出用户设置和Hive默认的配置变量列表。 |
set -v | 打印所有Hadoop和Hive配置变量。 |
add FILE[S] <filepath> <filepath>* add JAR[S] <filepath> <filepath>* add ARCHIVE[S] <filepath> <filepath>* |
将一个或多个文件,jar或存档添加到分布式缓存中的资源列表。 |
add FILE[S] <ivyurl> <ivyurl>* add JAR[S] <ivyurl> <ivyurl>* add ARCHIVE[S]<ivyurl> <ivyurl>* |
Hive1.2.0开始使用这种方法添加文件。 |
list FILE[S] list JAR[S] list ARCHIVE[S] |
列出已经添加到分布式缓存的资源 。 |
list FILE[S] <filepath>* list JAR[S] <filepath>* list ARCHIVE[S] <filepath>* |
检查给定资源是否已经添加到分布式缓存中。 |
delete FILE[S] <filepath>* delete JAR[S] <filepath>* delete ARCHIVE[S] <filepath>* |
从分布式缓存中删除资源。 |
delete FILE[S] <ivyurl> <ivyurl>* delete JAR[S] <ivyurl> <ivyurl>* delete ARCHIVE[S] <ivyurl> <ivyurl>* |
从Hive 1.2.0开始,从分布式缓存中删除使用<ivyurl>添加的资源。 |
! <command> | 在交互Shell中执行Linux操作系统命令并打印出结果,不常用,比如: hive> !pwd; /root |
dfs <dfs command> | 在交互Shell中执行hadoop fs 命令,不常用,比如,统计hdfs文件系统中/tmp/目录的总大小: hive> dfs -du -s /tmp/; 7545904793 22637714379 /tmp |
<query string> | 执行Hive sql语句查询并将结果打印到标准输出。 |
source FILE <filepath> | 在hive命令行内执行脚本文件。 |
1.1.Hive语法
1.1.1.基本数据类型
tinyint , smallint, int, bigint, float, double, boolean: true/false, string
1.1.2.基础运算符与函数
语法 | 描述 |
---|---|
A IS NULL | 空 |
A IS NOT NULL | 非空 |
A LIKE B | 模糊匹配 |
A RLIKE B | 正则表达式匹配 |
A REGEXP B | 正则表达式匹配 |
1.1.3.类型转换
cast(expr as <type>)
例如:
cast('1' as BIGINT) 将字符串'1'转化成bigint型
1.1.4.日期函数
返回值类型 | 名称 | 描述 |
---|---|---|
string | from_unixtime(int unixtime) | 将时间戳(unix epoch秒数)转换为日期时间字符串,例如from_unixtime(0)="1970-01-01 00:00:00" |
bigint | unix_timestamp() | 获得当前时间戳 |
bigint | unix_timestamp(string date) | 获得date表示的时间戳 |
bigint | to_date(string timestamp) | 返回日期字符串,例如to_date("1970-01-01 00:00:00") = "1970-01-01" |
string | year(string date) | 返回年,例如year("1970-01-01 00:00:00") = 1970,year("1970-01-01") = 1970 |
int | month(string date) | 返回月 |
int | day(string date) dayofmonth(date) | 返回天 |
int | hour(string date) | 返回时 |
int | minute(string date) | 返回分 |
int | second(string date) | 返回秒 |
int | weekofyear(string date) | 返回日期在当前的周数。 |
int | datediff(string enddate, string startdate) | 返回enddate和startdate的天数的差,例如datediff('2009-03-01', '2009-02-27') = 2 |
int | date_add(string startdate, int days) | 加days天数到startdate: date_add('2008-12-31', 1) = '2009-01-01' |
int | date_sub(string startdate, int days) | 减days天数到startdate: date_sub('2008-12-31', 1) = '2008-12-30' |
1.1.5.条件函数
返回值类型 | 名称 | 描述 |
---|---|---|
- | if(boolean testCondition, T valueTrue, T valueFalseOrNull) | 当testCondition为真时返回valueTrue,testCondition为假或NULL时返回valueFalseOrNull |
- | COALESCE(T v1, T v2, ...) | 返回列表中的第一个非空元素,如果列表元素都为空则返回NULL |
- | CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END | a = b,返回c;a = d,返回e;否则返回f |
- | CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END | a 为真,返回b;c为真,返回d;否则e |
例如:
(
case
when category = '1512' then reserve_price > cast(1000 as double)
when category = '1101' then reserve_price > cast(2500 as double)
else reserve_price > cast(10 as double)
end
)
1.1.6.常用字符串函数
返回值类型 | 名称 | 描述 |
---|---|---|
int | length(string A) | 返回字符串长度 |
string | reverse(string A) | 反转字符串 |
string | concat(string A, string B...) | 合并字符串,例如concat('foo', 'bar')='foobar'。注意这一函数可以接受任意个数的参数 |
string | substr(string A, int start) substring(string A, int start) | 返回子串,例如substr('foobar', 4)='bar',详见 [4] |
string | substr(string A, int start, int len) substring(string A, int start, int len) | 返回限定长度的子串,例如substr('foobar', 4, 1)='b',详见[5] |
string | upper(string A) ucase(string A) | 转换为大写 |
string | lower(string A) lcase(string A) | 转换为小写 |
string | trim(string A) | 去除空格 |
string | ltrim(string A) | 去除左边空格 |
string | rtrim(string A) | 去除右边空格 |
string | regexp_extract(string subject, string pattern, int intex) | 返回使用正则表达式提取的子字串。例如:regexp_extract('foothebar', 'foo(.*?)(bar)', 2)='bar'。注意使用特殊字符的规则:使用'\s'代表的是字符's';空白字符需要使用'\s',以此类推。 |
string | space(int n) | 返回一个包含n个空格的字符串 |
string | repeat(string str, int n) | 重复str字符串n遍 |
string | ascii(string str) | 返回str中第一个字符的ascii码 |
string | lpad(string str, int len, string pad) | 左端补齐str到长度为len。补齐的字符串由pad指定。 |
string | rpad(string str, int len, string pad) | 右端补齐str到长度为len。补齐的字符串由pad指定。 |
array | split(string str, string pat) | 返回使用pat作为正则表达式分割str字符串的列表。例如,split('foobar', 'o')[2] = 'bar'。 |
1.1.7.创建表
CREATE TABLE IF NOT EXISTS table_name
(
--field def
)
PARTITIONED BY (pt string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION '...';
注意:如果不是外表部,drop table的时候会将HDFS上文件删除。
1.1.8.创建外部表
CREATE EXTERNAL TABLE dm_all_cpv_assoc (
--field def
)
PARTITIONED BY (pt string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\1' 字段分隔符
LINES TERMINATED BY '\2' 行分隔符
STORED AS TEXTFILE
LOCATION '...';
注意:在删除外部表的时候,不会删除HDFS上的关联文件。
分析:其实多数情况下,内表和外表没区别。一个经验法则:如果所有处理都由hive完成,则使用内表,如果要用hive和其他工具来处理一个数据集,则使用外表。
1.1.9.添加分区
ALTER TABLE table_name ADD PARTITION (dt='2008-08-08', country='us')
location '/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us')
location '/path/to/us/part080809';
1.1.10.删除分区
ALTER TABLE table_name DROP PARTITION (dt='2008-08-08', country='us');
1.1.11.导入数据
a. insert overwrite table table_name partition (pt = '20110323000000')
select ... from ...
b. LOAD DATA LOCAL INPATH 'test.dat' OVERWRITE INTO table yahoo_music partition (pt=xxx);
1.1.12.查询数据
SELECT, JOIN, LIMIT
1.1.13.修改表
修改表名 Alter table t1 rename to t2;
增加一列 alter table t1 add columns (id int);
1.1.14. 添加UDF
add jar /home/hive/jar/my_udf.jar;
create temporary function sys_date as 'com.taobao.hive.udf.UDFDateSysdate';
1.2分组函数
使用以下数据进行测试。
1.2.1.Group By
Group by语句按照一个标准来对数据进行分组。
使用GROUP BY时,可以同时使用多个聚合函数,但是聚合函数里面使用DISTINCT时必须包含相同的列。
例1:得出每个年份的最大温度
select year,max(temperature)
as max_temperature
from records
group by year;
例2:得出特定月份的最低温度
select month,max(temperature) as min_temperature
from records
where month in (1,2,3,8,9)
group by month;from records
group by month;
1.2.2.Order by
Order by 对输入执行并行全排序。其实 Hive中的order by跟传统的sql语言中的order by作用是一样的,会对查询的结果做一次全局排序,所以说,只有hive的sql中制定了order by所有的数据都会到同一个reducer进行处理(不管有多少map,也不管文件有多少的block只会启动一个reducer)。但是对于大量数据这将会消耗很长的时间去执行。默认是asc(从小到大,可指定desc(从大到小))
例:按照月份排序
select *
from records
order by month;
1.2.3.sort by
sort by是order by的局部排序,sort by 为每个reducer产生一个排序文件。保证了局部有序(每个reducer出来的数据是有序的,但是不能保证所有的数据是有序的,除非只有一个reducer),好处是:执行了局部排序之后可以为接下去的全局排序提高不少的效率(其实就是做一次归并排序就可以做到全局排序了)。
例:按照月份排序
select *
from records
sort by month;
1.2.4.Distribute By
ditribute by是控制map的输出在reducer是如何划分的,就是控制特定行应该到哪个reducer,其目的通常是为了进行后续的聚集操作。和sort by 连用。其实就是将distribute by指定的相同的所有对象送到一个reducer中去处理。需要注意的是distribute by必须要写在sort by之前。
例;按月份将温度排序
select *
from records
distribute by month sort by month asc,temperature desc;
1.2.5.cluster By
cluster by的功能就是distribute by和sort by相结合,就是如果sort by 和distribute by 中所用的列相同,就可以缩写为cluster by。注意被cluster by指定的列只能是正序,不能指定asc和desc。
例如这两个语句就相等:
select * from records cluster by month
select * from records distribute by month sort by month
例:按月份将温度排序
select * from records cluster by month;