那么今天给大家带来的是有关hive shell的笔记总结,赶紧来看看提升自己吧。

一、关于数据库

1、因为我们在操作hive时,一般情况下是在cli窗口中,所以写sql脚本时,最好用一个记事本,写好之后放进去。

2、启动:需要先启动hdfs,如果有需要用到mr的查询时,必须启动yarn

3、DDL数据定义语言,主要是用于创建、删除、修改等数据库级别、表级别、索引等等

4、创建数据库

CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name

[COMMENT database_comment]

[LOCATION hdfs_path]

[WITH DBPROPERTIES (property_name=property_value, ...)];

CREATE:关键字

():必须

|:或者

[]:可选

IF NOT EXISTS:如果不存在,不加这个表示,如果存在就不能创建。

database_name:数据库名称,自己随便写

COMMENT:注释

LOCATION:修改存储位置

最简单的创建数据库方法:

CREATE DATABASE mydb02;

创建之前判断是否存在:

CREATE DATABASE IF NOT EXISTS mydb02;

创建数据库的同时,给数据库写点备注:

CREATE DATABASE IF NOT EXISTS mydb04 COMMENT 'my test mydb04'

注意:mysql里暂时不支持中文----自己先解决一下mysql的中文问题

创建数据库,将数据不放在默认的位置上:

CREATE DATABASE mydb05 LOCATION '/kda0601hive'

我们自己创建数据库之后,默认存储在什么位置?

如果需要修改,默认存储位置,将在hive-site.xml文件中,加入以上节点

/hive/${name}

注意事项

创建数据库之后,hive会给我们在指定的路径下生成一个:数据库.db的目录

创建hive时,会有一个默认的default数据库,存放的东西(表、分区等等),全部放在默认路径下的。

删除数据库的注意事项:

查看所有的数据库

show databases;

删除数据库

drop database mydb05;

切换数据库

use mydb04;

默认删除数据库时,只能删除空的数据库;

级联删除数据库

drop database mydb04 cascade;

二、表的基本使用

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name

[(col_name data_type [COMMENT col_comment], ... [constraint_specification])]

[COMMENT table_comment]

[LOCATION hdfs_path]

1、创建最简单的表CREATE TABLE tab01(age int);

2、创建时,给字段设置备注:CREATE TABLE tab02(name string COMMENT 'myname',age int comment 'myage') COMMENT 'mytable02';

3、创建复杂类型的表

