概述
Hive——Hadoop最常用的工具。
对于Hadoop的出现,无论是业界还是学术界对其都给予了极高的关注度,Hadoop及其生态圈提供了一个成熟高校的处理海量数据集的解决方案。数据基础架构大都基于关系型数据库(RDBMS)和结构化查询语言(SQL)。这就是Hive出现的原因。Mapreduce需要几十行代码完成的工作,Hive区区几行HiveQL就能胜任。
HiveQL是SQL语句的一种方言(dialect),遵循SQL-92标准,HiveQL简称HQL,这里请与Hibernate的HQL相区别。HiveQL语法与MySQL语法最为相似。
架构
需要注意的是,Hive不支持行级别的更新、插入、删除,这一点有别于RDBMS。此外,Hive不支持事务。Hive不适合用作OLTP(联机事务处理),而适合OLAP(联机分析处理)中的离线计算。
推荐使用本地模式和远程模式。
复杂数据类型
数据类型 | 说明 | 示例 |
STRUCT | 通过属性访问值。若某列数据类型为struct(first String, last String),则通过列名.first访问String类型的值 | struct(‘Tom’, ‘Jerry’) |
MAP | 通过Key访问Value | map(‘a’, ‘Tom’, ‘b’, ‘Jerry’) |
ARRAY | 通过下标访问 | array(‘Tom’, ‘Jerry’) |
基本操作
①创建数据库
CREATE DATABASE [IF NOT EXISTS] db_name;
数据库所在目录在hive-site.xml文件中的配置项hive.metastore.warehouse.dir配置的路径,默认是/user/local/warehouse。
②查看数据库
DESCRIBE DATABASE db_name;
③使用数据库
USE db_name;
④删除数据库
DROP DATABASE [IF EXISTS] db_name [CASCADE];
CASCADE为级联删除。
⑤创建表
CREATE TABLE [IF NOT EXISTS] table_name (
name STRING COMMENT 'student name',
age INT COMMENT 'student age',
cource ARRAY<STRING>,
body MAP(STRING, FLOAT),
address STRUCT<STREET:STRING, CITY:STRING, STATE:STRING>
)
COMMENT 'The info of students'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '002'
MAP KEYS TERMINATED BY '\003'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '/user/hive/warehouse/db_name.db/table_name';
最好要对标的字段上加注释,这在实际开发中是比较重要的。
如果当前使用的数据库并非目标数据库,则必须以“数据库名.表名”方式创建表。
可以通过一下命令查看不同级别的表的注释:
DESC table_name;
DESC EXTENDED table_name;
DESC FORMATTED table_name;
⑥查看表
SHOW TABLES;
⑦修改表
ALTER TABLE table_name RENAME TO table_name_new;
⑧删除表
DROP TABLE [IF EXISTS] table_name;
进阶操作
①创建外部表
在创建表的语句上加上“EXTERNAL”关键字。
外部表只存储在Hive元数据中,与实际数据存储位置无关。外部表被删除,只是删除其对应的元数据信息,其对应的物理表并不会被删除。
LOCATION指定了外部表所对应的物理数据存放路径地址。
一般来说,当数据需要被多个工具共享时,最好创建一个外部表来明确数据的所有权。
CREATE EXTERNAL TABLE [IF NOT EXISTS] table_name (
name STRING COMMENT 'student name',
age INT COMMENT 'student age',
cource ARRAY<STRING>,
body MAP(STRING, FLOAT),
address STRUCT<STREET:STRING, CITY:STRING, STATE:STRING>
)
COMMENT 'The info of students'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '002'
MAP KEYS TERMINATED BY '\003'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '/user/extra_dir/table_name';
②创建分区表
分区的单位是表目录下的多个不同的目录,也就是说,一个分区对应一个目录。
这个例子创建了拥有两个分区的表:province、city。province、city相当于key,一个完整的分区目录是由key=value组成的。
例如:/user/hive/warehouse/table_name/province=sichuan/city=chengdu
/user/hive/warehouse/table_name/province=sichuan/city=dazhou
CREATE TABLE table_name(
student_ID STRING,
name STRING,
age INT,
sex STRING,
father_name STRING,
mother_name STRING)
)
PARTITIONED BY (province STRING, city STRING);
创建外部分区表:
CREATE EXTERNAL TABLE table_name(
student_ID STRING,
name STRING,
age INT,
sex STRING,
father_name STRING,
mother_name STRING)
)
PARTITIONED BY (province STRING, city STRING);
还需为外部表的分区键(key)指定值和存储位置:
ALTER TABLE student_info ADD PARTITIONED (province = sichuan, city = chengdu) LOCATION 'hdfs://master:9000/student/sichuan/chengdu';
HQL数据操作
①装载数据
LOAD DATA INPATH '/user/kafka/log' INTO TABLE test;
这条命令将log这一数据装载到表名为test的表中。
若test为分区表,则必须指定分区
LOAD DATA INPATH '/user/kafka/log' INTO TABLE test PARTITION(part = "stream")