目录
一、HIVE概述
1.Hadoop分布式计算遇到的问题
MapReduce只能用java开发(也支持其他语言,但是不是主流)需要对Hadoop的底层原理 api比较了解才能顺畅的开发出分布式的处理程序开发调试麻烦。
2.HQL
Hive通过类SQL的语法,来进行分布式的计算。HQL用起来和SQL非常的类似,Hive在执行的过程中会将HQL转换为MapReduce去执行,所以Hive其实是基于Hadoop的一种分布式计算框架,底层仍然是MapReduce,所以它本质上还是一种离线大数据分析工具。
Hive是基于Hadoop的一个数据仓库工具。可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
Hive是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HiveQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
Hive不支持在线事务处理,.也不支持行级的插入和更新和删除。
3.数据仓库与数据库的主要区别
(1)数据库是面向事务的设计,数据仓库是面向主题设计的。
(2)数据库一般存储在线交易数据,数据仓库存储的一般是历史数据。
(3)数据库设计是尽量避免冗余,数据仓库在设计是有意引入冗余。
(4)数据库是为捕获数据而设计,数据仓库是为分析数据而设计。
(5)数据库实现完整的增删改查,数据仓库只能一次写入多次查询 不支持行级别的增删改。
(6)数据库具有完整的事务保证,数据仓库不强调事务特性。
二、Hive的安装配置
下载从apache官网下载新版本hive,要注意和hadoop版本的匹配。
安装
需要提前安装好jdk和hadoop,并且配置过JAVA_HOME和HADOOP_HOME,解压即可安装,安装完成后可以进入bin下执行hive脚本,如果能够进入hive命令行说明hive安装成功。
三、Hive原理
结论1:hive中的数据库对应hdfs中/user/hive/warehouse目录下以.db结尾的目录。
结论2:hive中的表对应hdfs/user/hive/warehouse/[db目录]中的一个目录
结论3:hive中的数据对应当前hive表对应的hdfs目录中的文件。
结论4:hive会将命令转换为mapreduce执行。
结论5:hive默认的default数据库直接对应/user/hive/warehouse目录,在default库中创建的表直接会在该目录下创建对应目录。
四、Hive的元数据库
Hive默认使用Derby作为元数据库,但是这种方式只能用于测试不应用于生产环境中,生产环境中应该使用其他数据库作为元数据储存的数据库使用。Hive目前支持Derby和MySql作为元数据库使用。
1.配置mysql作为hive的元数据库
mysql在linux中的安装过程这里不讲述。
步骤:
(1)删除hdfs中的/user/hive
hadoop fs -rmr /user/hive
(2)复制hive/conf/hive-default.xml.template为hive-site.xml
cp hive-default.xml.template hive-site.xml
在<configuration>中进行配置
#配置数据库连接地址
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop01: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>
配置过mysql元数据库后可能遇到的问题:
(1)hive无法启动,提示缺少驱动包:将mysql的数据库驱动包拷贝到hive/lib下
(2)hive无法启动,提示连接被拒绝:在mysql中启动权限:
#(执行下面的语句 *.*:所有库下的所有表 %:任何IP地址或主机都可以连接)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
(3)hive能够启动,但是在执行一些操作时报奇怪的错误:原因很可能是mysql中hive库不是latin编码,删除元数据库手动创建hive库,指定编码集为latin1。
连接mysql,发现多了一个hive库。其中保存有hive的元数据。
2.元数据库介绍
DBS:数据库的元数据信息
DB_ID 数据库编号
DB_LOCATION_URI 数据库在hdfs中的位置
TBLS:表信息。
TBL_ID 表的编号
DB_ID 属于哪个数据库
TBL_NAME 表的名称
TBL_TYPE 表的类型 内部表MANAGED_TABLE/外部表
COLUMNS_V2 表中字段信息
CD_ID 所属表的编号
COLUMN_NAME 列明
TYPE_NAME 列的类型名
SDS:表对应hdfs目录
CD_ID 表的编号
LOCATION 表对应到hdfs中的位置
五、内部表、外部表(重要)
内部表:
如果表是通过hive来创建,其中的数据也是通过hive来导入,则先有表后有表中的数据,则称这种表为内部表。
外部表:
如果是先有的数据文件,再创建hive表来管理,则这样的表称为外部表。
创建语法:create external table ext_student(id int ,name string) row format delimited fields terminated by '\t' location '/datax';
注意:
内部表被Drop的时候,表关联的hdfs中的文件夹和其中的文件都会被删除。
外部表被Drop的时候,表关联的hdfs中的文件夹和其中的文件都不会被删除。
内部表/外部表可以在表文件夹下直接上传符合格式的文件,从而增加表中的记录。
六、分区表(重要)
hive也支持分区表
对数据进行分区可以提高查询时的效率 。
普通表和分区表区别:有大量数据增加的需要建分区表
create table book (id bigint, name string) partitioned by (category string) row format delimited fields terminated by '\t';
create table book (id bigint, name string) partitioned by (category string,gender string) row format delimited fields terminated by '\t';
所谓的分区表是又在表文件夹下创建了子文件夹([分区的名]=分区名字的值 )分别存放同一张表中不同分区的数据,从而将数据分区存放,提高按照分区查询数据时的效率。所以当数据量比较大,而且数据经常要按照某个字段作为条件进行查询时,最好按照该条件进行分区存放。通过观察元数据库发现,分区表也会当作元数据存放在SDS表中。
注意:如果手动的创建分区目录,是无法被表识别到的,因为在元数据库中并没有该分区的信息,如果想让手动创建的分区能够被表识别需要在元数据库SDS表中增加分区的元数据信息。
ALTER TABLE book add PARTITION (category = 'jp',gender='male') location '/user/hive/warehouse/testx.db/book/category=jp/gender=male';
七、分桶表(重要)
hive也支持分桶表。分桶操作是更细粒度的分配方式。一张表可以同时分区和分桶。分桶的原理是根据指定的列的计算hash值模余分桶数量后将数据分开存放。分桶的主要作用是:对于一个庞大的数据集我们经常需要拿出来一小部分作为样例,然后在样例上验证我们的查询,优化我们的程序。
创建带桶的 table :
create table teacher(id int,name string) clustered by (id) into 4 buckets row format delimited fields terminated by '\t';
强制多个 reduce 进行输出:
set hive.enforce.bucketing=true;
往表中插入数据:
insert overwrite table teacher select * from temp;//需要提前准备好temp,从temp查询数据写入到teacher
查看表的结构,会发现当前表下有四个文件:
dfs -ls /user/hive/warehouse/teacher;
读取数据,看一个文件的数据:
dfs -cat /user/hive/warehouse/teacher/000000_0;
//桶使用 hash 来实现,所以每个文件拥有的数据的个数都有可能不相等。
对桶中的数据进行采样:
select * from teacher tablesample(bucket 1 out of 4 on id);
//桶的个数从1开始计数,前面的查询从4个桶中的第一个桶获取数据。其实就是四分之一。
查询一半返回的桶数:
select * from bucketed_user tablesample(bucket 1 out of 2 on id);
//桶的个数从1开始计数,前2个桶中的第一个桶获取数据。其实就是二分之一。
八、Hive的语法
1.数据类型
TINYINT - byte
SMALLINT - short
INT - int
BIGINT - long
BOOLEAN - boolean
FLOAT - float
DOUBLE - double
STRING - String
TIMESTAMP - TimeStamp
BINARY - byte[]
2.create table
create table book (id bigint, name string) row format delimited fields terminated by '\t';
create external table book (id bigint, name string) row format delimited fields terminated by '\t' location 'xxxxx';
create table book (id bigint, name string) partitioned by (category string) row format delimited fields terminated by '\t';
3.修改表
增加分区:ALTER TABLE book add PARTITION (category = 'zazhi') location '/user/hive/warehouse/datax.db/book/category=zazhi';
删除分区:ALTER TABLE table_name DROP partition_spec, partition_spec,...
重命名表:ALTER TABLE table_name RENAME TO new_table_name
修改列:ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
增加/替换列:ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
4.Show
查看数据库
SHOW DATABASES;
查看表名
SHOW TABLES;
查看表名,部分匹配
SHOW TABLES 'page.*';
SHOW TABLES '.*view';
查看某表的所有Partition,如果没有就报错:
SHOW PARTITIONS page_view;
查看某表结构:
DESCRIBE invites;
查看分区内容
SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';
查看有限行内容,同Greenplum,用limit关键词
SELECT a.foo FROM invites a limit 3;
查看表分区定义
DESCRIBE EXTENDED page_view PARTITION (ds='2008-08-08');
5.Load
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
Load 操作只是单纯的复制/移动操作,将数据文件移动到 Hive 表对应的位置。
6.Insert
(1)将查询的结果插入指定表中
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement
(2)将查询结果写入文件系统中
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...
7.Drop
删除一个内部表的同时会同时删除表的元数据和数据。删除一个外部表,只删除元数据而保留数据。
8.Limit
Limit 可以限制查询的记录数。查询的结果是随机选择的
9.Select
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT number]
10.JOIN
join_table:
table_reference JOIN table_factor [join_condition]
| table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition
| table_reference LEFT SEMI JOIN table_reference join_condition
table_reference:
table_factor
| join_table
table_factor:
tbl_name [alias]
| table_subquery alias
| ( table_references )
join_condition:
ON equality_expression ( AND equality_expression )*
equality_expression:
expression = expression
九、HIVE的UDF
如果hive的内置函数不够用,我们也可以自己定义函数来使用,这样的函数称为hive的用户自定义函数,简称UDF。
新建java工程,导入hive相关包,导入hive相关的lib。
创建类继承UDF
自己编写一个evaluate方法,返回值和参数任意。
为了能让mapreduce处理,String要用Text处理。
将写好的类打成jar包,上传到linux中
在hive命令行下,向hive注册UDF:add jar /xxxx/xxxx.jar
为当前udf起一个名字:create temporary function fname as '类的全路径名';
之后就可以在hql中使用该自定义函数了。
十、HIVE的java api操作
hive实现了jdbc接口,所以可以非常方便用jdbc技术通过java代码操作。
1.在服务器端开启HiveServer服务
./hive --service hiveserver2
2.创建本地工程,导入jar包
导入hive\lib目录下的hive-jdbc-1.2.0-standalone.jar
导入hadoop-2.7.1\share\hadoop\common下的hadoop-common-2.7.1.jar
3.编写jdbc代码执行
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection conn = DriverManager.getConnection("jdbc:hive2://192.168.242.101:10000/park","root","root");
Statement statement = conn.createStatement();
//statement.executeUpdate("create table x2xx (id int,name string)");
//其他sql语句...
statement.close();
conn.close();
以上就是hive的全部内容,如有疑问和建议欢迎留言。