hive分区、分桶、sql语句

hive分区、分桶、sql语句

1. sql语句

1.1 创建表

CREATE TABLE [IF NOT EXISTS] table_name 
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment] 
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] 
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 
[ROW FORMAT row_format] 
[fields terminated by ] 
[STORED AS file_format] SEQUENCEFILE|TEXTFILE|RCFILE
//如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
[LOCATION hdfs_path]  //文件的路径

eg1:
create table stu_buck(Sno int comment ‘学号’,Sname string comment ‘姓名’,Sex string,Sage int,Sdept string)
comment ‘个人信息表’ sorted by(Sno DESC)
row format delimited //以行为单位 –>划定界限的
fields terminated by ‘,’; //“,”间隔字段 –>终止

1.2 Load 插入数据

 ```
语法结构:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO 
TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

说明:
1、Load 操作只是单纯的复制/移动操作,将数据文件移动到 Hive 表对应的位置。

2、filepath:
相对路径,例如:project/data1 
绝对路径,例如:/user/hive/project/data1 
包含模式的完整 URI,列如:
hdfs://namenode:9000/user/hive/project/data1

3、LOCAL关键字
如果指定了 LOCAL, load 命令会去查找本地文件系统中的 
filepath。如果没有指定 LOCAL 关键字,则根据inpath中的uri[如果指定了 LOCAL,那么:load 命令会去查找本地文件系统中的 filepath。如果发现是相对路径,则路径会被解释为相对于当前用户的当前路径。load 命令会将 filepath中的文件复制到目标文件系统中。目标文件系统由表的位置属性决定。被复制的数据文件移动到表的数据对应的位置。

如果没有指定 LOCAL 关键字,如果 filepath 指向的是一个完整的 URI,hive 会直接使用这个 URI。 否则:如果没有指定 schema 或者 authority,Hive 会使用在 hadoop 配置文件中定义的 schema 和 authority,fs.default.name 指定了 Namenode 的 URI。 
如果路径不是绝对的,Hive 相对于/user/进行解释。Hive 会将 filepath 中指定的文件内容移动到 table (或者 partition)所指定的路径中。]查找文件

4、OVERWRITE 关键字
如果使用了 OVERWRITE 关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。 如果目标表(分区)已经有一个文件,并且文件名和filepath 中的文件名冲突,那么现有的文件会被新文件所替代。

eg: load data local inpath '/hadoopdata/hivetest/test' into table test1;

1.3 select 语句

语法结构
SELECT [ALL | DISTINCT] select_expr, select_expr, ... 
FROM table_reference
[WHERE where_condition] 
[GROUP BY col_list [HAVING condition]] 
[CLUSTER BY col_list 
  | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list] 
] 
[LIMIT number]

1、order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
2、sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。
3、distribute by根据distribute by指定的内容将数据分到同一个reducer。
4、Cluster by 除了具有Distribute by的功能外,还会对该字段进行排序。因此,常常认为cluster by = distribute by + sort by

1.4 其他sql语句

  • 重命名表:ALTER TABLE table_name RENAME TO new_table_name
  • 添加:ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], …)
  • 更新:ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

2. Hive表分区

2.1 为什么要创建分区表?

select查询中会扫描整个表内容,会消耗大量时间。由于相当多的时候人们只关心表中的一部分数据.

2.2 建表的语法

PARTITIONED BY指定按照什么分区,一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。

2.3 单表分区与多表分区

  • 单表分区:create table partition_table (id int, content string) partitioned by (day string)单分区表,按天分区,在表结构中存在id,content,day三列

  • 多表分区: create table partition_table (id int, content string) partitioned by (day string, hour string);双分区表,按天和小时分区,在表结构中新增加了day和hour两列。

2.4 添加分区

表已创建,在此基础上添加分区:

ALTER TABLE table_name ADD
partition_spec [ LOCATION ‘location1’ ]
partition_spec [ LOCATION ‘location2’ ] …
eg: alter table partition_table add partition(day=’2018-1-16’);

eg: 重命名分区:alter table sp_trans2 partition (dt=’2016-01-13’,shop=’001’) rename to partition (dt=’2016-01-13’,shop=’000’)

2.5 删除分区

删除分区语法:ALTER TABLE table_name DROP
partition_spec, partition_spec,…
eg: alter table partition_table drop partition (day=’2018-1-16’);

2.6 数据加载进分区表中语法

LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ..
指定分区加载数据:
eg load data local inpath ‘/hadoopdata/hive/test.txt’ into table partition_table partition (day=’2018-1-15’);

2.7 查看分区

show partitions partition_table;

2.8 静态分区与动态分区

分区表有静态分区和动态分区两种。若分区的值是确定的,那么称为静态分区字段,反之,若分区的值是非确定的,那么称之为动态分区字段。默认是采用静态分区。 —->将查询结果插入Hive表
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 …)] select_statement1 FROM from_statement
eg: insert overwrite table student partition (dy=’2018-1-15’) select id,age,name form student where stat_date=’2018-1-12’;

2.9 导出表数据

eg: insert overwrite local directory /hadoopdata/hive/testdata/student1’ select * from student;

3 分桶

3.1 概念

分桶是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。桶对应于MapReduce的输出文件分区:一个作业产生的桶(输出文件)和reduce任务个数相同

3.2 创建分桶表

create table t_buck(id string,name string)
clustered by (id) sort by(id) into 4 buckets;
指定了根据id分成4个桶,最好的导入数据方式是insert into table.
要开启模式开关
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;
查询时cluster by指定的字段就是partition时分区的key

3.3 分桶的作用

  • join操作:join操作两个表有一个相同的列,如果对这两个表都进行了桶操作,那么将保存相同列值的桶进行join操作,可以大大减少join的数据量.
  • 高效查询效率:当where语句后面的条件是分桶字段,在查询的时候根据字段的值取hash值,然后按照取模结果对数据分桶,到指定的桶去查询。不需要遍历整个文件。

3.4 分区又分桶

create table logs(ts int ,line string) partitioned by (dt String) clustered by (ts) into 4 buckets row format delimited fields terminated by ‘,’;
分区之后继续分桶,我们在hdfs文件系统上看不出分桶的多个数据表文件,只能看见一个文件,但是能从文件路径上看出分区的信息。

4.问题总结

4.1 包不兼容异常

hive 运行删除表语句出现异常:“we don’t support retries at the client level”问题

  • 情况一:mysql-connector-java与hive的版本不兼容,升级mysql-connector-jave
  • 情况二:mysql字符集问题:修改mysql的字符集 ,alter database hive character set latin1;

4.2 hadoop集群时间不同步问题

org.apache.hadoop.yarn.exceptions.YarnException: Unauthorized request to start container
This token is expired. current time is 1526411235575 found 1516159081055
出现这个问题一般是因为hadoop集群中出现了时间不一致问题,同步时间,再运行,ok

  • hadoop集群同步时间
    查看当前时间: date
    选择时区,在每台机子上都要执行: cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    网络同步: ntpdate cn.pool.ntp.org ,如果ntp命令不存在,centos 安装 ntpdate 并同步时间
    在命令行中做如下操作,来安装ntpdate,yum install -y ntp
    或者本地设置:将时间设置为2014年6月18日14点16分30秒(MMDDhhmmYYYY.ss)—- date 0618141614.30

猜你喜欢

转载自blog.csdn.net/wtzhm/article/details/79077878
今日推荐