cindysz110 / blog

8 stars 1 forks source link

[Hadoop] Hive 基本语法 #16

Open cindygl opened 6 years ago

cindygl commented 6 years ago

官网:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL

1. 数据库操作

1.1 创建数据库

语法: CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_name=property_value, ...)];

# 查看所有数据库
hive> show databases;
OK
default
Time taken: 0.011 seconds, Fetched: 1 row(s)
hive> 

# 其中,default是hive中默认的一个数据库,其数据文件路径为/user/hive/warehouse/
hive> !hdfs dfs -ls /user/hive;
Found 1 items
drwxr-xr-x   - hadoop supergroup          0 2018-06-04 15:25 /user/hive/warehouse
hive>

# 查看当前正在用哪个数据库
hive> select current_database();

# 创建数据库
hive> create database hive;     
OK
Time taken: 0.099 seconds
hive> 
# 这条命令会在hive的默认数据文件目录/user/hive/warehouse/下新建一个叫db_name.db的文件夹
hive> !hdfs dfs -ls /user/hive/warehouse/;
Found  items
drwxr-xr-x   - hadoop supergroup          0 2018-06-04 13:38 /user/hive/warehouse/hive.db
hive> 

1.2 删除数据库

语法: DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];

hive> drop database hive;
OK
Time taken: 0.05 seconds
hive> 
# 同时,这条命令会把/user/hive/warehouse/目录下的db_name.db文件夹删除
hive> !hdfs dfs -ls /user/hive/warehouse/;
注意:当数据库里没有任何表的时drop db_name才可以执行成功。

1.3 修改数据库

语法:ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path;

1.4 进入数据库

语法:USE database_name;

hive> use hive;
OK
Time taken: 0.013 seconds
hive> use default;
OK
Time taken: 0.018 seconds
hive> 

1.5 查看数据库描述

语法:DESC database_name;

hive> desc database hive;
OK
hive        hdfs://10.0.0.7:9000/user/hive/warehouse/hive.db    hadoop  USER    
Time taken: 0.013 seconds, Fetched: 1 row(s)
hive> 

# 更详细的信息
hive> desc database extended hive;
OK
hive        hdfs://10.0.0.7:9000/user/hive/warehouse/hive.db    hadoop  USER
Time taken: 0.014 seconds, Fetched: 1 row(s)
hive>

2. 表操作

Hive 创建表默认使用的是MANAGED_TABLE,也就是内部表。外部表在创建时,要指定EXTERNAL TABLE。 内部表使用场景:管理表的生命周期、生成临时表。

Hive 默认的分隔符:   行分隔符: \n   列分隔符: \001 ^A

2.1 创建表

*********************************************内部表*********************************************
hive> create table emp
    > (empno int, name string, job string, mgr int, hiredate string, salary double, comm double, depno int)
    > row format delimited
    > fields terminated by '\t';
OK
Time taken: 0.094 seconds
hive>

# 基于现有的表结构和数据内容创建新表,新表结构和内容与现有表一模一样(有mr过程)
hive> create table emp2 as select * from emp;

# 基于现有表创建新表,只创建表结构,不拷贝数据
hive> create table emp3 like emp;

*********************************************外部表*********************************************
hive> create external table emp_external
    > (empno int, name string, job string, mgr int, hiredate string, salary double, comm double, depno int)
    > row format delimited
    > fields terminated by '\t'
    > location '/user/hive/external/emp';
OK
Time taken: 0.071 seconds
hive>
hive> !hdfs dfs -ls /user/hive/external;
Found 1 items
drwxr-xr-x   - hadoop supergroup          0 2018-06-07 23:24 /user/hive/external/emp
hive>

2.2 向表中导入数据(txt文件导入)

