遇见hive之初级篇 ————hive数据仓库与hdfs的关系、以及hive的基础语句、表结构的介绍、

1、hive概述:

     由Facebook开源用于解决海量结构化日志的数据统计,后称为Apache Hive为一个开源项目 

-->结构化数据:数据类型,字段,value---》hive

-->非结构化数据:比如文本、图片、音频、视频---》会有非关系型数据库存储,或者转换为结构化

-->结构化日志数据:服务器生成的日志数据,会以空格或者制表符分割的数据,比如:apache、nginx等等
  • Hive 是一个基于 Hadoop 文件系统之上的数据仓库架构,存储用hdfs,计算用mapreduce
  • Hive 可以理解为一个工具,不存在主从架构,不需要安装在每台服务器上,只需要安装几台就行了
  • hive还支持类sql语言,它可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能(披着sql外衣的MapReduce)
  • hive有个默认数据库:derby,默认存储元数据---》后期转换成关系型数据库存储mysql 
     hive的版本:apache-hive-1.2.1 、hive-0.13.1-cdh5.3.6
-->https://github.com/apache/  主要查看版本的依赖
    下载地址:
-->apache的版本:http://archive.apache.org/dist/hive/

-->cdh的版本:http://archive.cloudera.com/cdh5/cdh/5/ 

2、hive的安装

tar -zxf apache-hive-1.2.1-bin.tar.gz -C /opt/module/apache/  

配置环境:修改名称:mv hive-env.sh.template hive-env.sh、截图保留配置

--># Set HADOOP_HOME to point to a specific hadoop install directory
--> HADOOP_HOME=/opt/module/apache/hadoop-2.7.3

--># Hive Configuration Directory can be controlled by:

-->export HIVE_CONF_DIR=/opt/module/apache/hive-1.2.1/conf


2.1、在hdfs上创建目录,如下

  • bin/hdfs dfs -mkdir             /tmp
  • bin/hdfs dfs -mkdir -p        /user/hive/warehouse
  • bin/hdfs dfs -chmod g+w   /tmp
  • bin/hdfs dfs -chmod g+w   /user/hive/warehouse

在启动hive之前,一定要保证启动hadoop(hdfs,yarn),因为hive的数据仓库是建立在hdfs的文件系统之上的然后启动hive  在hive目录下     bin/hive    则可以启动hive

-->查看有哪些数据库:show databases;
-->创建数据库:create database hadoop;
-->查看表:show tables;

-->使用数据库:use hadoop;

2.2、安装MySQL

-->1 查看是否安装过mysql:rpm -qa|grep mysql*  
-->2 查看有没有安装包:yum list mysql* 
-->3 安装mysql客户端:yum install -y mysql
-->4 安装服务器端:yum install -y mysql-server 
-->5 yum install -y mysql-devel
-->6 启动数据库 service mysqld start或者/etc/init.d/mysqld start
-->7 创建hadoop用户并赋予权限:
-->8 mysql>grant all on *.* to hadoop@'%' identified by 'hadoop';
-->9 mysql>grant all on *.* to hadoop@'localhost' identified by 'hadoop';
-->10 mysql>grant all on *.* to hadoop@'master' identified by 'hadoop';
-->11 mysql>flush privileges;
-->12 chkconfig mysqld on  开机自动启动MySQL

2.3、修改hive的原始Derby数据库,改为使用关系型数据库MySQL,配置如下

创建一个 hive-site.xml 从hive-defaule.xml 复制头部信息,修改具体内容如下

<configuration>
  <!-- WARNING!!! This file is auto generated for documentation purposes ONLY! -->
  <!-- WARNING!!! Any changes you make to this file will be ignored by Hive.   -->
  <!-- WARNING!!! You must make your changes in hive-site.xml instead.         -->
  <!-- Hive Execution Parameters -->
 <property>
 jasbdaksbdaskbdoajsbdasbu
  <name>javax.jdo.option.ConnectionURL</name>
	<!--指定连接的hostname及端口,和创建一张关于hive的元数据表-->
  <value>jdbc:mysql://make.hadoop.com: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>123456</value>
  <description>password to use against metastore database</description>
</property>
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
	<!--在hive客户端显示当前所在数据库-->
</property>
<property>
	<!--显示数据表的头部信息,也就是字段名称-->
    <name>hive.cli.print.header</name>
    <value>true</value>
</property>
</configuration>
然后将物理的用语连接的jar包放到     hive/lib的文件夹中,重新启动hive

-->这里用的是 mysql-connector-java-5.1.27-bin.jar

重启hive之后,我们可以看到在我们的MySQL中生成了一个名为hive的数据库,里面有三张表,表名区分大小写

  • DBS 存放hive的所有的数据库的信息及location
  • TBLS    存放hive的所有的表的的信息
  • PARTITIONS 存放hive的分区表的所有的分区的信息

3、hive的基础认识

