美文网首页
Hive Partitioning

Hive Partitioning

作者: watermark | 来源:发表于2021-04-08 14:41 被阅读0次

    Hive 分区是一项特别强大的功能,通过分区可以将一个表划分为更多的 pieces(实际上一个分区物理上对应 HDFS 一个目录),从而可以以更细的粒度对数据进行管理和访问。

    分区的优点如下:

    • 分区也有助于查询性能的提升,我们可以直接查询某个分区的数据,避免了对表中的全量数据进行扫描。
    • 借助分区,可以减少诸如 mapper 的数量,I/O 操作等系统资源。

    分区的种类

    分区可以进一步分为 静态分区动态分区

    分区表的创建语法:

    CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] 
      [db_name.]table_name
      [(col_name data_type [column_constraint_specification] [COMMENT col_comment],
      [COMMENT table_comment]
      [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)];
    

    静态分区

    静态分区需要明确指定向哪个分区写入。静态分区是可以 alter 的。
    使用静态分区特性需要在 hive-site.xml 中设置属性 hive. mapred.mode = strict
    通过以下例子感受一下静态分区。

    • 创建表
    CREATE TABLE user_data (
    user_id INT,
    user_name string,
    site_data string
    ) PARTITIONED BY (
    date_dt string,
    country string
    );
    
    create-table.png
    • 插入数据
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-29', country='US') VALUES(201, 'Wick', 'Google');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='UK') VALUES(202, 'John', 'Facebook');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='UK') VALUES(203, 'Partick', 'Instagram');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-29', country='UK') VALUES(204, 'Hema', 'Google');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-28', country='INDIA') VALUES(205, 'Holi', 'Facebook');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='RUSSIA') VALUES(206, 'Michael', 'Insatgram');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='RUSSIA') VALUES(207, 'Chung', 'Instagram');
    INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-22', country='NEPAL') VALUES(208, 'Anna', 'Instagram');
    
    show-partitions.png

    默认情况下,表会创建在 HDFS 的 /user/hive/warehouse 路径(本例指定创建位置为 /user/spark/spark-sql-warehouse)。

    由于我们的分区列为 date_dt 和 country 两列,相应的,可以在 HDFS 看到 user_data 的数据为以 date_dt 的取值作为第一级目录,country 的取值作为第二级目录进行存储。

    hdfs-ls-1.png hdfs-ls-2.png

    动态分区

    动态分区可以自动识别分区,不需要明确指定分区。例如,如果数据已经存储在一个非分区的表中,现在需要将数据转储到一个分区表中,此时动态分区比较适合。
    动态分区比静态分区更加耗时,且分区不可修改
    使用动态分区特性需要在 hive-site.xml 中设置属性 hive.exec.dynamic.partition.mode= nonstrict

    通过以下例子感受一下动态分区:

    准备两个表,user_data_dyn 和 user_log_data。user_data_dyn 是分区表,以 date_dt 列和 country 列作为分区列。user_log_data 为非分区表,接下来将数据从非分区表 user_log_data 转储到分区表 user_data_dyn 中。

    • 创建表非分区表 user_log_data
    CREATE TABLE user_log_data (
    user_id int,
    user_name string,
    site_data string,
    date_dt string,
    country string
    );
    
    • 向 user_log_data 中插入测试数据
    INSERT INTO TABLE user_log_data VALUES(1001, 'John', 'Google', '2016-04-27', 'US');
    INSERT INTO TABLE user_log_data VALUES(1002, 'Eric', 'Facebook', '2016-04-28', 'US');
    INSERT INTO TABLE user_log_data VALUES(1003, 'Annie', 'Instagram', '2016-04-28', 'UK');
    INSERT INTO TABLE user_log_data VALUES(1005, 'Ming', 'Google', '2016-04-29', 'CHINA');
    INSERT INTO TABLE user_log_data VALUES(1006, 'Li', 'Facebook', '2016-04-29', 'CHINA');
    INSERT INTO TABLE user_log_data VALUES(1007, 'Sota', 'Insatgram', '2016-04-29', 'JAPAN');
    INSERT INTO TABLE user_log_data VALUES(1008, 'Yuto', 'Instagram', '2016-04-27', 'JAPAN');
    INSERT INTO TABLE user_log_data VALUES(1009, 'Anna', 'Instagram', '2016-04-28', 'AUSTRALIA');
    INSERT INTO TABLE user_log_data VALUES(1010, 'Ricky', 'Facebook', '2016-04-28', 'AUSTRALIA');
    
    • 创建分区表 user_data_dyn
    CREATE TABLE user_data_dyn (
    user_id int,
    user_name string,
    site_data string
    ) PARTITIONED BY (
    date_dt string,
    country string
    );
    
    • 将数据从 user_log_data 转储到 user_data_dyn
    SET hive.exec.dynamic.partition = true;
    SET hive.exec.dynamic.partition.mode = nonstrict; 
    
    INSERT OVERWRITE TABLE user_data_dyn
    PARTITION(date_dt, country)
    SELECT user_id, user_name, site_data, date_dt, country FROM user_log_data; 
    

    可以看到动态分区已经基于 date_dt 和 country 自动创建:

    dynamic-partitions.png
    • 分区删除

    对 user_data_dyn 中的分区执行删除操作,感受一下分区的便捷。不知道为什么,就想删掉那个叫 JAPAN 的 country:

    alter table user_data_dyn drop partition (date_dt='2016-04-27', country='JAPAN');
    
    drop-partitions.png

    最后对 静态分区 和 动态分区 做一下对比:

    分区方式 优点 缺点
    静态分区 速度快,分区设定后可以更改 需要明确指定分区
    动态分区 速度慢,分区不可更改 自动创建分区

    相关文章

      网友评论

          本文标题:Hive Partitioning

          本文链接:https://www.haomeiwen.com/subject/inpmkltx.html