Hive中的内部表、外部表、分区表和分桶表

时间:2022-04-12 02:26:36

Hive中的内部表、外部表、分区表和分桶表

Hive数据仓库中,重要点就是Hive中的四个表。Hive 中的表分为内部表、外部表、分区表和分桶表。

内部表

 

默认创建的表都是所谓的内部表,有时也被称为管理表。因为这种表,Hive 会(或多或少地)控制着数据的生命周期。Hive 默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。当我们删除一个管理表时,Hive 也会删除这个表中数据。管理表不适合和其他工具共享数据。

具体的内部表创建命令

  1. CREATE TABLE emp( 
  2.     empno INT
  3.     ename STRING, 
  4.     job STRING, 
  5.     mgr INT
  6.     hiredate TIMESTAMP
  7.     sal DECIMAL(7,2), 
  8.     comm DECIMAL(7,2), 
  9.     deptno INT
  10.     ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"-- 分隔符\t 

外部表

 

外部表称之为EXTERNAL_TABLE;其实就是,在创建表时可以自己指定目录位置(LOCATION);如果删除外部表时,只会删除元数据不会删除表数据;

具体的外部表创建命令,比内部表多一个LOCATION而已。

  1. CREATE EXTERNAL TABLE emp_external( 
  2.   empno INT
  3.   ename STRING, 
  4.   job STRING, 
  5.   mgr INT
  6.   hiredate TIMESTAMP
  7.   sal DECIMAL(7,2), 
  8.   comm DECIMAL(7,2), 
  9.   deptno INT
  10.   ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t" 
  11.   LOCATION '/hive/emp_external'

「内部表和外部表的区别:」

  • 创建内部表时:会将数据移动到数据仓库指向的路径;
  • 创建外部表时:仅记录数据所在路径,不对数据的位置做出改变;
  • 删除内部表时:删除表元数据和数据;
  • 删除外部表时,删除元数据,不删除数据。

分区表

 

分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive 中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过 WHERE 子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。

具体的分区表创建命令如下,比外部表多一个PARTITIONED。PARTITIONED英文意思就是分区的,需要指定表中的其中一个字段,这个就是根据该字段的不同,划分不同的文件夹。

  1. CREATE EXTERNAL TABLE emp_partition( 
  2.   empno INT
  3.   ename STRING, 
  4.   job STRING, 
  5.   mgr INT
  6.   hiredate TIMESTAMP
  7.   sal DECIMAL(7,2), 
  8.   comm DECIMAL(7,2) 
  9.   ) 
  10.   PARTITIONED BY (deptno INT)   -- 按照部门编号进行分区 
  11.   ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t" 
  12.   LOCATION '/hive/emp_partition'

分桶表

 

分区在HDFS上的表现形式是一个目录,分桶则是一个单独的文件。分桶则是指定分桶表的某一列,让该列数据按照哈希取模的方式随机、均匀地分发到各个桶文件中。

具体的分桶表创建命令如下,比分区表的不同在于CLUSTERED。CLUSTERED英文意思就是群集的。分桶操作和分区一样,需要根据某一列具体数据来进行哈希取模操作,故指定的分桶列必须基于表中的某一列(字段)

  1. CREATE EXTERNAL TABLE emp_bucket( 
  2.   empno INT
  3.   ename STRING, 
  4.   job STRING, 
  5.   mgr INT
  6.   hiredate TIMESTAMP
  7.   sal DECIMAL(7,2), 
  8.   comm DECIMAL(7,2), 
  9.   deptno INT
  10.   CLUSTERED BY(empno) SORTED BY(empno ASCINTO 4 BUCKETS  --按照员工编号散列到四个 bucket 中 
  11.   ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t" 
  12.   LOCATION '/hive/emp_bucket'

「分区表和分桶表的区别:」

Hive 数据表可以根据某些字段进行分区操作,细化数据管理,可以让部分查询更快。同时表和分区也可以进一步被划分为 Buckets,分桶表的原理和 MapReduce 编程中的 HashPartitioner 的原理类似;分区和分桶都是细化数据管理,但是分区表是手动添加区分,由于 Hive 是读模式,所以对添加进分区的数据不做模式校验,分桶表中的数据是按照某些分桶字段进行 hash 散列形成的多个文件,所以数据的准确性也高很多。

分桶表的建表有三种方式:直接建表,CREATE TABLE LIKE 和 CREATE TABLE AS SELECT

  • 注:不能直接向桶表中加载数据,需要使用insert语句插入数据,因此只要见到load data 到桶表的,基本是乱来的。分桶表的数据通常只能使用 CTAS(CREATE TABLE AS SELECT) 方式插入,因为 CTAS 操作会触发 MapReduce,因此分桶的时间是比较长的,因为要进行MapReduce操作。

根据上面命令,成功创建了内部表、外部表、分区表和分桶表。

Hive中的内部表、外部表、分区表和分桶表

下面依次插入数据到四张表,emp.txt具体内容如下:

  1. 7369 SMITH CLERK 7902 1980-12-17 00:00:00 800.00  20 
  2. 7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 1600.00 300.00 30 
  3. 7521 WARD SALESMAN 7698 1981-02-22 00:00:00 1250.00 500.00 30 
  4. 7566 JONES MANAGER 7839 1981-04-02 00:00:00 2975.00  20 
  5. 7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 1250.00 1400.00 30 
  6. 7698 BLAKE MANAGER 7839 1981-05-01 00:00:00 2850.00  30 
  7. 7782 CLARK MANAGER 7839 1981-06-09 00:00:00 2450.00  10 
  8. 7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 1500.00  20 
  9. 7839 KING PRESIDENT  1981-11-17 00:00:00 5000.00  10 
  10. 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 1500.00 0.00 30 
  11. 7876 ADAMS CLERK 7788 1987-05-23 00:00:00 1100.00  20 
  12. 7900 JAMES CLERK 7698 1981-12-03 00:00:00 950.00  30 
  13. 7902 FORD ANALYST 7566 1981-12-03 00:00:00 3000.00  20 
  14. 7934 MILLER CLERK 7782 1982-01-23 00:00:00 1300.00  10 

具体的插入数据命令如下所示:

  1. ## 内部表 
  2. load data local inpath "emp.txt" into table emp; 
  3. ## 外部表 
  4. load data local inpath "emp.txt" into table emp_external; 
  5. ## 分区表 
  6. LOAD DATA LOCAL INPATH "emp.txt" OVERWRITE INTO TABLE emp_partition PARTITION (deptno=10); 
  7. LOAD DATA LOCAL INPATH "emp.txt" OVERWRITE INTO TABLE emp_partition PARTITION (deptno=20); 
  8. LOAD DATA LOCAL INPATH "emp.txt" OVERWRITE INTO TABLE emp_partition PARTITION (deptno=30); 
  9. ## 分桶表 
  10. -- 启用桶表 
  11. set hive.enforce.bucketing=true
  12. -- 限制对桶表进行load操作 
  13. set hive.strict.checks.bucketing = true
  14. INSERT INTO TABLE emp_bucket SELECT *  FROM emp;  --这里的 emp 表就是一张普通的雇员表 

每次向桶表进行INSERT操作,其实都需要创建中间表。

原文地址:https://mp.weixin.qq.com/s/jdmcEB8iwZv1nojXoZyk8w