BI:商业智能
BIEE:oracle的bi框架
HADOOP:
hdfs
mapreduce
yarn
Hive:分布式数据仓库
Zookeeper
HBase:基于hadoop的分布式nosql数据库(phoenix)
flume:日志采集
sqoop:数据库数据采集
kafka:消息系统
scala:语言
spark:数据计算软件栈
-------------------------------------------------------------
kettle:etl工具
elasticsearch:全文检索搜索引擎
storm:(实时数据)流处理工具
cdh:clouderamanager
hue
impala
oozie、azkban:调度系统,工作流框架
-------------------------------------------------------------
一级:
大数据存储:HBase、hdfs
大数据计算:Hive、spark(scala)
二级:
数据搜集:flume、kafka、sqoop
三级:
etl工具:kettle
不重要,不需要在上面画太多时间,了解即可:
elasticsearch、storm、cdh、oozie、azkban
-------------------------------------------------------------
特级:
sql
表结构--schema---模式
作业代码提交:
svn
git
svn:server端---》visualSVN
client端---》TortoiseSVN
server:repositories-->知识库(一个目录或者文件夹)
users-->用户
groups-->用户组,权限组
钩子:触发器,过滤器,拦截器,监听器
默认端口:443
https://192.168.6.133/svn/bd19/
https://192.168.6.177:444/svn/bd20/
---------------------------------------------------------------hive
hive安装需要安装两个软件:
1.元数据库:默认的hive的元数据库是derby,我们选择mysql
h2,sqllite,sybase
2.hive软件:需要各种配置
上述两个安装完后需要执行指令,初始化元数据库
区别:延迟性
维度内容
应用场景:数据库适用于业务应用(web应用,app),数据仓库适用于数据分析和数据处理
共同点:数据存储
基本上都可以使用sql来对数据进行操作
都有schema(模式,指的就是表结构)
--------------------------------------------------------------------getting start
create table pokes(foo int,bar string)
row format delimited
fields terminated by ' ';
load data local inpath '/usr/tmp/pokes.txt' overwrite into table pokes;
select * from pokes;
--------------------------------------------------------------------wordcount
数据文件上传到hdfs上:
hdfs dfs -put README.txt /hivewc_readme.txt
建表加载要被wordcount的文件
create table for_wcfile(line string);
把数据文件加载到表for_wcfile
load data inpath '/hivewc_readme.txt' overwrite into table for_wcfile;
使用sql对该数据文件进行wordcount计算
create table wc_result as
select word
,count(1) as w_count
from (
select explode(split(line,'\s+')) as word
from for_wcfile
)a
group by word
;
--------------------------------------------------------------------------------------------
mq:消息队列
activeMQ、rabbitMQ、rocketMQ
redis、kafka
JMS
JPA
--------------------------------------------------------------------------------------------
hive解析编译优化成逻辑计划的过程
select *
from tabela a
join tableb b
on a.cid=b.cid
*元数据库
DBS---数据库信息
TBLS---表信息
SDS---表的属性信息
COLUMNS_V2---表字段信息
---查看一个表中的字段信息
SELECT c.*
FROM TBLS a
INNER JOIN SDS b
ON a.sd_id=b.sd_id
INNER JOIN COLUMNS_V2 c
ON b.cd_id=c.cd_id
WHERE a.tbl_name='pokes'
*hiveserver2的启动依赖
1.hdfs start-dfs.sh
2.yarn start-yarn.sh
-----------------------------------------
3.historyserver(jobhistory) mr-jobhistory-daemon.sh start historyserver
*beeline连接hiveserver2
先通过beeline指令进入beeline的shell,然后通过下面指令连接
!connect jdbc:hive2://centos1:10000 root
~如果beeline的root用户没法访问的话,在hadoop的配置文件core-site.xml里添加配置
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
安装squrrile:
java -jar squirrel-sql-snapshot-20170531_2205-standard.jar
class not found
com.google.protobuf.ProtocoleMessageEnum
*hive-hql
1.数据类型
数值型:int
DECIMAL、DOUBLE
字符串:string
日期类型:date(毫秒),timestamp(纳秒)
2.数据定义语法:DDL (重要)
表的定义
表结构的修改
数据库对象:table、view、index、trigger(触发器)、procedure存储过程、function、constraint(约束)
table
Create/Drop/Alter/Use Database
Create/Drop/Truncate Table
Alter Table/Partition/Column
-----------------------------------------------------
Create/Drop/Reload Function
namespace:很多软件技术都会使用namespace(命名空间),它的主要作用是用来做 数据或程序 隔离的
做隔离的好处:1.权限控制,2.防止命名冲突
常见的namespace:package
数据库上的:database、schema
mq:频道channel
drop table:删除表
truncate table:清空表,只删除表中的数据,保留表的定义
delete from table:删除表数据
delete数据其实是行级别操作,可以回滚
truncate是表级别操作,不可回滚
create table的形式
1.create table table_name
(col1 type1,col2 type2,col3 type3)
row fromat delimited
LINES TERMINATED BY '\n'
FIELDS TERMINATED BY ' ';
2.create table pokers_clone like pokes
表克隆,只赋值表结构,不复制表数据
3.create table as select ...
create table pokers1 as
select * from pokes where foo>3
row format:数据行的格式定义
delimited:分割符
serder:序列化反序列化类
TEMPORARY:临时表修饰
temporary表创建出来只能被当前session访问
当session断开或消失的时候temporary表会被hive自动删除
限制:
不支持表分区
不支持创建索引
EXTERNAL:外部表修饰
外部表:允许用户创建的表的数据在hive的文件夹外部自由指定
如果删除外部表,源数据文件不会被删除,只是删除元数据
创建外表时一般通过在ddl后加
LOCATION '<hdfs_location>'的形式来指定该表所存放的文件夹位置
一般不使用load data的形式来加载数据
内部(managed)表:表所对应文件夹由hive自己维护
drop表时源数据文件和元数据同时都会被删除
load data:它的作用实质就是文件的剪切
一般情况下外来数据,或者原始数据都创建成外部表
在hive里面通过代码分析产生的数据一般都简称内部表
*hive表创建定义加载文件格式化的方式
1.delimited 指定分隔符,简单易用,但是限制比较多
2.serder 序列化反序列化,功能比较强,使用比较复杂 常用的有:正则serder
*hive表的分区和分桶
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
*hive的数据文件格式
STORED AS file_format
常用的文件格式
TEXTFILE 一般数据源会是文本格式
ORC hive里面最常用的一种文件格式
PARQUET impala里常用的一种文件格式
*hive查看表元数据信息
describe user_action_login --只有字段信息
describe extended user_action_login --详细信息
describe formatted user_action_login --格式化后的详细信息
*TBLPROPERTIES表的属性配置
比方说该表是否要压缩
该表是否支持事务等
*修改表
ALTER TABLE table_name RENAME TO new_table_name; --表重命名
ALTER TABLE table_name SET TBLPROPERTIES table_properties; --设置表的属性配置
ALTER TABLE table_name SET TBLPROPERTIES ('comment' = new_comment);
ALTER TABLE table_name CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name, ...)]
INTO num_buckets BUCKETS; --把原来不是分桶表的表,改成是分桶表的表
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location'][, PARTITION partition_spec [LOCATION 'location'], ...];
--修改表的分区操作
*hive创建函数
CREATE FUNCTION [db_name.]function_name AS class_name
[USING JAR|FILE|ARCHIVE 'file_uri' [, JAR|FILE|ARCHIVE 'file_uri'] ];
DROP FUNCTION [IF EXISTS] function_name;
3.数据操作语法:DML (重要)
DML: Load, Insert, Update, Delete
load:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
overwrite:覆盖并加载
local:添加local是path指向的是执行该语句的机器本地的文件目录
不加local时path指向的是hdfs的目录
insert:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;
insert into aaa (col1,col2,col3) values(value1,value2,value3)
-------------------------
create table user_new_tweet like user_action_m;
create table action_log_192_184_237_49 like user_action_m;
insert overwrite table user_new_tweet
select * from user_action_m
where action_type='new_tweet';
insert overwrite table action_log_192_184_237_49
select * from user_action_m
where ip='198.184.237.49';
优化的写法:
from user_action_m
insert overwrite table user_new_tweet select * where action_type='new_tweet'
insert overwrite table action_log_192_184_237_49 select * where ip='198.184.237.49'
-------------------------
使用insert把数据写出到hdfs的文件系统中
update、delete:
hive中只有支持事务管理(ACID)的表才能进行update和delete
如果想让一个表支持事务管理需要满足如下条件:
1.表的存储格式必须是ORC
2.表必须要进行分桶
3.表的属性上必须要配置:transactional=true
4.当前连接hiveserver的session必须要设置一些参数:
set hive.support.concurrency=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
Import/Export
应用场景:
dml是对数据进行表级别操作
Import/Export主要是用作对数据的备份和恢复
4.数据查询语法:DQL (最重要)
5.数据库控制语法:DCL (不重要)
mysql的数据备份和恢复指令
mysqldump -uroot -psa dbname>backupfile.sql
mysql -uroot -psa dbname<backupfile.sql
-----------------------------------------------------------------------
*select
select关键词的后面可以添加哪些内容
1.*
2.具体的一个或多个字段名称
3.函数
4.常量
5.字段和数据运算表达式
*hive配置指令
reset 把当前session的所有配置参数值重置为默认值
set 打印出当前session的所有参数(hive)的配置信息
set propertiesname 打印propertiesname的配置值
set propertiesname=propertiesvalue 把propertiesname设置成propertiesvalue
set -v 打印出当前session的所有(hive和hadoop)参数的配置信息
add、list、delete
file、jar
把file、jar作为资源文件加入到分布式缓存中
当hive的程序运行需要额外的资源文件(配置文件,参数文件时)就需要add file
当hive的程序运行需要第三方的一些jar包的时候,就需要add jar
add的jar和file只对当前的session起作用
*hive的排序
order by 是hive的全排序,它是通过指定只有1个reduce节点来实现全排序的,这个排序作用于所有数据
select *
from employee
order by salary nulls last,status_salary
sort by 是hive的单个reduce节点的排序而不是全局有序
distribute by 并不是对数据进行排序,而是指定数据从map节点到reduce节点分区的依据
一般情况下distribute by和sort by结合使用
cluster by 它是distribute by 和 sort by的结合
cluster by columnx === distribute by columnx sort by columnx
当distribute by和sort by后面的字段一致的时候可以cluster by来代替
cluster by的reduce单节点排序只能够升序
*分组聚合
聚合可以单独使用,如果聚合单独使用的话它会把设计的所有数据当做一个整体来进行聚合计算,相当于把所有数据当做一组来进行聚合
分组也可以单独使用,如果不结合聚合只做分组的话,它的作用就只有去重
分组和聚合在实际工作过程中经常是结合在一块来使用的
*表关联
内关联
inner join:两张表的数据会根据关联字段相互过滤,两张表的地位是对等的
外关联
left join:两张表分为主表和副表,结果集以主表数据为标准(主表的数据不会根据关联条件被过滤),副表的数据会被主表的数据过滤
left join左边的表是主表,右边的表是副表
right join
right join右边的表是主表,左边的表是副表
当使用left join或right join进行关联查询的时候如果需要添加对副表的限定条件,把这个限定条件添加到on后面而不能添加到where后面,否则这个限定条件会让left join或right join失效而变成inner join
full outer join
两张表会根据关联字段来关联,关联不上的会相互补充,两张表的地位是对等的
工作过程中会经常把
关联、分组聚合、子查询 组合在一块来使用
*hive的分区和分桶
分区和分桶都是减少当用户在根据某些条件(维度)过滤数据时所需要扫描的数据量
分区是通过把一个hive表根据某些条件(维度/虚拟字段)把数据划分到不同子文件夹下面
分桶是通过把一个hive表根据某些条件(字段)把数据划分到不同的子文件中
1.分区是把数据分割到不同的文件夹下
分桶是把数据分割到不同的桶文件中
2.某一个分区夹下的所有数据对应的分区条件(虚拟字段)值都是相同的
某一个分桶文件下数据的分桶条件(表字段)值是可以不同
3.分区的条件值是存放于分区文件目录的名称上面的(虚拟字段)
分桶的条件值是存储于数据的每一条记录里的(表字段)
在使用上选择分区还是分桶,首先确定好分区条件
然后看这个分区条件在某一个值下面的数据量的大小,如果数据量非常大选择分区,如果数据量很小就选择分桶
如果某个字段的每一个值所对应的数据量都很小,比如唯一标识只对应一条记录,如果对这种数据选择分区而不选择分桶的话
那么就会产生大量的小文件,会对hadoop的hdfs和mapreduce造成极大的效率影响。
在工作中,统一的维度字段例如:时间、行政区域。。。。等会作为分区的条件
比较明细的维度,如:各种数据的唯一标识(ID),人员姓名,等等类似的字段值会被作为分桶的条件
应用
1.创建分区分桶表
在create table和字段定义之后添加:
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
分区需要填写 分区名称和类型(虚拟字段)
分桶只需要填写 分桶字段名称(表字段)
create table ttt(...)
partitioned by(year string,month string,day string)
create table ttt(...)
partitioned by(date string)
load data到分区表中必须指定分区值,使用load data加载数据,hive并不会去判断数据是否真的满足分区条件值,而只做文件的剪切
load data local inpath '/usr/tmp/user-logs-large.txt' overwrite into table user_log_p_action partition(p_action='logout');
add partition
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location'][, PARTITION partition_spec [LOCATION 'location'], ...];
partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)
alter table user_log_p_action add if not exists partition(p_action='login');
drop partition
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec[, PARTITION partition_spec, ...]
[IGNORE PROTECTION] [PURGE];
alter table user_log_p_action drop if exists partition(p_action='logout');
动态分区导入:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table user_log_p_action partition(p_action)
select user_name
,action_type
,ip
,action_type as actiontype
from user_action_log
其中p_action是分区表的分区字段名称
,action_type as actiontype:必须要放在表正式字段的后面,按顺序这个位置往后是分区字段值,动态导入的过程就是根据分区字段值来分区的
工作中很有可能对原始数据的加载使用的是外表,外表也可以创建分区表
外部表一般情况下都是使用location的方式定位数据的位置
当有分区的外部表新导入某个分区的数据时,我们可以使用如下方式导入
alter table partition_table_name add partition(p_column=new_partition_value) location '/path/to/new/partition/data'
*functions
show functions
describe function 'functionname'
条件判断函数
nvl(字段,常量) 判断是否为空,为空就返回常量,否则返回字段本身
COALESCE(字段值1,字段值2,....,常量) 按照参数顺序返回第一个不为空的值
if(boolean testCondition, T valueTrue, T valueFalseOrNull)
1.判断表达式
2.判断成功的返回值
3.判断失败的返回值
string函数
length(string A) 求字符串的长度
lower(string A) lcase(string A) 字母转换成小写
upper(string A) ucase(string A) 字母转换成小写
replace(string A, string OLD, string NEW) 在a中找OLD,找到就把其替换成NEW
regexp_replace(string INITIAL_STRING, string PATTERN, string REPLACEMENT)
1.源字符串
2.正则表达式
3.匹配上后要替换的值
split(string str, string pat) 把str按照pat正则分割成多个字符串,然后以一个数组的结构返回
substr(string|binary A, int start)
substr(string|binary A, int start, int len)
instr(string str, string substr) 相当于java中indexOf 然后再加1
format_number(number x, int d) '#,###,###.##'的形式把数字转换成字符串,d代表小数点后的精确位数
concat(string|binary A, string|binary B...) 连接多个字符串
日期函数
unix_timestamp() 返回系统当前时间戳,返回类型是long类型
unix_timestamp(string date) 把字符串转换成long类型的时间戳, yyyy-MM-dd HH:mm:ss
from_unixtime(bigint unixtime[, string format]) 格式化日期
date_format(date/timestamp/string ts, string fmt) 格式化日期
date_add(date/timestamp/string startdate, tinyint/smallint/int days) 日期加减,单位是天
datediff(string enddate, string startdate) 用enddate减去startdate 返回相差天数
*weblog accesslog
web服务器:tomcat、apache、IIS、nginx、weblogic、jetty
CREATE TABLE apachelog (
host STRING,
identity STRING,
username STRING,
time STRING,
request STRING,
status STRING,
size STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\\[[^\\]]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\"[^\"]*\") ([^ \"]*|\"[^\"]*\"))?"
)
STORED AS TEXTFILE;
host STRING, 远程主机名,客户端的远程ip地址
identity STRING, 用户标识
user STRING, 用户id
time STRING, 访问时间
request STRING, request信息,请求方法、请求url、请求的协议
status STRING, 响应状态
size STRING, 响应的字节数byte
referer STRING, 跳入关联地址
agent STRING 代理客户端信息
-- 每个ip的访问网站的次数,请求的流量大小
-- 统计当日网站的pv uv
-- 统计每个时段的pv和uv数量
*自定义函数UDF的方法步骤
1.创建项目,引入依赖
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.0</version>
</dependency>
2.自定义类型继承自UDF类
3.在自定义的UDF子类里面实现一个或多个evaluate方法
每个evaluate的定义样式都可以直接在hivesql中调用,调用的传参和返回值和evaluate的方法是一致的
evaluate的返回值不能是void,必须指定非void的返回值类型,当某些计算确实没返回值时可以返回null
evaluate的返回值类型可以是java的基础类型,也可以是Writable类型
evaluate可以根据需求决定所接收的参数类型和个数
UDF--- 普通的用户自定义函数,一般适用于,一行对一行的需求
UDAF--- aggregate 多行输入对应一行输出 sum,count,avg,max,min等
UDTF--- 一行输入对应多行输出 如:explode
4.把该项目打成jar包,然后把jar包上传到hdfs上
5.在hive的session中引入jar包:
add jar /path/of/jar/on/hdfs
add jar /usr/tmp/hiveudf20.jar
add jar hdfs://centos1:9000/hiveudf20.jar
6.使用ddl创建自定义函数名,用as指向我们定义的类型
create function function_name as 'name.of.my.udfsclass'
create function str_to_date as 'com.zhiyou.bd20.hiveudf.TimeFormatUDF'
7.在我们的hivesql中就可以使用function_name来做为函数了
select str_to_date(time)
from default.apachelog
*hive程序:hql脚本
把一系列的hive sql,按照顺序组装在一个脚本文件里面,就是一个hql脚本
hql脚本可以使用hive指令直接执行
hql脚本必须要支持重跑(重新运行),并且重新运行后的数据要保证无重复,无缺失
hive的hql脚本是可以接收参数的,给hive脚本发送参数的方式是,在hive指令后面,通过
--hiveconf varname=varvalue
或者
--hivevar varname=varvalue
例如
hive -f /path/to/script.hql --hivevar filename=access_2016_04_30
上述指令就是在执行script.hql时,给脚本传一个参数,参数名称是:filename,参数值是:access_2016_04_30
在script.hql脚本里面,就可以使用${filename}的形式来接收这个参数
load data local inpath '/usr/tmp/${filename}.log' overwrite into table apachelog;
=
load data local inpath '/usr/tmp/access_2016_04_30.log' overwrite into table apachelog;
接收参数可以使用${filename},直接用hivevar的名称接收,可以使用:
${hivevar:filename}
${hiveconf:paramname} 来接收指令上的参数
--hiveconf 后面一般跟hive的客户端配置参数,如
--hiveconf hive.exec.scratchdir=/home/my/hive_scratch
--hivevar 后面一般跟hive的脚本中所需要使用的动态参数。
如果要穿多个参数就需要写多个--hivevar,例如要传递两个参数:filename和nowdate
hive -f /path/to/script.hql \
--hivevar filename=pathtofile
--hivevar nowdate=datevalue
如果开发的数据处理过程非常复杂,需要在sql层面进行一些判断、循环,或者系统资源调用等操作的时候,hql脚本就显得比较弱了,这时可以使用 shell+hql 或者 使用python+hql的形式来做hive开发
,还可以使用pl/hql,pl/sql
*topN
-- 取出访问请求数最高的ip地址 top5
如果数据量比较大就不适用 order by + limit的写法
可以使用sort by + limit的写法来求topn的需求如:
select a.*
from (select host
,count(1) times
from apachelog
group by host
) a
sort by times desc
limit 5
-- 取出每个部门销量月份的top3
-- 普通的sql的写法
select *
from (
select a.dep_name
,a.date_month
,a.sale_mount
,sum(case when b.sale_mount>a.sale_mount then 1 else 0 end)+1 rank_num
from dep_sales a
inner join dep_sales b
on a.dep_name=b.dep_name
group by a.dep_name
,a.date_month
,a.sale_mount
)a
where a.rank_num<=3
-- hive的窗口计算函数
窗口函数的语法是:
函数调用 over(partition by columnname order by columnname rows between xxx and xxx)
rank() over(partition by dep_name order by sale_mount)
窗口函数的over 表达式
1.partition by
窗口的初步确定,例如partition by a.dep_name,就是把dep_sales中的数据按照a.dep_name的值来划分计算窗口
2.order by
窗口内计算数据的顺序,例如order by a.sale_mount desc,就是指按照dep_name划分的窗口内部的数据根据a.sale_mount来进行降序排序,最大的第一个参与窗口计算,依次类推
3.rows between
rows between是调节真正参与计算时窗口的大小的
如果没有rows between,窗口的大小完全由partition by来决定
如果有rows between,rows between可以在partition by划分的大窗口内来更进一步细分计算窗口
Rank, NTile, DenseRank, CumeDist, PercentRank等函数不支持rows between来细分窗口的
COUNT、SUM、MIN、MAX、AVG支持rows between来细分窗口
rows between后面的写法:
UNBOUNDED PRECEDING 从大窗口开始的第一条记录开始
UNBOUNDED FOLLOWING 一直到大窗口的最后一条记录结束
CURRENT ROW 当前行
n PRECEDING 当前行往前数n行做为小窗口的开始
n FOLLOWING 从当前行往后数n行做为小窗口的结束
每个部门在该部门内部往前近三个月内的销量排名
rows between 2 PRECEDING and CURRENT ROW
*hive的虚拟字段
hive中分区表的分区字段就是一种虚拟字段,虚拟字段和真实的字段数据存放的位置不一样,但是它可以像正式的字段一样在sql里面被使用
除了分区虚拟字段外hive本身有两个虚拟字段:
INPUT__FILE__NAME :某行数据所对应的文件名称
BLOCK__OFFSET__INSIDE__FILE :某行数据在对应文件里面的偏移量
*grouping sets
grouping sets的语法是添加在group by后面
一般group by后面的内容是全维度,然后再grouping sets里面就可以添加多组降维的维度组合
group by a,b
grouping sets((a,b),(a),(b),())
输出结果里面被降维的维度值将会是null
当进行降维统计处理时,明细数据的维度值可能是null,这种情况下就会和降维数据的数据结果发生值上的维度重复,例如
有个部门的部门名称就是null
那么这个部门的各个月的销量会是:
null 1 xx
null 2 xx
null 3 xx
...
按照grouping sets的规则,根据部门降维后的数据将会是:
null 1 xxx
null 2 xxx
null 3 xxx
这种情况下可以使用一个额外的字段来表示是否分组:Grouping__ID
GROUP BY a, b, c WITH CUBE is equivalent to
GROUP BY a, b, c GROUPING SETS ( (a, b, c), (a, b), (b, c), (a, c), (a), (b), (c), ( )).
ROLLUP clause is used with GROUP BY to compute the aggregate at the hierarchy levels of a dimension.
GROUP BY a, b, c with ROLLUP assumes that the hierarchy is "a" drilling down to "b" drilling down to "c".
GROUP BY a, b, c, WITH ROLLUP is equivalent to GROUP BY a, b, c GROUPING SETS ( (a, b, c), (a, b), (a), ( )).
*查看sql的执行计划
EXPLAIN [EXTENDED|DEPENDENCY|AUTHORIZATION] query
*lock hive锁
当多个客户端,对表进行,插入,修改,改变表结构等操作时,会出现锁表情况
查看锁表语句:
SHOW LOCKS <TABLE_NAME>;
SHOW LOCKS <TABLE_NAME> EXTENDED;
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>);
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>) EXTENDED;
*join优化
set hive.auto.convert.join=true;
代表当hive能识别被关联的两张表一个是大表一个是小表的时候,会自动启动map端join的mr机制
set hive.auto.convert.join.noconditionaltask = true;
set hive.auto.convert.join.noconditionaltask.size = 10000000;
hive.mapjoin.check.memory.rows=100000
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
hive解决数据倾斜
set hive.groupby.skewindata=true
hive会自动识别数据倾斜的key,然后启动过两个mr,第一个mr要把倾斜key打散,第二个mr会把打散的key再进行一次聚合得到最终结果
hive.skewjoin.key=100000
hive.skewjoin.mapjoin.map.tasks=10000
hive.skewjoin.mapjoin.min.split=33554432
*工作过程中开发人员在hive中生成的表
一般情况下使用:orc parquet格式
如果要压缩的话:
orc对应的压缩格式一般采用lzo
parquet对应的压缩格式是snappy