CREATE TABLE tab03(name string,age int,iphone ARRAY

4、将其它两个复杂类型都一同创建

CREATE TABLE tab04(name string,age int,iphone ARRAY

5、创建一张外部表

CREATE EXTERNAL TABLE tab05(age int) LOCATION "/kda0601/tab05";

6、如果查看某些表是外部表还是内部表

desc formatted 表名

Table Type: EXTERNAL_TABLE --外部表

Table Type: MANAGED_TABLE --内部表、管理表、托管表

7、临时表

CREATE TEMPORARY TABLE tab06(age int)

quit;--退出

TEMPORARY:临时表 只能在当前线程中有效 用于中转站

EXTERNAL:外部表

三、加载数据与创建带有分隔符的表

1、如果需要向表中插入数据,采用insert的方式,来源一般是来自于另一张表中的数据。

但是我们现在做事情是,为一张新表插入数据。直接使用insert的方式不行!

2、在hive中采用的是加载的方式:通过文件的方式加载到表中

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

[LOCAL]:如果加上表示从本地上拿数据,如果不加表示从HDFS上拿数据

[OVERWRITE]:如果是以追加还是覆盖的方式进入到数据中

为tab01插入数据

需要准备一份数据,要么在Linux的本地或者是hdfs上。

在/keduox/hive_data目录下创建了一个tab01文件,内容为一行一个值

2.1将本地的一个文件内容加载到hive表中

load data local inpath '/keduox/hive_data/tab01' into table tab01;

如果表中的数据格式与要求的格式不一致时?

可以成功加载!但是类型不匹配时,会以NULL来表示

2.2加载的数据以覆盖的方式进行?

load data local inpath '/keduox/hive_data/tab01' OVERWRITE into table tab01;

2.3那如何为集合类型插入值?如果来判定字段的分隔?

name age iphone

试验以空格分隔字段是失败的!

试验以table来分隔

load data local inpath '/keduox/hive_data/tab03' OVERWRITE into table tab03;

3、创建的时候指定分隔符

3.1:行、字段、集合

ROW FORMAT row_format

row_format

: DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]

[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

[NULL DEFINED AS char] -- (Note: Available in Hive 0.13 and later)

| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

#创建带有字段分隔符的表-分隔符为制表符

CREATE TABLE tab06(name string ,age int ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '';

load data local inpath '/keduox/hive_data/tab06' into table tab06;

问题:如果加载的文件中,文件的字段多于表的字段时,会出现什么情况?

load data local inpath '/keduox/hive_data/tab03' into table tab06;

多出的部分会自动截取掉

指定字段分隔符时,指定行分隔符

CREATE TABLE tab07(name string ,age int ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '' LINES TERMINATED BY '';

为集合指定分隔符:COLLECTION和MAP

COLLECTION所管理:数组中各个元素的分隔、map元素的分隔、struct的元素分隔

MAP所管理的是:key与value的分隔

CREATE TABLE tab08(name string,age int,iphone ARRAY

取集合中的值:

数组中的:字段名[下标值]

map:字段名['key']

struct:字段名.属性名

四、分区

1、分区---hive默认情况下查询表的内容时,是以查询全表的内容进行过滤。效率比较低。所以采用分区这个设计。分区的好处是提高了查询效率。

创建分区:创建表时,需要指定哪些字段作为分区字段

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name -- (Note: TEMPORARY available in Hive 0.14.0 and later)

[(col_name data_type [COMMENT col_comment], ... [constraint_specification])]

[COMMENT table_comment]

[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

分区字段,不需要在创建表的字段中

CREATE table tab11(name string)PARTITIONED BY (age string);

加载

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

我们按照普通的加载方法,向分区表中插入数据会出现错误:

静态分区加载数据

load data local inpath '/keduox/hive_data/tab06' into table tab11 PARTITION(age=18);

在hdfs中存储的结构与普通表有所不同

分区表分在表目录下,创建以分区字段=值的方式存在

load data local inpath '/keduox/hive_data/tab06' into table tab11 PARTITION(age=19);

当分区字段有多个时,如何处理

CREATE table tab12(name string)PARTITIONED BY (sex int,age string);

问题1:当有多个分区时,在加载数据时,能否只给定一个分区的值会报错:

load data local inpath '/keduox/hive_data/tab06' into table tab12 PARTITION(sex=1,age=18);

问题2:分区字段的顺序是否可以换,可以,在执行时,会自动切换

load data local inpath '/keduox/hive_data/tab06' into table tab12 PARTITION(age=18,sex=1);

问题3:在hdfs中是如何存储的?

在创建表时,放在前面的分区字段,作为主分区字段,后面的是以子目录的形式存在

load data local inpath '/keduox/hive_data/tab06' into table tab12 PARTITION(age=18,sex=2);

在设计表时候,查询字段使用频率高应该放在前面还是后面?前面

在查询的时候,一般会将分区的字段放在where条件里面。

如果我需要加载的文件内容中,包含了分区字段,那该如何处理?

hive当中的动态分区

1:准备一批数据(包含了需要分区的值)

age作为分区

zs 18

zs1 19

zs2 20

2:加载表中的时候,需要将不同的年龄,放在不同的文件夹中。

修改分区-值的增加

alter table table11 add PARTITION(age=20)

删除某个值的分区

alter table table11 drop PARTITION(age=20)

五、分桶

1、分桶。在hive中是比分区更细粒度的数据分类

2、创建:

[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]

#创建一个带有6个桶的表

CREATE table tab13(name string,age int) CLUSTERED BY (age) SORTED BY(age ASC) INTO 6 BUCKETS;

分桶字段是否可以采用分区字段?——不可以

但是可以采用不同的字段作为分桶

CREATE table tab15(name string,age int)PARTITIONED BY (sex int ) CLUSTERED BY (sex) SORTED BY(age ASC) INTO 6 BUCKETS;

3、加载数据以普通方式一样。

可以在cli中显示当前使用的数据库名:

set hive.cli.print.current.db=true

hive.cli.print.header=true //显示字段的头信息

注意,只是对当前会话有效

如果需要长期有效在,hive-site.xml文件中加入

修改表字段

ALTER TABLE table_name [PARTITION partition_spec] CHANGE [COLUMN] col_old_name col_new_name column_type

[COMMENT col_comment] [FIRST|AFTER column_name] [CASCADE|RESTRICT];

#前字段名改变另一个字段名

ALTER TABLE tab02 CHANGE age age1 int;

#修改字段名的位置

注意:修改了表的位置,但是数据不会进行改变位置,

ALTER TABLE tab03 CHANGE age age string FIRST;