*********************************************内部表*********************************************
# 从本地文件系统加载数据到hive表
hive> load data local inpath '/home/hadoop/data/emp.txt' overwrite into table emp;
Loading data to table hive.emp
Table hive.emp stats: [numFiles=1, numRows=0, totalSize=700, rawDataSize=0]
OK
Time taken: 0.824 seconds
hive> select * from emp;
OK
7369    SMITH   CLERK   7902    1980-12-17  800.0   NULL    20
7499    ALLEN   SALESMAN    7698    1981-2-20   1600.0  300.0   30
7521    WARD    SALESMAN    7698    1981-2-22   1250.0  500.0   30
7566    JONES   MANAGER 7839    1981-4-2    2975.0  NULL    20
7654    MARTIN  SALESMAN    7698    1981-9-28   1250.0  1400.0  30
7698    BLAKE   MANAGER 7839    1981-5-1    2850.0  NULL    30
7782    CLARK   MANAGER 7839    1981-6-9    2450.0  NULL    10
7788    SCOTT   ANALYST 7566    1987-4-19   3000.0  NULL    20
7839    KING    PRESIDENT   NULL    1981-11-17  5000.0  NULL    10
7844    TURNER  SALESMAN    7698    1981-9-8    1500.0  0.0 30
7876    ADAMS   CLERK   7788    1987-5-23   1100.0  NULL    20
7900    JAMES   CLERK   7698    1981-12-3   950.0   NULL    30
7902    FORD    ANALYST 7566    1981-12-3   3000.0  NULL    20
7934    MILLER  CLERK   7782    1982-1-23   1300.0  NULL    10
8888    HIVE    PROGRAM 7839    1988-1-23   10300.0 NULL    NULL
Time taken: 0.083 seconds, Fetched: 15 row(s)
hive>

# 从HDFS文件系统加载数据到hive表
hive> !hdfs dfs -put /home/hadoop/data/emp.txt /tmp/;
hive> load data inpath '/tmp/emp.txt' overwrite into table emp;
Loading data to table hive.emp
Table hive.emp stats: [numFiles=1, numRows=0, totalSize=700, rawDataSize=0]
OK
Time taken: 0.32 seconds
hive> select * from emp;
OK
7369    SMITH   CLERK   7902    1980-12-17  800.0   NULL    20
7499    ALLEN   SALESMAN    7698    1981-2-20   1600.0  300.0   30
7521    WARD    SALESMAN    7698    1981-2-22   1250.0  500.0   30
7566    JONES   MANAGER 7839    1981-4-2    2975.0  NULL    20
7654    MARTIN  SALESMAN    7698    1981-9-28   1250.0  1400.0  30
7698    BLAKE   MANAGER 7839    1981-5-1    2850.0  NULL    30
7782    CLARK   MANAGER 7839    1981-6-9    2450.0  NULL    10
7788    SCOTT   ANALYST 7566    1987-4-19   3000.0  NULL    20
7839    KING    PRESIDENT   NULL    1981-11-17  5000.0  NULL    10
7844    TURNER  SALESMAN    7698    1981-9-8    1500.0  0.0 30
7876    ADAMS   CLERK   7788    1987-5-23   1100.0  NULL    20
7900    JAMES   CLERK   7698    1981-12-3   950.0   NULL    30
7902    FORD    ANALYST 7566    1981-12-3   3000.0  NULL    20
7934    MILLER  CLERK   7782    1982-1-23   1300.0  NULL    10
8888    HIVE    PROGRAM 7839    1988-1-23   10300.0 NULL    NULL
Time taken: 0.094 seconds, Fetched: 15 row(s)
hive>

local:从本地文件系统加载数据到hive表
非local:从HDFS文件系统加载数据到hive表
两种方式语法上的差别:一个local,一个不带local;一个是本地路径,一个是hdfs文件路径。

overwrite:加载数据到表的时候数据的处理方式:覆盖
非overwrite:加载数据到表的时候数据的处理方式:追加
对非分区表来说,overwrite是指全覆盖;如果是指定分区,是覆盖指定分区的数据。

# 查询现有表数据,插入其他表(有mr过程)
hive> insert overwrite table emp4 select * from emp;    # 前提是表emp4已经存在
hive> insert into table emp4 select empno,job,ename,mgr, hiredate, salary, comm, deptno from emp;
虽然hive支持这样的操作,但是在生产中99%的场景都是load数据,一般不这样insert。

