Hive - DDL & DML

HiveSQL DDL

  HiveSQL中的DDL语言是对Hive表数据结构的操作,比如创建、修改、删除一张表。
  Hive是构建在HDFS之上的,Hive的数据存放于HDFS之中,HDFS存储的是文件,怎么对应结构化数据,这就要求Hive必须要有存放元数据信息的Meta表,这个可以存放在RDBMS中。

Hive与RDBMS中存储结构的对比

  Hive中的存储结构其实就是DHFS的存储格式

RDBMS Hive
数据库database HDFS上顶层文件夹
表table 对应Database所指向的目录
分区Partition table文件夹下
块bucket 对应以及具体的文件

Hive数据库Database

  Hive数据库就是HDFS上顶层的文件夹。

所有的操作都在hive CLI中进行
1、创建一个数据库叫hive001
  create database hive001;
2、查看数据库
  show databases;
3、详细显示数据库描述
  desc database hive001; 
4、显示HDFS上用户信息
  desc database extended hive001;

  通过上面的show显示,会发现确实有hive001,但是也有个default,这个default是hive创建完就有的。
  那hive001这个数据库到底在HDFS上哪里?!在HDFS上有一个叫做 /user/hive/warehouse/hive001.db 目录,这个是目录,虽然.db结尾。所以Hive上手工创建数据库的数据库存放在HDFS上的 /user/hive/warehouse/ < databasename >.db上。但是这个数据库没有default数据库。Hive的default数据库存放路径其实就是/user/hive/warehouse,这个数据库比较特殊。

具体创建语法
  CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
  [COMMENT database_comment]
  [LOCATION hdfs_path]
  [WITH DBPROPERTIES (property_name=property_value, ...)];
删除一个数据库
  DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];

Hive数据表table

  Hive数据表是建立在数据库基础上的,所以对应的存放也是在HDFS目录之下。

选择一个数据库
  use hive001;
创建一个数据表
  create table test(id int);
从别的表复制一份表结构
  CREATE table test1 like test;
查看一张表明细
  desc formatted test;
查看表的创建语句
  show create table test;

  Hive创建完数据表后,我们查看下HDFS,发现确实在对应hive001数据库所在的HDFS目录下有一个test目录(/user/hive/warehouse/hive001.db/test)。

相对完整创建表:
  CREATE TABLE person
  (id int comment 'this is id', name string comment 'this id name' )
  comment 'this is person'
  ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\t' ;
如果要完整的创建语法,则需要看官网

  Hive中创建一张表,创建表默认使用的是MANAGED_TABLE:内部表。内部表的在drop的时候会删除HDFS上的文件和Meta上的结构也会删除。而外部表只删除meta上的信息,HDFS上的数据还是保留。

外部表定义
create EXTERNAL table test_external 
(empno int, ename string, job string, mgr int, hiredate string, salary double, comm double, deptno int)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t';    

Hive数据表table 常用的数据类型

常用的数据类型 Hive
数值 int bigint float double
字符串 String
时间 date timestamp

  Hive基本上使用的只要使用数值的和字符串,因为毕竟存储到文件,一旦转化成时间出错,那个记录就被丢掉,所以直接存String就好了。

Hive数据表DML语言 - 导入数据

  Hive的DML语言是对数据的操作,当然从本地导入数据也是DML语言之一。

1、从本地导入数据到Hive仓库,当然行和列的分割方式要符合Hive制表的时候的方式
LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' OVERWRITE INTO TABLE person; 
2、或者从Hive上的别的表载入数据
INSERT OVERWRITE TABLE person1
select * FROM person;

Hive数据表DML语言 - Select

  Hive的的DML的Select语法和SQL中的Select的写法相似,但普通的Select并不会触发底层MapReduce作业,但是如果Select使用聚合函数(sum、count、max、min、avg等)这个时候会触发底层的MapReduce。那还有哪些会触发呢,聚合函数(sum、count、max、min、avg)、分组(group by 、having)、关联(Join)。
  Hive中有一个case when then语法(不会触发MR操作)。

select ename,salary,
case 
when salary>1 and salary<=1000 then 'lower'
when salary>1000 and salary<=2000 then 'middle'
when salary>2000 and salary<=4000 then 'high'
else 'highest'
end
from ruozedata_emp;

Hive数据表分区表

  分区表存在的意义就是分数据段查询时较少IO压力。比如,你的日志数据每天放在一个分区内,如果你要查什么数据,只需要指定分区查找就可以了,没有必要全表查找。Hive分区表分为:静态分区,动态分区。

扫描二维码关注公众号,回复: 1764815 查看本文章

静态分区

  在定义表的时候定义分区字段。比如:

按照订单的月份进行分区
  create table order_partition(
  ordernumber string,
  eventtime string
  )
  partitioned by (event_month string)
  row format delimited fields terminated by '\t';
查看分区
  show partitions order_partition;

  好了表创建好了,下面需要导入数据,load的语法

把数据导入到哪个分区
  LOAD DATA LOCAL INPATH '/home/hadoop/data/order.txt' 
  OVERWRITE INTO TABLE order_partition 
  PARTITION(event_month='2014-05'); 
或者
  insert overwrite table order_partition 
  partition(event_month='2014-08')
  select * from order_4_partition;

  这个时候会出错,出错后去 /tmp/$(username)/hive.log中查看下原因,发现还是和原来初始化部署hive一样的问题。

进入mysql,找到对应数据库,然后修改字符集
alter table PARTITIONS convert to character set latin1;
alter table PARTITION_KEYS convert to character set latin1;

  这里有一个很有趣的问题,如果Hive上的数据库数据都是在HDFS上,如果不用Load也可以直接将数据文件直接放到对应HDFS文件夹下,在查询表时也能查出新增的数据。但是但是但是,如果按照HDFS中Hive分区的目录规则创建一个新的分区目录,插入数据,可是Hive中查询不到新的数据,因为这些数据Hive是不认的。因为MySQl中mate没有注册过这个分区。

想要解决HDFS上添加分区在Hive中不认的问题,只需要:
   MSCK REPAIR TABLE order_partition 
或者
   ALTER TABLE order_partition ADD IF NOT EXISTS PARTITION (event_month='2014-07') ;
就会刷新进Hive Meta。
但是第一种方式太暴力了,他会将所有信息会写到Meta表,性能上消耗太多。推荐使用第二种。

动态分区

  动态分区与静态分区的区别:创建静态表插入数据的时候必须要指明分区,这就麻烦了,麻烦在于要是该字段有1000多种值,那就麻烦了。动态分区就不需要指定值。

动态分区创建数据表语法和静态的一模一样
  create table ruozedata_dynamic_emp 
  (empno int, ename string, job string, mgr int, hiredate string,   salary double, comm double)
  PARTITIONED by(deptno string)
  ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\t' ;

区别在于插入数据的时候
动态分区明确要求:分区字段写在select的最后面   
  insert into table ruozedata_dynamic_emp partition(deptno)
  select empno,ename,job,mgr,hiredate,salary,comm,deptno from   ruozedata_emp ;
这种方式是非严格动态分区写法,一般Hive是严格模式,可以关闭,否者上诉的插入会报错
  set hive.exec.dynamic.partition.mode=nonstrict;

扩展

Hive CLI的参数设置

  Hive在CLI命令行的参数设置采用严格的key=value格式

设置只能当前窗口有效,除非写入到hive-site.sh中
set key=value; 设置    
set key;       取值

猜你喜欢

转载自blog.csdn.net/myt0929/article/details/80634650