Hive第二天总结
hive与hdfs关系
- hive中的数据是存放在HDFS上的,元数据存放在数据库中,元数据(表与文件之间的映射关系)。默认的数据库名称default
- hive的数据库默认位置是由hive-site.xml文件中的hive.metastore.warehouse.dir参数指定的,默认位置为/user/hive/warehouse。
数据库位置在HDFS中的对应图:
元数据服务(metastore)
为了保证数据的安全性,主要作用是为了管理元数据的,自身暴漏的服务地址,让客户端连接metastore,再通过metastor链接MySQL存取元数据。值得注意的是hive原生的存放元数据的数据库是derby数据库。
metastore的三种部署方式:
- 内嵌模式;是默认部署方式,元数据存储在derby中,但只能支持一个用户,所以仅用与测试环境。
- 本地模式;数据库采用外部数据库存储元数据。metastore服务和HiveService是在一起的,每多一个来连接,都要新开一个metastore服务。
- 远程模式(需要单独启动metastore);metastore单独部署在一个jvm上。元数据存储也使用外部数据库。
metastore的启动方法,将信息重定向到日志文件目录。
//metastore启动命令
nphup hive --service metastore >/hive/log/metastore.log 2>&1 &
//hiveserver2启动命令
nphup hive --service hiveserver2 >/hive/log/hiveserver2.log 2>&1 &
连接hive有两种客户端,一是第一代的hive,二是beeline。
使用beeline客户端需要,在启动了metastore的情况下启动hiveserver2服务。连接方式为
jdbc:hive2://name:10000
验证的用户名需要在为在Hadoop集群core-site.xml文件中配置。
<property>
<name>hadoop.proxyuser.名称.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.名称.groups</name>
<value>*</value>
</property>
hive中的数据类型分为基本数据类型与集合数据类型:
基本数据类型:
集合数据类型:
- struct类型与java中的对象类似,可以存储“属性”。
- map即是键值对。
- array即是数组。
需要注意的点:
hive中会有隐式转换,在数据与规定的类型不一致时,hive可以将小范围的数据类型转为大范围的数据类型。可以将string类型的数字转为double类型。
hive也可利用cast手动准换类型.
例如:
select '1' + 1 //直接执行将隐式转换为double类型
>>>2.0
select cast('1' as int) + 1 //手动转型为int类型
>>>2
hive的数据定义语言DDL
创建数据库
- 创建语句:
CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];
切换数据库
use database_name;
查看所有数据库
show databases;
第一种情况直接创建数据库:
例如创建了test这个数据库,则在hive规定的HDFS默认文件夹中就会增加以test.db为名的文件夹,这个文件夹即对应这个数据库。
/user/hive/warehouse/test.db
当在test数据库创建test2表后即创建test2文件夹。
/user/hive/warehouse/test.db/test2
只需要将数据上传到指定的文件夹下,hive即会自动将数据映射为一张表。
第二种情况:
- 在创建表时使用location关键字可以任意指定数据库位置。例如在根目录创建数据库mydb。
create database mydb location "/mydb";
删除数据库
- 删除语句
drop database mydb;
- 库有表无法直接删除需要加关键字cascade
drop databases mydb cascade;
修改数据库
- 可以使用ALTER DATABASE命令为某个数据库的DBPROPERTIES设置键-值对属性值,来描述这个数据库的属性信息。
alter database mydb set dbproperties('createtime'='20170830');
查看数据库
- 查看数据库信息
desc database mydb;
- 查看数据库详细信息
desc database extended mydb;
建表语句:
create table test2(
name string, //string类型
friends array<string>, //数组类型
children map<string,int>, //键值对类型
address struct<street:string,city:string> //结构(对象)类型
)
row format delimited fields terminated by "," //每个字段之间用,分割
collection items terminated by "_" //数组之间以_分割
map keys terminated by ":" //key value之间以:分割
lines terminated by "\n"; //以换行分割数据
hive中插入数据等操作都是靠MapReduce程序实现,所以不推荐直接使用插入语句,hive有自己的映射方法。
- 在每次建表成功以后即在表所在的数据库文件夹下创建一个与表同名的文件夹,只需要将数据放入到表所在的这个文件夹下,hive会按照建表时规定的分割符将数据映射为表中的数据。
- 也可以在创建表时指定位置。创建成功后指定位置下的数据就会直接映射到表中成为数据。
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 delimited fields terminated by ...] //指定字段之间的分割符
[collection items terminated by ...] //指定集合元素的分隔符
[map keys terminated by ...] //指定键值对之间的分隔符
[STORED AS file_format] //指定数据存储格式
[LOCATION hdfs_path] //指定表的位置
[TBLPROPERTIES (property_name=property_value, ...)] //设置表的属性(外部表;内部表)
[AS select_statement]
hive的默认分割符为^A (\001) ,这是一种特殊的分隔符,使用的是 ASCII 编码的值,键盘是打不出来的
外部表与内部表的区别:
外部表:在数据库中删除表后,仅仅删除了表与数据之间的映射信息,即只删除了存储在MySQL中的元数据,仅在hive中查询不到这个表,不删除存储在hdfs上的数据。在生产环境中用外部表多。
内部表:在数据库中删除表后,删除元数据与hdfs上的数据。
内部表与外部表之间的转换
alter table tableName set tblproperties('EXTERNAL'='TRUE') //设置内部表为fales,外部表为true
删除表
drop table tableName;
修改表
alter table test3 change age new_age int; //修改列名
alter table test3 add columns(address string); //默认往最后添加字段
alter table test3 replace columns (name string,age int,aex string); //替换所有的列
查询表
show tables; //查看所有的表
desc formatted tableName; //查看表的详细信息
导入数据
1. 本地导入
在导入时,将本地文件上传到hdfs的表对应路径下。
直接导入表内有数据则追加
load data local inpath '/本地的路径' into table staudent;
重写表数据,导入后仅有本次导入内容
load data local inpath '/本地内容' overwrite into table student;
hdfs文件导入
导入时,直接将数据移动到表所在路径下。不复制避免数据重复浪费空间。
load data '/hdfs下路径' into table student;
2. insert方式
直接插入:
insert into student values(180,'小明'),(190,'小红');
将查询到的数据插入:
install into 以追加方式将数据插入
insert overwrite 以重写方式将原数据删除,再写入当前数据。
insert不能插入部分字段数据!
insert into student select * from student1;
3. as select
将查询到的数据以同样形式直接插入表中。
create table student as select * from student1;
4. 直接指定表位置
create table student(
name string,
age int
)
row format delimited fields terminated by ','
location '/mydb/student'
导出数据
- insert导出到本地 通过insert导出的数据null值都会变为\N
insert overwrite local directory '/home/本地' row format delimited fields terminated by "," select * from student;
- insert导出到hdfs
insert overwrite directory '/home/本地' row format delimited fields terminated by "," select * from student;
- 通过Hadoop导出
hdfs dfs -get /mydb/0.00000 /home/wgq/
- 通过EXPORT导出到hdfs上
export table mydb.student to '/路径';
- 通过hive shell命令导出
因为hive -e可以执行语句,再将打印出来的信息重定向到文件中,因为是打印出来的故null仍然为null。
hive -e 'select * from mydb.student;' > /home/wgq/student;
数据迁移
hive中可以用export与import进行数据迁移,export导出表时会将表数据与表的元数据一同导出,再有import导入数据即可。
首先导出数据
export table mydb.student to '/mydb1';
再导入数据
import table test4 from '/mydb1' //注意这里不能写;号