3.1、hive数据类型:
-->数值型:tinyint、smallint、int、bigint  --》常用的int
-->字符型:varchar、char、string  --》常用string
-->时间型:date、timestamp
-->其他类型:boolean
-->复杂类型:arrays(下标是从0开始)、map(key,value)、structs
tips   userlist map(int、string)    userlist['1']取出value
user structs<name:string,age:int>  user.name  user.age

-->官网可以查看更多信息:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types

3.2、如何创建表

-->如果数据的分割符与表的分割符不一致,就会解析数据异常
-->默认分割符:默认的分隔符是\001(^A),(\002为^B)默认的分隔符是以ctrl+v、ctrl+A
-->分隔符:"\t"、","、" "、^A、^B
-->指定:ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"

create table test3(
id int,
name string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

加载数据
-->load data local inpath '/opt/datas/test' into table test;
查询数据
-->select * from test;
hdfs的目录结构:hive的默认存放 数据库 表 加载的数据
-->/user/hive/warehouse/    hadoop.db/    test/      test

    warehouse.dir          database      table     data

3.3、hive的操作命令

描述表

-->desc table_name;  

-->desc extended  table_name;

-->desc formatted table_name;  --》推荐使用,如下图所示,每个信息,都有所描述


修改表名
-->alter table old_table_name rename to new_table_name;
给表新添加一个列
-->alter table table_name add columns (age int);
-->alter table table_name add columns (sex int comment 'this is age'); //注释
修改列的名字或类型或顺序
-->ALTER TABLE table_name  CHANGE  col_old_name col_new_name column_type
创建一个测试表:
-->create table test_change (a int,b int, c int);
修改列的名称:a  ---> a1
-->alter table test_change CHANGE a a1 int;
将a1改为a2,并且类型string,并放在b的后面
-->alter table test_change CHANGE a1 a2 string after b;
将c改为c1,并且放在第一列
-->alter table test_change CHANGE c c2 int first;
替换列(不能够指定替换,是全表替换)
-->ALTER TABLE table_name REPLACE COLUMNS (col_name data_type)
--> alter table test_change replace columns (d int, f string);
清空表数据
-->TRUNCATE TABLE table_name [PARTITION partition_spec];
只清空数据,表和表的结构还存在
-->truncate table test;
删除数据表drop
删除表:同时将表的元数据信息删除
-->drop table table_name;
删除数据库drop (CASCADE)
-->drop database dabase_name;
-->drop database dabase_name cascade;
查看hive自带的函数方法
-->show functions;
描述函数的信息:
-->desc function count;

-->desc function extended count;  推荐使用这个

3.4、hive的常用配置以及linux命令选项

设定hive的log存放目录,修改hive-log4j.properties

-->hive.log.dir=/opt/apps/hive-1.2.1/logs

指定登录到某个数据库 
-->bin/hive --database hadoop
指定一个sql语句,去执行,sql语句必须用引号包裹
-->bin/hive -e 'select * from hadoop.test'
指定一个包含sql语句的文件,去执行
-->bin/hive -f /opt/datas/test.sql
使用重定向将结果保存到某个文件
-->bin/hive -f /opt/datas/test.sql >> /opt/datas/hive.txt
临时修改配置信息参数的值,属于临时生效
-->bin/hive --hiveconf hive.cli.print.current.db=false
在hive客户端里去修改参数信息
-->set hive.cli.print.current.db;   --》查看
-->set hive.cli.print.current.db=false;  --》修改
自定义数据仓库的位置localtion
-->CREATE DATABASE database_name [LOCATION hdfs_path]
-->create database hive_db location "/hive_test"
-->show tables in hadoop22;  查看其他数据库下的所有表
常用的shell:! 和 dfs

-->! 表示可以访问linux本地文件系统:比如:! ls /opt/apps;


-->dfs 表示可以访问hdfs文件系统: 


4、对于如何将sql语句转化为课执行的任务的?

1、Antlr自定义规则,识别hive的sql,(写sql的时候,语法错误,可以直接被识别,不会运行到一半才报错)(跟mysql很类似的,但是会有一些自己的东西。rownumber,over X partition(XXX)range 30  between 30 XXX)
2、抽象语法树AST tree sql根据 select ,from,filter(where)XXX---》生成像一个树节点状的逻辑,查询分块(spark,dsl语法的时候)
3、逻辑操作operator 每一块的输入是哪些字段,输出是哪些字段(as 别名)
4、逻辑优化 谓词前置,前推 判断是否能在map直接聚合(mapjoinXX)
-->select X ,X  from (select u.name,u.orderid from  user u  where XXX)where XXX
5、遍历逻辑生成mr任务

6、物理层面的优化器,在优化mr任务,生成最终执行的计划

下面从其他博客截了几张图,应该会更好的理解,方便我自己后面可查看啦

两张标的join的实现


group by 的实现


distinct 的实现


更多的请参考此地址:https://blog.csdn.net/u010738184/article/details/70893161

5、hive的四大表数据的类型

表类型说明table内部表 Partition分区表 External Table外部表 Bucket Table桶表

5.1、内部表就相当于我们前面创建的表,建好内部表后,通过load的方式加载本地数据,和通过hdfs文件系统-put一份数据到表下面的效果是一样的,

也就是说load的本质,就是把本地文件put上去,并不会修改相关表的元数据。

外部表与内部表的区别

  • 创建表时:创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变。
  • 删除表时:在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据

分区表:[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

普通的表:select * from logs where date = '20171209'
-->执行流程:对全表的数据进行查询,然后才过滤操作

分区表:select * from logs where date = '20171209'

-->执行流程:直接加载对应文件路径下的数据

分区表的直接加载方式,以及对分区的修复

直接在hdfs上创建分区文件夹    

-->dfs -mkdir /user/hive/warehouse/emp_part/day=20180627

-->dfs -put /opt/datas/emp.txt  /user/hive/warehouse/emp_part/day=20180627

但是这样创建day=20180627的分区表之后,直接查看,表中是没有数据的,因为我们的元数据库里面,根本没有day这个分区,所以我们要对这个表进行修复才可以有以下两种方式

1、=>msck repair table emp_part

2、=>alter table emp_part add partition(day = '20180627')

这样就可以把分区的信息,更新到元数据信息里面,也就可以查出对应的数据

分区的字段是逻辑性的,体现在hdfs上形成一个文件夹存在,并不在数据中,必须不能是数据中已包含的字段

创建一级分区,并加载数据

create table emp_part(  
empno int,  
ename string,
job string,  
mgr int,
hiredate string,  
sal double,  
comm double,  
deptno int
)partitioned by (`date` string)
row format delimited  fields terminated by '\t';

load data local inpath '/opt/datas/emp.txt' into table emp_part partition(`date`='20171209');
load data local inpath '/opt/datas/emp.txt' into table emp_part partition(`date`='20171208');

select *  from emp_part;

创建二级分区,并加载数据

create table emp_part2(  
empno int,  
ename string,
job string,  
mgr int,
hiredate string,  
sal double,  
comm double,  
deptno int
)partitioned by (`date` string,hour string)
row format delimited  fields terminated by '\t';

load data local inpath '/opt/datas/emp.txt' into table emp_part2 partition(`date`='20171209',hour='01');

load data local inpath '/opt/datas/emp.txt' into table emp_part2 partition(`date`='20171209',hour='02');

select * from emp_part2 where datatime = '20180518' and hour = '2';

老师给的小技巧啦

关于分区字段的设置:
报错一:
FAILED: SemanticException [Error 10035]: Column repeated in partitioning columns

原因:分区字段不能和原有字段冲突,比如有个叫day的字段,分区就不能用这个字段名


报错二:新版本会报错
FAILED: ParseException line 11:15 Failed to recognize predicate 'date'. Failed rule: 'identifier' in column specification
因为这个是在1.2.0版本之后增加的一个新特性     hive.support.sql11.reserved.keywords
支持了sql2011,就是保留了一些关键字
解决方法:date上面加反引号 `date`
或者hive.support.sql11.reserved.keywords这个参数改成false

但是建议还是避开关键字,不然你把sql写在shell中的时候,`date`,shell会识别成一个脚本(推荐避开关键字)


报错三:插入字段时候不指定分区
FAILED: SemanticException [Error 10062]: Need to specify partition columns because the destination table is partitioned

解决:指定分区就好了。。

桶表:获得更高的查询处理效率、join、抽样数据,但是在做join的时候的两张表必须都是桶表,桶表其实就是根据一个字段的hash值来对表进行分区的感觉,自己这样认为,除非真的这个业务通过桶表能大大提神效率,负责分区表应该就足够了。

桶表的应用场景

比如我数据有严重的数据倾斜,分布不均匀、相对来说每个桶中的数据量会比较平均、桶于桶之间做join等查询的时候,会有优化

6、hive数据导入的多种方式

1、本地 load data local inpath '' XXXX   --》cp
2、hdfs load data local inpath '' XXXX   --》mv
3、加载一份临时的数据
load data local inpath '路径' overwrite into table emp
4、子查询  
insert into table XXX select * from XXXX
like(不复制数据,只复制表机构)
5、location 
数据本身已经存在,建表的时候指定hdfs上的路径
6、通过hdfs命令,将文件put到对应的位置
(如果分区表,要记得alter XXXX add/drop partition(XXXX))
7、通过其他工具(sqoop,spaark这类型的工具,从数据库等其他地方将数据加载到hdfs或者hive的表中)

暂时写到这里,我开始理思路了,毕竟太菜啦!!!!!



3、分区表
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]


普通的表:select * from logs where date = '20171209'
     执行流程:对全表的数据进行查询,然后才过滤操作


分区表:select * from logs where date = '20171209'
     执行流程:直接加载对应文件路径下的数据


分区的字段是逻辑性的,体现在hdfs上形成一个文件夹存在,并不在数据中,必须不能是数据中已包含的字段

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值