• 大数据之路Week08_day03 (Hive的动态分区和分桶)


    一、动态分区

    先来说说我对动态分区的理解与一些感受吧。

    由于我们通过hive去查询数据的时候,实际还是查询HDFS上的数据,一旦一个目录下有很多文件呢?而我们去查找的数据也没有那么多,全盘扫描就会浪费很多时间和资源。

    为了避免全盘扫描和提高查询效率,引入了分区的概念。

    分区的展现形式,就是在HDFS上的多级目录展现。

    分区又分为静态分区和动态分区,静态分区是我们在创建表的时候去手动创建分区,然后将文件load上去。

    这样就会显得很麻烦,当我们数据量特别大而且是同一类型数据的时候,手动就会显得很麻烦,也很容易出错。

    于是我们有了动态分区,使用 insert 去插入数据

    在去使用动态分区的时候,我们首先需要开启动态分区。

    开启动态分区支持

      hive>set hive.exec.dynamic.partition=true; (一定要开启!!!!!)

    设置严格动态分区

      hive>set hive.exec.dynamic.partition.mode=nostrict;

    设置最大可以分多少区

      hive>set hive.exec.max.dynamic.partitions.pernode=1000;

    当然,这里需要注意的一点就是,适当的分区可以提高我们的查询效率,但是过多的去分区,效果则会相反,因为分区多了,多级目录就会加深,去查询的时候就会将时间浪费在这个递归查询上面,反而会降低查询效率。

    一般创建动态分区的时候,先将所有数据放在一个目录下,然后通过insert into ... select ...  from ... 的方式将数据加载过去,自动创建 

    举例:(说那么多,不如实际操作记忆深刻)

    首先我们先准备数据

    1,小虎1,12,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    2,小虎2,13,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    3,小虎3,13,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    4,小虎4,12,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    5,小虎5,13,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    6,小虎6,13,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    7,小虎7,13,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    8,小虎8,12,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
    9,小虎9,12,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong

    创建一个普通的表

    create table stu_dy1_1
    (
    id int,
    name string,
    age int,
    gender string,
    likes array<string>,
    address map<string,string>
    )
    row format delimited
    fields terminated by ','
    collection items terminated by '-'
    map keys terminated by ':'

    将数据load到这个表中

    load data local 'Linux本地文件目录' into table stu_dy1_1;

    然后创建动态分区表

    create table stu_dy1_2
    (
    id int,
    name string,
    likes array<string>,
    address map<string,string>
    )partitioned by(age int,gender string)
    row format delimited
    fields terminated by ','
    collection items terminated by '-'
    map keys terminated by ':'

    最后使用inset的方式将stu_dy1_1上的数据加载过来

    from放在前面或者后面都可以

    from stu_dy1_1
    insert into stu_dy1_2 partition(age,gender)
    select id,name,likes,address,age,gender
    
    或者
    
    insert into stu_dy1_2 partition(age,gender)
    select id,name,likes,address,age,gender from stu_dy1_1

    去HDFS上查看

     

     

     二、分桶

    首先,分区和分桶是两个不同的概念,很多资料上说需要先分区在分桶,其实不然,分区是对数据进行划分,而分桶是对文件进行划分。

    当我们的分区之后,最后的文件还是很大怎么办,就引入了分桶的概念。

    将这个比较大的文件再分成若干个小文件进行存储,我们再去查询的时候,在这个小范围的文件中查询就会快很多。

    对于hive中的每一张表、分区都可以进一步的进行分桶。

    当然,分桶不是说将文件随机进行切分存储,而是有规律的进行存储。在看完下面的例子后进行解释,现在干巴巴的解释也不太好理解。它是由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。

    创建顺序和分区一样,创建的方式不一样。

    举例:

    首先我们依然需要开启分桶的支持:

      set hive.enforce.bucketing=true; (依然十分重要,不然无法进行分桶操作!!!!)

    数据准备:(id,name,age)

    1,tom,11
    2,cat,22
    3,dog,33
    4,hive,44
    5,hbase,55
    6,mr,66
    7,alice,77
    8,scala,88

    创建一个普通的表

    create table psn31
    (
    id int,
    name string,
    age int
    )
    row format delimited
    fields terminated by ','

    将数据load到这张表中

    load data local '文件在Linux上的绝对路径' into table psn31;

    创建分桶表

    create table psn_bucket
    (
    id int,
    name string,
    age int
    )
    clustered by(age) into 4 buckets
    row format delimited
    fields terminated by ','

    将数据insert到表psn_bucket中(注意:这里和分区表插入数据有所区别,分区表需要select 和指定分区,而分桶则不需要)

    insert into psn_bucket select id,name,age from psn31;

    去HDFS上查看数据

     

    查询数据

    我们在linux中使用Hadoop的命令查看一下(与我们猜想的顺序一致)

    这里设置的桶的个数是4 数据按照 年龄%4 进行放桶(文件)
    11%4 == 3 -----> 000003_0
    22%4 == 2 -----> 000002_0
    33%4 == 1 -----> 000001_0
    44%4 == 0 -----> 000000_0
    ...以此类推

    在HIve进行查询

    select * from psn_bucket tablesample(bucket 2 out of 2);
    随机取值(设置因子,桶的个数/因子)
    这里就是取2号桶和4号桶,取2个
    select * from psn_bucket tablesample(bucket 2 out of 4); 随机取值(设置因子,桶的个数/因子) 这里就是取2号桶,取一个
    select * from psn_bucket tablesample(bucket 2 out of 8); 随机取值(设置倍数,倍数/桶的个数) 这里就是取2号桶 1/2个数据
    取出来是一条数据


    而我们一般取因子!!!

  • 相关阅读:
    Angular 的性能优化
    通往架构师之路的三本书,高分!
    从单体架构到微服务架构的演化历程
    nginx 配置stream模块代理并开启日志配置
    UnixLinux 执行 shell 报错:“$' ': 未找到命令” 的解决办法
    红胖子(红模仿)的博文大全:开发技术集合大版本更新v4.0.0
    案例分享:Qt高频fpga采集数据压力位移速度加速度分析系统(通道配置、电压转换、采样频率、通道补偿、定时采集、距离采集,导出exce、自动XY轴、隐藏XY轴、隐藏显示通道,文件回放等等)
    字符编码和字符集到底有什么区别?Unicode和UTF-8是什么关系?
    Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解
    【分页机制】-看了这篇文章还没彻底搞懂?我自罚三杯!
  • 原文地址:https://www.cnblogs.com/wyh-study/p/12098756.html
Copyright © 2020-2023  润新知