zoukankan      html  css  js  c++  java
  • hive内部表、外部表

    hive内部表、外部表区别自不用说,可实际用的时候还是要小心。

    Hive的数据分为表数据和元数据,表数据是Hive中表格(table)具有的数据;而元数据是用来存储表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。下面分别来介绍。
      一、Hive的数据存储
      在让你真正明白什么是hive 博文中我们提到Hive是基于Hadoop分布式文件系统的,它的数据存储在Hadoop分布式文件系统中。Hive本身是没有专门的数据存储格式,也没有为数据建立索引,只需要在创建表的时候告诉Hive数据中的列分隔符和行分隔符,Hive就可以解析数据。所以往Hive表里面导入数据只是简单的将数据移动到表所在的目录中(如果数据是在HDFS上;但如果数据是在本地文件系统中,那么是将数据复制到表所在的目录中)。

      Hive中主要包含以下几种数据模型:Table(表),External Table(外部表),Partition(分区),Bucket(桶)(本博客会专门写几篇博文来介绍分区和桶)。

      1、表:Hive中的表和关系型数据库中的表在概念上很类似,每个表在HDFS中都有相应的目录用来存储表的数据,这个目录可以通过${HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.warehouse.dir属性来配置,这个属性默认的值是/user/hive/warehouse(这个目录在HDFS上),我们可以根据实际的情况来修改这个配置。如果我有一个表wyp,那么在HDFS中会创建/user/hive/warehouse/wyp目录(这里假定hive.metastore.warehouse.dir配置为/user/hive/warehouse);wyp表所有的数据都存放在这个目录中。这个例外是外部表。

      2、外部表:Hive中的外部表和表很类似,但是其数据不是放在自己表所属的目录中,而是存放到别处,这样的好处是如果你要删除这个外部表,该外部表所指向的数据是不会被删除的,它只会删除外部表对应的元数据;而如果你要删除表,该表对应的所有数据包括元数据都会被删除。

      3、分区:在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如wyp表有dt和city两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse/dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。

      4、桶:对指定的列计算其hash,根据hash值切分数据,目的是为了并行,每一个桶对应一个文件(注意和分区的区别)。比如将wyp表id列分散至16个桶中,首先对id列的值计算hash,对应hash值为0和16的数据存储的HDFS目录为:/user/hive/warehouse/wyp/part-00000;而hash值为2的数据存储的HDFS 目录为:/user/hive/warehouse/wyp/part-00002。

      来看下Hive数据抽象结构图

    <ignore_js_op> 

    Data Abstractions in Hive



    从上图可以看出,表是在数据库下面,而表里面又要分区、桶、倾斜的数据和正常的数据等;分区下面也是可以建立桶的。

      二、Hive的元数据
      Hive中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。 由于Hive的元数据需要不断的更新、修改,而HDFS系统中的文件是多读少改的,这显然不能将Hive的元数据存储在HDFS中。目前Hive将元数据存储在数据库中,如Mysql、Derby中。我们可以通过以下的配置来修改Hive元数据的存储方式

    1. <property>
    2.   <name>javax.jdo.option.ConnectionURL</name>
    3.   <value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8
    4.                     &createDatabaseIfNotExist=true</value>
    5.   <description>JDBC connect string for a JDBC metastore</description>
    6. </property>
    7. <property>
    8.   <name>javax.jdo.option.ConnectionDriverName</name>
    9.   <value>com.mysql.jdbc.Driver</value>
    10.   <description>Driver class name for a JDBC metastore</description>
    11. </property>
    12. <property>
    13.   <name>javax.jdo.option.ConnectionUserName</name>
    14.   <value>root</value>
    15.   <description>username to use against metastore database</description>
    16. </property>
    17. <property>
    18.   <name>javax.jdo.option.ConnectionPassword</name>
    19.   <value>123456</value>
    20.   <description>password to use against metastore database</description>
    21. </property>
    复制代码


     当然,你还需要将相应数据库的启动复制到${HIVE_HOME}/lib目录中,这样才能将元数据存储在对应的数据库中。

    1. 内部表:

    create table tt (name string , age string) location '/input/table_data';


    此时,会在hdfs上新建一个tt表的数据存放地,例如,笔者是在 hdfs://master/input/table_data 

    上传hdfs数据到表中:

    load data inpath '/input/data' into table tt;


    此时会将hdfs上的/input/data目录下的数据转移到/input/table_data目录下。

    删除tt表后,会将tt表的数据和元数据信息全部删除,即最后/input/table_data下无数据,当然/input/data下再上一步已经没有了数据!

    如果创建内部表时没有指定location,就会在/user/hive/warehouse/下新建一个表目录,其余情况同上。

    注意的地方就是:load data会转移数据!

    2. 外部表:

    create external table et (name string , age string);


    此时,会在/user/hive/warehouse/新建一个表目录et

    load data inpath '/input/edata' into table et;

    此时会把hdfs上/input/edata/下的数据转到/user/hive/warehouse/et下,删除这个外部表后,/user/hive/warehouse/et下的数据不会删除,但是/input/edata/下的数据在上一步load后已经没有了!数据的位置发生了变化!本质是load一个hdfs上的数据时会转移数据!

    3. 其他:

    (1)加上location用法一样,只不过表目录的位置不同而已。

    (2)加上partition用法也一样,只不过表目录下会有分区目录而已。

    (3)load data local inpath直接把本地文件系统的数据上传到hdfs上,有location上传到location指定的位置上,没有的话上传到hive默认配置的数据仓库中。

  • 相关阅读:
    算法竞赛入门经典训练指南
    git保护--git分支创建
    解决多个iframe嵌套而造成的多个滚动条问题
    css如何让div元素铺满整个屏幕
    第一个用python3写的爬虫小例子
    用JS获取当前页面的URL以及截取其中的字段
    css处理超出文本截断问题的两种情况(多行或者单行)
    约数的个数
    成绩排序
    八进制
  • 原文地址:https://www.cnblogs.com/catWang/p/4358082.html
Copyright © 2011-2022 走看看