菜鸡一只,如果有说错的地方还请大家指出批评!
很多人,会有这样的想法:这个东西,很简单嘛,这样这样这样,就可以。当然一部分情况确实是这样的,不过有些时候,让你亲身去做这件事情,你又会觉得完全和想的是两码事,觉得困难重重。
没错,我就是这样!
我一直觉得hive建表,建库很简单啊!但是老是会忘记命令的具体写法,所以特地开一篇帖子来记录下我这个缺点和相关的sql。
1、数据类型:
官网:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
在这里我就记录下简单的东西:
#cast是用来做类型转换的,比如转化日期成为可以加减的时间戳
cast(unix_timestamp(start_time) as bigint)as ts
#修改字段名和类型
ALTER TABLE 表名 CHANGE COLUMN 要修改的字段名 修改后的名字(如果不改可以保留原名) 修改的类型;
#eg.
>create table a(a int ,b string);
>desc a;
a int
b string
#将a表的字段a改成字段c,并且修改类型为DECIMAL(38,18);
>ALTER TABLE a CHANGE COLUMN a c DECIMAL(38,18);
>desc a;
c decimal(38,18)
b string
当然,我要强调下,hive中能使用string解决问题就尽量使用string解决问题,不然后面你会发现一些很不舒服的事情。
比如:
报类型转换异常的错
又比如,一些小数点后面有很多位的数字,展示出来的时候被科学计数法!
关于科学计数法的解决办法:http://www.it610.com/article/761847.htm
2、建库
#创建数据库:
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];
#eg.
create database 数据库名 comment '描述信息' location '/user/warehouse/数据库名.db'
3、建表
我觉得建表的写法比较。。。杂,写全和写不全的区别还是蛮大的。
但是总体上就是规定这么几个东西
- 数据字段分隔符(默认是''/001",一般可以用逗号,tab键,或者“|”来代替,但是最好只用一个字符来分割,不要多个)
- 数据存储方式,官网:https://cwiki.apache.org/confluence/display/Hive/FileFormats(较常用orc,最简单是textfile)
- 其他项,例如:自定义Serde,自定义input或者output
所以不写全,就如下:
#指定分隔符为"|" ,数据格式为文本格式(textfile)
create table origin_log1(
字段1 string,
字段2 string,
字段3 string,
...
字段10 string
)row format delimited fields terminated by '|'
STORED AS TEXTFILE;
create table origin_log2(
字段1 string,
字段2 string,
字段3 string,
...
字段10 string
)row format delimited fields terminated by '\t'
STORED AS ORC;
写全的话:
#创建一张textfile格式的表,并且一级分区为月份,二级分区为天,分隔符为"|"
CREATE TABLE `数据库名`.`表名`(
`字段1` string COMMENT '字段1描述',
`字段2` string COMMENT '字段2描述',
`字段3` string COMMENT '字段3描述',
...
`字段10` string COMMENT '字段10描述'
)
PARTITIONED BY (
`month_id` string,
`day_id` string)
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'field.delim'='|',
'serialization.format'='|')
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 'XXXX'
#如上的location也可以不写,会自动建表到对应数据库的hdfs路径下
写全也容易写错,所以可以通过写不全的方式创建其他格式的表,然后再通过
show create table 表名来查看不同格式的inputformat和outputformat的区别!
最后通过load data方式加载数据
#LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
#从本地上传数据到表中,本地原文件不会消失,相当于copy
load data local inpath 'linux路径上的数据' into table hive中的表名;
#从hdfs上传数据到指定表中,原文件会消失,相当于mv
load data inpath 'hdfs路径上的数据' into table hive中的表名;
#还可以选择overwrite,将表中原有数据先清空,再加载新的数据
哦!在加载数据的时候顺便提一句
hdfs上的数据是可以做压缩的,比如GZip,生成的文件会以gz结尾,如果想要看数据的话,使用-cat会乱码,但是使用-text就不会
#这样会乱码
hive> dfs -cat hdfs://路径/文件名.gz
#这样不会乱码
hive> dfs -text hdfs://路径/文件名.gz
#如果只想看这个文件的前几行,在hive命令行中我没想到怎么操作
#但是可以直接使用hdfs命令+linux命令
bin/hdfs dfs -text hdfs://路径/文件名.gz | head -2
#这样就可以查看前两行文件
诶,然后是拉数据到本地!
#在hive中执行
INSERT OVERWRITE local DIRECTORY 'linux本地的某个目录' select * from 表1 limit 100;
#指定分隔符
insert overwrite local directory 'linux本地的某个目录'
row format delimited fields terminated by '|'
select * from 表1 limit 100;
#在linux命令行中执行
#-S是不显示hive的相关运行日志,数据拉出来之后,将空格替换成"|",但是最好还是用上面的sql
hive -S -e "use 数据库;
select 字段 from 表;" | sed 's/\t/|/g'
#或者可以使用tr命令(因为默认字段是使用\t来分割的)
hive -S -e "select 字段 from 表" | tr "\t" "," > result.csv
更新个内容:
添加自定义UDF的实现:
1、import org.apache.hadoop.hive.ql.exec.UDF;
让自己的类继承UDF这个类
2、手动实现evaluate这个方法
3、然后将这个类打成jar包,放到服务器上
add jar ~/test.jar;
create temporary function bit32 as 'util.SelfUDF';
4、select bit32('字符串'),就可以使用了
再次更新:
设置等等要跑的sql的队列
SET mapreduce.job.queuename=queue3;
再再次更新
修复元数据
单独对某一个分区操作:ALTER TABLE table_name ADD/DROP PARTITION (pt_d = ‘20170101’);
批量修复分区:MSCK REPAIR TABLE table_name;
但是如果批量修复元数据,有可能分区太多导致OOM,可以设置下批次,比如:set hive.msck.repair.batch.size=5000;
大概就是这样,没太多营养,更多的是我自己想记录下,省得每次要用的时候都要翻官网翻博客~