********************************************外部表*********************************************
# 直接将数据文件放到外部表指定的hdfs_path,完成数据加载。可以先有hdfs上指定路径的文件,然后再创建外部表
hive> !hdfs dfs -put /home/hadoop/data/emp.txt /user/hive/external/emp;
hive> !hdfs dfs -ls /user/hive/external/emp/emp.txt;
-rw-r--r--   1 hadoop supergroup        700 2018-06-07 23:28 /user/hive/external/emp/emp.txt
hive> select * from emp_external;
OK
7369    SMITH   CLERK   7902    1980-12-17  800.0   NULL    20
7499    ALLEN   SALESMAN    7698    1981-2-20   1600.0  300.0   30
7521    WARD    SALESMAN    7698    1981-2-22   1250.0  500.0   30
7566    JONES   MANAGER 7839    1981-4-2    2975.0  NULL    20
7654    MARTIN  SALESMAN    7698    1981-9-28   1250.0  1400.0  30
7698    BLAKE   MANAGER 7839    1981-5-1    2850.0  NULL    30
7782    CLARK   MANAGER 7839    1981-6-9    2450.0  NULL    10
7788    SCOTT   ANALYST 7566    1987-4-19   3000.0  NULL    20
7839    KING    PRESIDENT   NULL    1981-11-17  5000.0  NULL    10
7844    TURNER  SALESMAN    7698    1981-9-8    1500.0  0.0 30
7876    ADAMS   CLERK   7788    1987-5-23   1100.0  NULL    20
7900    JAMES   CLERK   7698    1981-12-3   950.0   NULL    30
7902    FORD    ANALYST 7566    1981-12-3   3000.0  NULL    20
7934    MILLER  CLERK   7782    1982-1-23   1300.0  NULL    10
8888    HIVE    PROGRAM 7839    1988-1-23   10300.0 NULL    NULL
Time taken: 0.083 seconds, Fetched: 15 row(s)
hive>

2.3 删除表

语法:DROP TABLE [IF EXISTS] table_name [PURGE];

内部表在删除时,hdfs+meta同时被删除。 外部表在删除时,只有meta被删除,hdfs数据保留。

hive> DROP TABLE IF EXISTS emp;

2.4 修改表

语法: 表重命名: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);

# 表重命名
hive> alter table emp3 rename to emp3_new;

2.5 查看表描述信息

语法:DESC table_name;

hive> desc emp;
OK
empno                   int
name                    string
job                     string
mgr                     int
hiredate                string
salary                  double
comm                    double
depno                   int
Time taken: 0.086 seconds, Fetched: 8 row(s)
hive>

# 更详细
hive> desc formatted emp;
OK
# col_name              data_type               comment

empno                   int
name                    string
job                     string
mgr                     int
hiredate                string
salary                  double
comm                    double
depno                   int

# Detailed Table Information
Database:               hive
Owner:                  hadoop
CreateTime:             Thu Jun 07 22:40:02 CST 2018
LastAccessTime:         UNKNOWN
Protect Mode:           None
Retention:              0
Location:               hdfs://10.0.0.7:9000/user/hive/warehouse/hive.db/emp
Table Type:             MANAGED_TABLE
Table Parameters:
    transient_lastDdlTime   1528382402

# Storage Information
SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat:            org.apache.hadoop.mapred.TextInputFormat
OutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed:             No
Num Buckets:            -1
Bucket Columns:         []
Sort Columns:           []
Storage Desc Params:
    field.delim             \t
    serialization.format    \t
Time taken: 0.084 seconds, Fetched: 34 row(s)
hive>

2.6 清空表

只有内部表才有这个操作,外部表没有。 语法:TRUNCATE TABLE table_name [PARTITION partition_spec];

注意清空表时,内部表无论数据是本地加载的还是hdfs文件系统加载的,hdfs对应的文件都会被删除。但是hive表对应的元数据还会保留在mysql里面。
hive> !hdfs dfs -ls /user/hive/warehouse/hive.db/emp;
Found 1 items
-rwxr-xr-x   1 hadoop supergroup        700 2018-06-07 23:12 /user/hive/warehouse/hive.db/emp/emp.txt
hive> truncate table emp;
OK
Time taken: 0.124 seconds
hive> !hdfs dfs -ls /user/hive/warehouse/hive.db/emp;     # 数据文件已经不存在了
hive>

# 外部表没有truncate操作
hive> truncate table emp_external;
FAILED: SemanticException [Error 10146]: Cannot truncate non-managed table emp_external.
hive>

2.7 查看表的建表语句(DDL)

