zoukankan      html  css  js  c++  java
  • Hive的DDL操作

    DDL(数据定义语言)操作

      

      Hive配置单元包含一个名为 default 默认的数据库.

        create database [if not exists] <database name>;---创建数据库

        show databases | schemas; --显示所有数据库

        drop database if exists <database name> [restrict|cascade]; --删除数据库,默认情况下,hive不允许删除含有表的数据库,要先将数据库中的表清空才能drop,否则会报错
        --加入cascade关键字,可以强制删除一个数据库,默认是restrict,表示有限制的
          eg. hive> drop database if exists users cascade;

        use <database name>; --切换数据库

      显示命令

        show tables; --显示当前库中所有表

        show partitions table_name; --显示表的分区,不是分区表执行报错

        show functions;  --显示当前版本 hive 支持的所有方法

        desc extended table_name;  --查看表信息

        desc formatted table_name;  --查看表信息(格式化美观)

        describe database database_name; --查看数据库相关信息

      创建表

        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 row_format]
          [stored as file_format]
          [location hdfs_path]

        说明:

          1、 create table 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 if not exists 选项来忽略这个异常

          2、 external关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径( LOCATION)。

          Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。

          3、 like允许用户复制现有的表结构,但是不复制数据

          create [external] table [if not exists] [db_name.]table_name like existing_table;

          4、row format delimited(指定分隔符)

            [fields terminated by char]

            [collection items terminated by char]

            [map keys terminated by char]

            [lines terminated by char] | serde serde_name

            [with serdeproperties(property_name=property_value, property_name=property_value,...)]

          hive 建表的时候默认的分割符是'01',若在建表的时候没有指明分隔符,load 文件的时候文件的分隔符需要是'01';若文件分隔符不是'001',程序不会报错,但表查询的结果会全部为'null';

          用 vi 编辑器 Ctrl+v 然后 Ctrl+a 即可输入'01' -----------> ^A

          SerDe 是 Serialize/Deserilize 的简称,目的是用于序列化和反序列化。

          Hive 读取文件机制:首先调用 InputFormat(默认 TextInputFormat),返回一条一条记录(默认是一行对应一条记录)。然后调用SerDe (默认LazySimpleSerDe)的 Deserializer,将一条记录切分为各个字段(默认'01')。

          Hive 写文件机制:将 Row 写入文件时,主要调用 OutputFormat、SerDe 的Seriliazer,顺序与读取相反。可通过 desc formatted 表名;进行相关信息查看。当我们的数据格式比较特殊的时候,可以自定义 SerDe。

          5、 partitioned by(分区)

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

        分区表指的是在创建表时指定的 partition 的分区空间。一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。表和列名不区分大小写。分区是以字段的形式在表结构中存在,通过 describe table 命令可以查看到字段存在,但是该字段不存放实际的数据内容,仅仅是分区的表示。

          6、 stored as sequencefile|textfile|rcfile

        如果文件数据是纯文本,可以使用 stored as textfile。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。

        textfile是默认的文件格式,使用 delimited子句来读取分隔的文件。

          7、 clustered by into num_buckets buckets(分桶)

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

        把表(或者分区)组织成桶(Bucket)有两个理由:

        (1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如 JOIN 操作。对于 JOIN 操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行 JOIN 操作就可以,可以大大较少 JOIN 的数据量。

        (2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。


     

    •   内部版要想映射成功 文件位置必须在指定的路径下

        /user/hive/warehouse/xxx.db

    •   要想映射成功 要根据文件指定具体的分隔符

        row format delimited fields terminated by ","

    •   要想映射成功 必须保证定义的表字段顺序类型跟结构化文件中保持一致

      


      本地模式

      有时hive的输入数据量是非常小的。在这种情况下,为查询出发执行任务的时间消耗可能会比实际job的执行时间要多的多。对于大多数这种情况,hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间会明显被缩短。

            如此一来,对数据量比较小的操作,就可以在本地执行,这样要比提交任务到集群执行效率要快很多。

      

    set hive.exec.mode.local.auto=true;

      当一个job满足如下条件才能真正使用本地模式:

                1.job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)

                2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)

        3.job的reduce数必须为0或者1

     hive分隔符:

    ​     row format delimited(hive内置分隔符类) |serde(自定义或者其他分隔符类)

    create table day_table (id int, content string) partitioned by (dt string) row format delimited fields terminated by ',';   ---指定分隔符创建分区表

        

       复杂类型的数据表指定分隔符

    create table complex_array(name string,work_locations array<string>) row format delimited fields terminated by '	' collection items terminated by ',';
    数据:
    1,zhangsan,唱歌:非常喜欢-跳舞:喜欢-游泳:一般般
    2,lisi,打游戏:非常喜欢-篮球:不喜欢
    create table t_map(id int,name string,hobby map<string,string>)
        row format delimited 
        fields terminated by ','
        collection items terminated by '-'
        map keys terminated by ':' ;

      分区表(PARTITIONED BY)(创建子文件夹)

        分区建表分为2种,一种是单分区,也就是说在表文件夹目录下只有一级文件夹目录。另外一种是多分区,表文件夹下出现多文件夹嵌套模式。

        分区字段不是表中真实字段 虚拟字段(它的值只是分区的标识值)

        分区的字段不能是表中已经存有的字段 否则编译出错

        单分区建表语句:
       create table day_table (id int, content string) partitioned by (dt string);单分区表,按天分区,在表结构中存在id,content,dt三列。

        导入数据

         LOAD DATA local INPATH '/root/hivedata/dat_table.txt' INTO TABLE day_table partition(dt='2017-07-07');

        双分区建表语句:

    create table day_hour_table (id int, content string) partitioned by (dt string, hour string);双分区表,按天和小时分区,在表结构中新增加了dt和hour两列。

        导入数据

    LOAD DATA local INPATH '/root/hivedata/dat_table.txt' INTO TABLE day_hour_table PARTITION(dt='2017-07-07', hour='08');

        

        基于分区的查询:

    SELECT day_table.* FROM day_table WHERE day_table.dt = '2017-07-07';

        查看分区:

    show partitions day_hour_table;

          总的说来partition就是辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格和条件进行管理。


      分桶表(cluster by into num buckets)

    • 分桶表是在文件的层面把数据划分的更加细致

    • 分桶表定义需要指定根据那个字段分桶

    • 分桶表分为几个桶最后自己设置的时候保持一致

    • 分桶表的好处在于提高join查询效率 减少笛卡尔积(交叉相差)的数量

          #指定开启分桶(分成几个文件)

    set hive.enforce.bucketing = true;
    set mapreduce.job.reduces=4;//与分桶数相同,少于分桶数时不影响分桶,但是速度会降低

        TRUNCATE TABLE stu_buck;

        drop table stu_buck;

    create table stu_buck(Sno int,Sname string,Sex string,Sage int,Sdept string)
    clustered by(Sno) 
    into 4 buckets
    row format delimited
    fields terminated by ',';

      分桶表导入数据

    insert overwrite table stu_buck
    select * from student cluster by(Sno);//通过查询中间表向分桶表里导入数据,两张表的结构应该相同

    --------------------------------华丽的分割线----------------------------------

      分桶、排序等查询:cluster by 、sort by、distribute by

    select * from student cluster by(Sno);
    insert overwrite table student_buck
    select * from student cluster by(Sno) sort by(Sage); 报错,cluster 和 sort 不能共存

      对某列进行分桶的同时,根据另一列进行排序

    insert overwrite table stu_buck
    select * from student distribute by(Sno) sort by(Sage asc);

      根据指定的字段把数据分成几桶,分成几桶取决于set mapreduce.job.reduces=?  

      当分的字段跟排序的字段不是同一个的时候,distribute by(xxx) sort by(yyy)

      order by 根据指定的字段全局排序 这时候 不管环境设置set mapreduce.job.reduces为几,最终执行的时候都是1个,因为只有一个reducetask才能保证所有的数据来到一个文件中 才能全局排序

      总结:
        cluster(分且排序,必须一样)==distribute(分) + sort(排序)(可以不一样)


      内部表、外部表

        建内部表(映射时需将文件上传到hdfs的固定路径;删除表时,不仅会删除表数据,还会将hdfs中hive路径中的文件删除)

    create table student(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';

        建外部表(文件可以在hdfs的任意位置,但须使用location指定其路径)

    create external table student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',' location '/stu';


        内、外部表加载数据:

          如果加local 表示数据来自于本地(hiveserver2服务运行所在机器的本地文件系统)

    ​         如果不加local 表示数据在hdfs分布式文件系统的某个位置

        • 如果数据存在于本地 load加载数据是纯复制操作

        • 如果数据位于hdfs load加载数据就是移动操作

    load data local inpath '/root/hivedata/students.txt' overwrite into table student;//local指的是hiveserver服务所在的服务器,而不是hivecli或beeline客户端所在的机器(生产环境中hiveserver和hivecli不再一台机器上)
    load data inpath '/stu' into table student_ext;//hdfs中的文件


    修改表

        增加分区:

          alter table table_name add partition (dt='20170101') location '/user/hadoop/warehouse/table_name/dt=20170101'; //一次添加一个分区

          alter table table_name add partition (dt='2008-08-08', country='us') location '/path/to/us/part080808' partition (dt='2008-08-09', country='us') location '/path/to/us/part080809'; //一次添加多个分区

        删除分区

          alter table table_name drop if exists partition (dt='2008-08-08');

          alter table table_name drop if exists partition (dt='2008-08-08', country='us');

        修改分区

          alter table table_name partition (dt='2008-08-08') rename to partition (dt='20080808');

        添加列

          alter table table_name add|replace columns (col_name string);

        注: add 是代表新增一个字段,新增字段位置在所有列后面 (partition 列前 )

          replace 则是表示替换表中所有字段。

        修改列

        test_change (a int, b int, c int);

          alter table test_change change a a1 int; //修改 a 字段名

        // will change column a's name to a1, a's data type to string, and put it after column b. the new

        table's structure is: b int, a1 string, c int

          alter table test_change change a a1 string after b;

        // will change column b's name to b1, and put it as the first column. the new table's structure is:

        b1 int, a ints, c int

          alter table test_change change b b1 int first;

        表重命名

          alter table table_name rename to new_table_name

  • 相关阅读:
    win7为IIS7添加程序映射
    【整理】在一亿个数中寻找出现频率最多的4个 <转>
    优化SQL Server数据库的几个大招<转>
    最长单调子序列(DP)
    详细解说 STL 排序
    获取word中的原始大小图片
    MD5 算法实现(c++)
    udp 通信中的端口问题
    Yacc 与 Lex 快速入门
    HDOJ (HDU) 1561 The more, The Better (树形DP)
  • 原文地址:https://www.cnblogs.com/jifengblog/p/9278600.html
Copyright © 2011-2022 走看看