数据仓库工具Hive实践

数据仓库工具Hive实践

官网命令链接:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select

一、DDL库操作

数据定义语言 Data Definition Language

(一)针对库

创建库、查看库、删除库、修改库、切换库

    1、创建库
        create database myhive;
        create database if not exists myhive;
    
    CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
    小括号表示必选,小括号中间的竖线表示或者,中括号表示可选。
        create database myhive_1 comment "myhive_1 database 1" location "/myhive_1";
        # location是HDFS的目录
    2、查看库
        show databases;//查看所有的库
        desc  database  [extended]  myhive_1; //显示数据库的详细属性信息 
        select current_database();//查看当前使用的库
    3、删除库
        默认:
        drop database myhive_1; 等价于     drop database myhive_1 RESTRICT;
        drop database if exists myhive_1; 
        drop database myhive_1 cascade;//强制级联删除,慎用!慎用!慎用!
    4、修改库
        不同版本可以使用的功能不同
        不常用!!
    5、切换库
        use myhive;     
(二)针对表

创建表、删除表、修改表、查看表、查看某张表的详细信息。

    1、查看表
        show tables;
        show tables in myhive;//在当前库查看另外一个库的表的信息
        show tables "stu*"; //正则匹配表名查询
    2、查看某张表的详细信息
        desc student;
        desc formatted student;    //查看表的格式化了之后的详细信息
        desc extended student;    //查看表的详细信息
        show create table student_ptn;     //查看建表完整语法
        show partitions student_ptn;          //查看分区

相关名词解释

CREATE TABLE创建一个指定名字的表。

EXTERNAL关键字可以让用户创建一个外部表。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。

PARTITIONED BY在 Hive Select 查询中一般会扫描整个表内容,会消耗很多时间做没必要 的工作。 有时候只需要扫描表中关心的一部分数据,因此建表时引入 partition 概念。

LIKE允许用户复制现有的表结构,但是不复制数据。

COMMENT可以为表与字段增加描述。

ROW FORMAT用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。

STORED AS TEXTFILE | SEQUENCEFILE | RCFILE : 如果文件数据是纯文本,可以使用 STORED AS TEXTFILE,默认也是 textFile 格式,可以通过执行 命令 set hive.default.fileformat,进行查看,如果数据需要压缩,使用 STORED AS SEQUENCEFILE。 RCFILE 是一种行列存储相结合的存储方式。

CLUSTERED BY:对于每一个表(table)或者分区,Hive 可以进一步组织成桶,也就是说桶是更为细粒 度的数据范围划分。Hive 也是针对某一列进行桶的组织。Hive 采用对列值哈希,然后 除以桶的个数求 余的方式决定该条记录存放在哪个桶当中。