hive> show create table emp;
OK
CREATE TABLE `emp`(
  `empno` int,
  `name` string,
  `job` string,
  `mgr` int,
  `hiredate` string,
  `salary` double,
  `comm` double,
  `depno` int)
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY '\t'
STORED AS INPUTFORMAT
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  'hdfs://10.0.0.7:9000/user/hive/warehouse/hive.db/emp'
TBLPROPERTIES (
  'COLUMN_STATS_ACCURATE'='true',
  'numFiles'='1',
  'numRows'='0',
  'rawDataSize'='0',
  'totalSize'='700',
  'transient_lastDdlTime'='1528384633')
Time taken: 0.113 seconds, Fetched: 24 row(s)
hive>

3. 函数

3.1 查看hive内建(build-in)函数

hive> show functions;

3.2 Hive聚合函数

聚合函数:max/min/count/sum/avg ,聚合函数特点是多进一出(有mr过程) 分组函数:group by; case when then(有聚合函数,所以也有mr过程) join函数:(有mr过程)   inner join: =join   outer join:left join,right join,full join   left semi join(子查询)

# 聚合函数
hive> select max(salary) from emp;

# 分组函数
hive> select deptno, avg(salary) from emp group by deptno;
hive> 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 emp;
hive>

# join 函数
hive> create table a(
    > id int, name string
    > ) row format delimited fields terminated by '\t';
OK
Time taken: 0.229 seconds
hive> create table b(
    > id int, age int
    > )row format delimited fields terminated by '\t';
OK
Time taken: 0.094 seconds
hive> load data local inpath '/home/hadoop/data/join_a.txt' overwrite into table a;
hive> load data local inpath '/home/hadoop/data/join_b.txt' overwrite into table b;
hive> select * from a;
OK
1   name1
2   name2
3   name3
Time taken: 0.057 seconds, Fetched: 3 row(s)
hive> select * from b;
OK
1   15
2   16
4   17
Time taken: 0.055 seconds, Fetched: 3 row(s)
hive> 

# inner join
hive> select * from a inner join b on a.id = b.id;      # (有mr过程)
OK
1   name1   1   15
2   name2   2   16
Time taken: 19.598 seconds, Fetched: 2 row(s)
hive> select * from a join b on a.id = b.id;      # (有mr过程,与上面一条inner join语句等价)
OK
1   name1   1   15
2   name2   2   16
Time taken: 19.639 seconds, Fetched: 2 row(s)
hive> 

# left join
hive> select * from a left join b on a.id = b.id;     # (有mr过程)
OK
1   name1   1   15
2   name2   2   16
3   name3   NULL    NULL
Time taken: 20.097 seconds, Fetched: 3 row(s)
hive> 

# right join
hive> select * from a right join b on a.id = b.id;     # (有mr过程)
OK
1   name1   1   15
2   name2   2   16
NULL    NULL    4   17
Time taken: 19.124 seconds, Fetched: 3 row(s)
hive> 

# full join
hive> select * from a full join b on a.id = b.id;          # (有mr过程)
OK
1   name1   1   15
2   name2   2   16
3   name3   NULL    NULL
NULL    NULL    4   17
Time taken: 19.047 seconds, Fetched: 4 row(s)
hive> 

# left semi join
hive> select a.id,a.name from a where a.id in (select b.id from b);
OK
1   name1
2   name2
Time taken: 21.852 seconds, Fetched: 2 row(s)
hive> 
上面这个子查询等价于
hive> select a.id,a.name from a left semi join b on a.id = b.id;
OK
1   name1
2   name2
Time taken: 19.91 seconds, Fetched: 2 row(s)
hive> 
  1. hive数据分为哪两块?分别存储在哪?
    1. hive的建表SQL语句你们觉得里有哪些内容?(不光光是字段的定义)
    2. 默认的换行符和分割符是什么? 行:\n 列:\001 ^A
    3. 加载数据或本地数据到hive表或者覆盖hive表,语法是什么?
    4. 加载数据或本地数据到hive表或者覆盖hive表,语法是什么?
    5. create table a as select * from b; 你们觉得有没有mr job?(好像要加as 我不太确认)
    6. 谈谈你们对分区表的理解? 怎样定义的,怎样加载数据,怎么查询
    7. 静态分区表和动态分区表是什么区别?
    8. 查看函数的是什么语法?
    9. (拓展题)hive一般我们用来做数据插入和追加,不会去更新删除数据,那么hive支持这种操作吗?该加什么参数呢?

注意: 对大数据工具来说,不存在回滚的概念。但是有一个概念叫重跑(要求重跑的操作是幂等的,即跑100遍结果都一样)。