这里是在基于完成mysql数据库的安装后使用Hive:
在windows中使用navicat远程登录到Linux下面的mysql数据之后,在mysql数据库里面有个DBS表,该表存放的就是hive表在hdfs系统中的路径,这里默认应该是hdfs://hadoop0:9000/user/hive/warehouse,现在为了简单将默认存放路径修改为/hive,那么这里会显示为:hdfs://hadoop0:9000/hive;
Hive的数据模型-数据库
1)类似传统数据库的DataBase;
2)默认数据库"default";
使用#hive命令后,不使用hive>use,系统默认的数据库。可以显示使用hive>use
default;
创建一个新的数据库:
hive>create database test_dw;
Hive的数据模型-表
1)Table:内部表;
2)Partition:分区表;
3)External Table:外部表;
4)Bucket Table:桶表;
这里介绍下hive的这几种类型的表:
1. 内部表
1.1 创建一个普通的内部表:
create table t1(id string);
创建之后的t1存放在hdfs://hadoop0:9000/hive里面;
加载数据:
这里的命令有两种形式:
一种是加载Linux系统本地的文件数据到hive表,需要用local指定,inpath指定Linux的绝对路径;
LOAD DATA LOCAL INPATH '/root/id' INTO TABLE t1;
一种是直接加载hdfs系统上面的某个文件,则不需要local,inpath指定hdfs系统根路径下面的某个文件):
LOAD DATA INPATH '/id' INTO TABLE t1;
注1:这里如果是加载hdfs系统上面的文件,每次加载完成后都会hdfs上面的文件的数据都已经加载hive表中,该文件存储在hdfs系统的指定路径,但是在hdfs系统的根路径下面就消失了,这里的根路径也可以是自定义的文件存放路径;
注2:hive表中的数据其实是一个数据文件,它是创建在hive下面的某个文件下的;
注3:hive里面的数据加载除了LOAD的加载方式外,还可以使用hadoop fs -put id /hive/t1/id2
这个命令来加载数据;
1.2 指定hive表字段直接的分隔符:
在hive的实际使用中,创建一个表,肯定不止一个字段,都是多个字段,所以当有多个字段的时候,就需要在创建表的时候指定各个字段直接的分隔符是什么:
创建一个两个字段的表:
CREATE TABLE t2(id int, name string) ROW FORMAT DELIMITED FIELDS
TERMINATED BY '\t';
注:行格式化,使用制表符(也可以指定其他的符号来区分)分隔各个字段,这个分隔其实是分隔的数据文件里面的字段值,好让各个值按顺序对应到hive的指定字段中;
使用命令:load data inpath '/user.txt' into t2;
或者是:hadoop fs -put stu /hive/t2
查询数据:select * from t2;
查看t2表的ID字段:select id from t2;
注:这时会发现,hive后台调用了mapreduce来执行该语句,所以在hive中所有的查询,除了select *
以外,其他的都要走mapreduce;
Load操作:当数据加载到表中时,不会对数据进行任何转换。Load操作知识将数据复制/移动到hive表对应的位置;
在hive中创建的表也会在mysql里面映射出来:
登录navicat后进入hadoop0数据库,查看TBLS,就能看到所有的内部表,同时这两个表的字段存放在COLUMNS_V2中;
2. 分区表
指的是hive里面的数据分区,分区就是按照某个不同的字段,把文件划分为不同的标准,比如在实际项目中,电信行业每天数据量很大,我们可以用时间来作为分区存放数据,方便按天查询;
使用partitioned by来创建分区表(例如:按天分区)
创建表:create table t3(id int) partitioned by (day int);
加载数据:load data inpath '/id' into table t3 partition (day=28);
分区表加载之后和内部表明显的区别是:在t3下面多了个目录,该目录为分区字段:day=28;
这样可以根据分区字段day来过滤查询:
select * from t3 where day=28;
3. 桶表(使用比较少,仅仅在表连接里面使用)
桶表时数据进行哈希取值,然后放到不同的文件中存储,就是把数据按照某个字段分到桶中;
创建表:
create table bucket_table(id string) clustered by(id) into 4
buckets;
加载数据:
先执行(启用桶加载):set hive.enforce.bucketing = true;
再执行:insert into table bucket_table select name from t3;
注1:这里不能用LOAD来加载:因为load加载的不走mapreduce计算,但是桶表要求走mapreduce计算;
可以进入浏览器查看桶表,发现bucket_table下面有四个file,没有文件里面都存放了数据,桶表的这一特点表示:分到同一个桶表里面的数据的哈希值非常有可能相等;
注2:分区表和桶表都是对数据进行划分,它们的区别是:分区表是使用文件夹划分,桶表是使用文件划分;
注3:以上三种表统称为受控表(MANAGED_TABLE),而下面的外部表则是(EXTERNAL_TABLE);
4. 外部表
外部表只有一个过程,加载数据和创建表同时完成,并不会移动数据到数据库目录下,只是与外部建立一个连接;
外部表的优点:当删除一个外部表时,仅仅只是删除了该链接,而数据本身(hdfs上面的数据文件)依然存在;
在创建之前,先在hdfs上面创建一个文件夹,将数据文件上传到该文件夹下,例如:hdfs://hadoop0:9000/external/id;
创建表:
create external table t5(id int) location '/external';
使用location指定该文件夹即可,不用指定到具体文件;
因为外部的目录就已经指定了数据在哪里,这里指定的外部路径就是:hdfs://hadoop0:9000/external下面,所以就无需加载,直接查询就行:
查询数据:
select * from t5;
删除表之后数据文件依然存在,只是删除了一个链接:
drop table t5;
5. 视图
视图可以屏蔽掉复杂的操作、进行一些权限的控制,创建的语法和前面基本没有区别:
create view v1 AS select * from t1;
6. 表的修改
表的修改:
alter table target_tab add columns(cols, string);
表的删除:
drop table target_tab;
7. 导入数据
当数据被加载至表中时,不会对数据进行任何转换。Load 操作只是将数据复制/移动至 Hive 表对应的位置。
LOAD:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE
tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
把一个Hive表导入到另一个已建Hive表:
INSERT OVERWRITE TABLE tablename [PARTITION (partcol1=val1,
partcol2=val2 ...)] select_statement FROM from_statement
CTAS:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name (col_name
data_type, ...) … AS SELECT …
例:create table new_external_test as select * from
external_table1;