hive 分区和分桶
分区表:
create table fzname_p ( id int, name string, age int, tel string ) PARTITIONED BY (month string) ---指定分区 ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;
分区:
PARTITIONED :表示的是分区,不同的分区会以文件夹的形式存在
创建分区表:
(1) 可以把数据分开存储在不同的文件夹下
(2) 分区的规则,也就是按照那个字段的值进行分区
(3) 对于查询,起到优化的作用,查询某个分区的数据会比较快
1、创建分区表
--【例1】把员工信息按照员工"所属部门"分开存储到不同的分区里面(也就是子文件夹)中 drop table IF EXISTS mydb.emp_dept_p;--如果存在就删掉 create table mydb.emp_dept_p ( empno int, ename string ) PARTITIONED BY (deptno int); --同步数据到分区表中(10、20、30、40) insert overwrite table mydb.emp_dept_p partition(deptno=10) select e.empno, e.ename from mydb.emp e where e.deptno=20; 和oracle差异 1. 建表的时候 oracle 要指定分区,oralce 不用 2. hive的分区字段,不在建表语句当中,需要有类型 3. 插入数据时,hive 需要指定分区的值 select * from emp_dept_p where deptno=10 ---建立员工表,empno,ename,按照 job 来创建分区表emp_job_p。并且把 SALESMAN 的数据插入到 emp_job_p表中的 SALESMAN 分区。
2.动态分区
--设置动态分区
--开启动态分区
set hive.exec.dynamic.partition=true;
--设置动态分区的模式
set hive.exec.dynamic.partition.mode=nonstrict;
exec ---execute
dynamic ---动态
strict --严格的 ---第一个分区必须是静态的,必须指定它值,动态分区(不指定值)只能放在第二个
nonstrict --第一个分区可以是 动态的(不指定值)
-------------动态分区 ---向分区表中插入数据时,只指定字段,不指定值。值从表中的最后一个字段中获取。 CREATE TABLE mydb.emp_par2( empno INT, ename STRING, job STRING, mgr INT, sal DOUBLE, comm DOUBLE, deptno INT ) PARTITIONED BY (hiredate STRING) ---动态分区 ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; --装载数据 INSERT INTO mydb.emp_par2 PARTITION (hiredate) SELECT empno, ename, job, mgr, sal, comm, deptno, hiredate ---动态分区 from mydb.emp;
注意:
1 动态分区在装载数据的时候,分区字段要放在查询的最后一位,这样才能识别到分区字段
2 创建分区表的时候,分区字段不要出现在创建表的字段里面
----查看分区
show partitions 表名;
--桶表(了解)
在分区数量过于庞大以至于可能导致文件系统崩溃时,我们就需要使用分桶来解决问题了。
与分区的区别,分区表针对是目录,也就是存储路径,分桶表,则针对的是文件,把文件分成多个小文件,粒度更细。
1 在Hive分区表中,分区中的数据过于庞大,建议使用桶表
2 在分桶的时候,对指定的字段取hash值,并且使用这个hash值对桶的个数取余来进行分桶
--创建桶表
CREATE TABLE mydb.emp_bucket( empno INT, ename STRING, sal DOUBLE, deptno INT ) clustered by (empno) into 4 buckets ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
--强制设置分桶
set hive.enforce.bucketing = true;
--装载数据
INSERT OVERWRITE TABLE mydb.emp_bucket select empno, ename, sal, deptno from mydb.emp;
----查看数据文件
hadoop fs -ls /user/hive/warehouse/mydb.db/emp_bucket
Found 4 items -rwxr-xr-x 1 root supergroup 84 2021-08-03 21:16 /user/hive/warehouse/mydb.db/emp_bucket/000000_0 -rwxr-xr-x 1 root supergroup 40 2021-08-03 21:16 /user/hive/warehouse/mydb.db/emp_bucket/000001_0 -rwxr-xr-x 1 root supergroup 127 2021-08-03 21:16 /user/hive/warehouse/mydb.db/emp_bucket/000002_0 -rwxr-xr-x 1 root supergroup 41 2021-08-03 21:16 /user/hive/warehouse/mydb.db/emp_bucket/000003_0
备注:
数据分桶存在的一些缺陷:
如果通过数据文件LOAD 到分桶表中,会存在额外的MR负担。
实际生产中分桶策略使用频率较低,更常见的还是使用数据分区。