LOCATION指定数据文件存放的 HDFS 目录,不管内部表还是外表,都可以指定。不指定就在默认的 仓库路径。

    3、创建表
        
        分桶表
        示例:CLUSTERED BY department SORTED BY age ASC,id DESC INTO 3 BUCKETS
        
        Create Table ... As Select  简称CTAS
        
        create table studentss like student; //复制表结构,不是复制数据 
        创建表的类型有6种:
        (1)创建内部表
        create table student(id int, name string, sex string, age int, department string) row format delimited fields terminated by ",";
            
            内部表的类型:MANAGED_TABLE
            
        (2)创建外部表
        create external table student_ext_1(id int, name string, sex string, age int, department string) row format delimited fields terminated by ",";

        内部表和外部表的对比:
            1、在创建表的时候指定关键字: external
            2、一般来说,创建外部表,都需要指定一个外部路径  
        内部表和外部表的区别:
            删除表的时候,内部表会都删除,外部表只删除元数据
        到底选择内部表还是外部表?
            1、如果数据已经存储在HDFS上面了,需要使用hive去进行分析,并且这份数据还有可能使用其他的计算引擎来执行分析,使用外部表
            2、如果这个一份数据只是hive做数据分析使用,就可以使用内部表
        
        // 指定一个不存在的外部路径: 创建表的时候,会自动给你创建表目录
        create external table student_ext_2(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," location "/student_ext_2";

        // 指定一个已经存在的目录: 并且有数据
        //在linux中执行
        //hadoop fs -mkdir -p /student_ext_3
        //hadoop fs -put /home/bigdata/data/student.txt /student_ext_3
        //在hive命令行中执行
        create external table student_ext_3(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," location "/student_ext_3";
        
        
        (3)创建分区表
        
        // 创建只有一个分区字段的分区表:
        create table student_ptn(id int, name string, sex string, age int, department string) partitioned by (city string comment "partitioned field") row format delimited fields terminated by ",";

        load data local inpath "/home/bigdata/data/student.txt" into table student_ptn;  //错误XXXXXX

        // 把数据导入到一个不存在的分区,它会自动创建该分区
        load data local inpath "/home/bigdata/data/student.txt" into table student_ptn partition(city="beijing");  //正确√√√√√√

        注意:partitioned里的字段不能是表中声明的字段
        分区字段是虚拟列,它的值是存储在元数据库中,不是存储在数据文件中。
        分区字段的使用和普通字段没有区别

        // 把数据导入到一个已经存在的分区
        alter table student_ptn add partition (city="chongqing"); //没有变化
        load data local inpath "/home/bigdata/data/student.txt" into table student_ptn partition(city="chongqing"); //数据翻倍
                

        // 创建有多个分区字段的分区表:
        create table student_ptn_date(id int, name string, sex string, age int, department string) partitioned by (city string comment "partitioned field", dt string) row format delimited fields terminated by ",";

        // 往分区中导入数据:
        load data local inpath "/home/bigdata/data/student.txt" into table student_ptn_date partition(city="beijing");  //错误XXXXXX

        load data local inpath "/home/bigdata/data/student.txt" into table student_ptn_date partition(city="beijing", dt='2012-12-12');     //正确√√√√√√

        // 不能在导入数据的时候指定多个分区定义
        load data local inpath "/home/bigdata/data/student.txt" into table student_ptn_date partition(city="beijing", dt='2012-12-14') partition(city="beijing" , dt='2012-12-13');   //错误XXXXXX

        // 添加分区
        alter table student_ptn_date add partition(city="beijing", dt='2012-12-14') partition (city="beijing" , dt='2012-12-13');     //正确√√√√√√
        alter table student_ptn_date add partition(city="chongqing", dt='2012-12-14') partition (city="chongqing" , dt='2012-12-13'); 

        // 查询一个分区表有那些分区
        show partitions student_ptn;
        show partitions student_ptn_date;
        show partitions student; //报错
        
        (4)创建分桶表
        
        // 创建一个分桶表
        create table student_bucket (id int, name string, sex string, age int, department string) clustered by (department) sorted by (age desc, id asc) into 3 buckets row format delimited fields terminated by ",";

        //desc formatted student_bucket;
        //Num Buckets:          3                        
        //Bucket Columns:       [department]             
        //Sort Columns:         [Order(col:age, order:0), Order(col:id, order:1)]   

        注意:clustered里的字段必须要是表字段中出现的字段
        分桶字段和排序字段可以不一样,分桶字段和排序字段都必须是表字段中的一部分

        你往分通表里面导入数据要通过分桶查询方式进行导入数据。
        
        
        (5)从查询语句的结果创建新表
        //通过下面的命令:
        create table ... as  select ....
        //查询例子:
        select department, count(*) as total from student group by department;
        //完整的CTAS语句:
        create table dpt_count as select department, count(*) as total from student group by department;
                        
        (6)通过like复制已有表的结构创建新表
        create table student_like like student;
    4、删除表
    drop table student;
    drop table if exists student;   
    5、修改表
        
        1)修改表名
        alter table student_like rename to studentss;

        2)修改字段

            添加字段: 
            alter table student2 add columns (city string, dt string);
            删除字段: 
            alter table student2 drop columns (city);   //报错XXXXXX
            替换字段:
            alter table student2 replace columns (id int, name string, sex string, age int);
            改变列的定义:
            alter table student2 change id newid string comment "new id";
            改变列的顺序:
            alter table student2 change sex sex string first;
            alter table student2 change name name string after sex;

        3)修改分区

            添加分区:
            alter table student_ptn add partition(city='tiajin') partition(city='shanghai');

            删除分区:
            alter table student_ptn drop partition(city='tiajin');  
            alter table student_ptn drop partition(city='tiajin'),partition(city='shanghai'); 

            修改分区的数据目录:
            alter table student_ptn partition(city="beijing") set location "/stu_beijing";   //报错XXXXXX
            alter table student_ptn partition(city="beijing") set location "hdfs://bigdata02:8020/stu_beijing";  //正确√√√√√√
    
    6、清空表
    truncate table student;//清空表只是清空该表的所有数据文件
    hadoop fs -rm -r /user/hive/warehouse/myhive.db/student/*       

三、DML操作

数据操纵语言 Data Manipulation Language

    1、导入数据
    LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
    (1)LOAD操作是复制或者移动操作,将数据文件复制或移动到Hive设置的路径上。
    写LOCAL的是复制,不写LOCAL是移动
    //导入本地绝对路径数据:
    load data local inpath "/home/bigdata/data/student.txt" into table student;

    //导入本地相对路径的数据:
    load data local inpath "./student.txt" into table student;
    load data local inpath './student.txt' overwrite into table student;
    (覆盖导入)

     导入本地数据,相当于复制或者上传

    //导入HDFS上的简便路径数据:
    // hadoop fs -put /home/bigdata/data/student.txt /
    load data inpath '/student.txt' into table student;

    //导入HDFS上的全路径模式下的数据:
    load data inpath 'hdfs://bigdata02:9000/student.txt' into table student;

    导入HDFS上的数据到hive表,表示截切,移动

    insert
    insert into table student (id, name, sex, age, department) values (101,"huangbo","M",222,"IT");
    
    创建分区表:

    create table student_ptn (id int, name string, sex string, age int) partitioned by (department string) row format delimited fields terminated by ",";


    单重插入:
    insert into table student_ptn partition (department = 'IS') select id,sex,name,age from student where department  = 'IS';
    insert into table student_ptn partition (department = 'CS') select id,sex,name,age from student where department  = 'CS';
    insert into table student_ptn partition (department = 'MA') select id,sex,name,age from student where department  = 'MA';


    多重插入:
    from student 
    insert into table student_ptn partition (department = 'IS') select id,sex,name,age where department = 'IS' 
    insert into table student_ptn partition (department = 'CS') select id,sex,name,age where department = 'CS' 
    insert into table student_ptn partition (department = 'MA') select id,sex,name,age where department = 'MA' 
    
    多重插入最大的好处就是给很多结构相同的SQL语句组合在一起提高所有的HQL的执行效率,翻译成的MapReduce只需要读取一次数据就搞定了。

        分区插入:
    需要手动的创建分区
    alter table student add partition (city="zhengzhou")
    load data local inpath '/student.txt' into table student partition(city='zhengzhou');


    CTAS(create table ... as select ...)(直接把查询出来的结果存储到新建的一张表里)
    内部表/内建表
    create table student as select id,name,age,department from mingxing;
    注意:自动新建的表中的字段和查询语句出现的字段的名称,类型,注释一模一样

    限制:
    1、不能创建外部表
    2、不能创建分区表
    3、不能创建分桶表

    分桶插入:
    创建分桶表:
    create table mingxing(id int, name string, sex string, age int, department string)
    clustered by(id) sorted by(age desc) into 4 buckets
    row format delimited fields terminated by ',';

    //不能使用load方式直接往分桶表中导入数据
    插入数据:
    insert into table mingxing select id,name,sex,age,department from mingxing2
    distribute by id sort by age desc;
    注意:查询语句中的分桶信息必须和分桶表中的信息一致

    2、导出数据
    单模式导出数据到本地:
    insert overwrite local directory '/root/outputdata' select id,name,sex,age,department from mingxing;

    多模式导出数据到本地:
    from mingxing
    insert overwrite local directory '/root/outputdata1' select id, name
    insert overwrite local directory '/root/outputdata2' select id, name,age

    简便路径模式导出到hdfs:
    insert overwrite directory '/root/outputdata' select id,name,sex,age,department from mingxing;

    全路径模式查询数据到hdfs:
    insert overwrite directory 'hdfs://bigdata02:9000/root/outputdata1' select id,name,sex,age,department from mingxing;

    local :导出到本地目录
    overwrite :表示覆盖
    3、查询数据
     Hive 中的 SELECT 基础语法和标准 SQL 语法基本一致,支持 WHERE、DISTINCT、GROUP BY、 ORDER BY、HAVING、LIMIT、子查询等

    order by : 全局排序
    sort by :局部排序
    一般来说,要搭配 分桶操作使用
    distribute by id sort by age desc;
    
    distribute by : 纯粹就是分桶
    在使用distribute by的时候:要设置reduceTask的个数

    cluster by : 既分桶,也排序
    cluster by age = distribute by age sort by age;
    
    cluster by 和 sort by 不能同时使用

    where , group by, distinct ,having ,  case...when, ....

四、Hive视图

和关系型数据库一样,Hive 也提供了视图的功能,不过请注意,Hive 的视图和关系型数据库的数据还 是有很大的区别:

1、只有逻辑视图,没有物理视图;
2、视图只能查询,不能 Load/Insert/Update/Delete 数据;
3、视图在创建时候,只是保存了一份元数据,当查询视图的时候,才开始执行视图对应的那些子查询 。

1、创建视图 
    create view view_name as select * from carss; create view carss_view as select * from carss limit 500; 

2、查看视图
    show tables;   // 可以查看表,也可以查看视图 
    desc view_name  // 查看某个具体视图的信息 
    desc carss_view 

3、删除视图 
    drop view view_name drop view if exists carss_view 

4、使用视图 
    create view sogou_view as select * from sogou_table where rank > 3 ; 
    select count(distinct uid) from sogou_vi

你可能感兴趣的:(数据仓库工具Hive实践)