hive学习笔记之-数据定义

1. 数据库定义及操作

--创建数据库

hive(default)> SET hive.cli.print.current.db=false;

hive> CREATE DATABASE financials;

 

--创建库时加判断语句

hive> CREATE DATABASE if not exists financials;

 

--也可以使用关键字schames 代替database,是一样的

hive> CREATE SCHEMA if not exists financials;

 

--查看数据库

hive> SHOW DATABASE;

default

financials

 

hive> SHOW DATABASES LIKE 'fin*';

financials

 

--指定数据创建目录

hive> CREATE DATABASE financials1     

> LOCATION '/user/hive/warehouse/';

 

--查看数据描述

hive> DESC DATABASE financials1;

financials1             hdfs://nticket1:9000/user/hive/warehouse

Time taken:0.043 seconds, Fetched: 1 row(s)

 

--指定自定义key-value参数创建数据库及查看

hive> drop database if exists financials;

hive> CREATE DATABASE financials

    > WITH DBPROPERTIES ('creator' = 'licz','date' = '2014-01-23');

 

hive> DESC DATABASE financials;

financials             hdfs://nticket1:9000/user/hive/warehouse/financials.db

 

hive> DESC DATABASE EXTENDED financials ;

financials             hdfs://nticket1:9000/user/hive/warehouse/financials.db  {date=2014-01-23,creator=licz}

 

 

--切换数据库

hive> USE financials1;

hive虽然没有像mysql那样有查看当前数据库的命令,但可以通过hive.cli.print.current.db参数达到同样的目的。

mysql> select database();

+------------+

| database() |

+------------+

| mysql      |

+------------+

1 row in set(0.00 sec)

 

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

hive(financials1)> use financials;

hive(financials)>

 

--删除数据库

hive> DROP DATABASE financials;

hive> DROP DATABASE IF EXISTS financials;

 

如果数据库下面有表存在,要删除表之后再用上面的语句,否则加cascade子句

hive> DROP DATABASE IF EXISTS financials CASCADE;

 

 

2. 修改数据库

hive (financials)>alter database financials set dbproperties ('creator' = 'lichangzai','editedby' = 'licz' ); 

hive(financials)> desc database extended financials;

financials             hdfs://nticket1:9000/user/hive/warehouse/financials.db  {edited by=licz, date=2014-01-23,creator=lichangzai}

 

3. 创建表

下面是一个建表的例子:

hive > create database mydb;

hive >

CREATE TABLE IF NOT EXISTS mydb.employees (

name        STRING COMMENT 'Employee name',

salary        FLOAT  COMMENT'Employee salary',

subordinates    ARRAY COMMENT 'Names of subordinates',

deductions    MAP

COMMENT 'Keys are deductions names, values are percentages',

address       STRUCT

COMMENT 'Home address')

COMMENT 'Description ofthe table'

LOCATION '/user/hive/warehouse/mydb.db/employees'

TBLPROPERTIES ('creator'='li','created_at'='2014-1-23 10:00:00');

 

根据上节的建表语句,上面例子增加了些附加子句

 

--创建和其它表相同结构的表

CREATE TABLE IFNOT EXISTS mydb.employees2

LIKEmydb.employees;

 

--查看详细表

hive > descextended mydb.employees;

 

4. 管理表

Hive中分管理表和外部表,管理表又叫托管表、内部表。

以上创建的表都是管理表,可以表里的数据进行直接操作,删除表后表的内容也被告删除。

 

5. 外部表

下面是一个例子说明外部表的用法。

--查看外部文件

[licz@nticket1~]$ hadoop dfs -ls /data/stocks

Found 3 items

-rw-r--r--   2 licz supergroup       8645 2014-01-24 14:17/data/stocks/sz000001.txt

-rw-r--r--   2 licz supergroup       8368 2014-01-24 14:17/data/stocks/sz000002.txt

-rw-r--r--   2 licz supergroup       7720 2014-01-24 14:17/data/stocks/sz000003.txt

 

目录下3个文件,每个文件中有100条记录

内容如下:

[licz@nticket1~]$ hadoop dfs -cat /data/stocks/sz000001.txt|head -5

sz,10000001,2013-07-0800:00:00,1983.215,1983.215,1953.121,1958.273,84136491,2007.199

sz,10000001,2013-07-0500:00:00,2006.191,2021.541,2002.367,2007.199,91345222,2006.098

sz,10000001,2013-07-0400:00:00,1982.870,2022.136,1974.103,2006.098,100394183,1994.268

sz,10000001,2013-07-0300:00:00,1996.506,1996.537,1965.519,1994.268,93466471,2006.560

sz,10000001,2013-07-0200:00:00,1992.890,2007.620,1978.428,2006.560,86415418,1995.242

 

--创建外部表

CREATE EXTERNAL TABLE IF NOT EXISTS stocks (

exchange STRING,

symbol STRING,

ymd STRING,

price_open FLOAT,

price_high FLOAT,

price_low FLOAT,

price_close  FLOAT,

volume INT,

price_adj_close FLOAT)

ROW FORMAT DELIMITED 

FIELDS TERMINATED BY ','

LOCATION'/data/stocks';

 

--查看外部表记录

hive (mydb)>select * from stocks limit 10;

OK

sz      10000001        2013-07-08 00:00:00     1983.215        1983.215        1953.121        1958.273        84136491        2007.199

sz      10000001        2013-07-05 00:00:00     2006.191        2021.541        2002.367        2007.199        91345222        2006.098

sz      10000001        2013-07-04 00:00:00     1982.87 2022.136        1974.103        2006.098        100394183       1994.268

sz      10000001        2013-07-03 00:00:00     1996.506        1996.537        1965.519        1994.268        93466471        2006.56

 

hive (mydb)>select count(*) from stocks; 

300

 

--创建结构相同的空表

和管理表一样,外部表也能用like创建和其它表管理表一样的空表

CREATE EXTERNAL TABLE IF NOT EXISTS mydb.employees3

LIKEmydb.employees

LOCATION'/path/to/data';

 

6. 分区表

分区管理表

 

--创建分区表

DROP TABLE IFEXISTS employees;

 

CREATE TABLE employees (

name STRING,

salary FLOAT,

subordinates ARRAY,

deductions MAP,

address STRUCT

)

PARTITIONED BY(country STRING, state STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY ','

COLLECTION ITEMS TERMINATED BY '|'

MAP KEYS TERMINATED BY ':';

 

hive (mydb)>desc employees;

OK

name                    string                  None               

salary                  float                   None               

subordinates            array           None                

deductions              map       None               

address                struct  None               

country                 string                  None               

state                   string                  None               

                

# PartitionInformation         

# col_name              data_type               comment            

                

country                 string                  None                

state                   string                  None               

Time taken:0.129 seconds, Fetched: 13 row(s)

 

--导入数据

load data local inpath '/app/hadoop/data/employees_1'

overwrite into table employees partition(country = 'CH',state = 'BeiJin');

 

load data local inpath '/app/hadoop/data/employees_2'

overwrite into table employees partition(country = 'US',state = 'NY');

 

--导入后目录结构

.../employees/country=CH/state=BeiJin'

.../employees/country=US/state=NY

.../employees/country=US/state=AK

 

--查看表的分区

hive (mydb)>show partitions employees;                                              

OK

country=US/state=CL

country=US/state=NY

country=CH/state=BeiJin

 

hive> SHOWPARTITIONS employees PARTITION(country='US');

country=US/state=AL

country=US/state=AK

...

 

注意:

当用户不加限制条件对一个非常大的分区表进行全表扫描时,这样触发一个巨大的MapReduce Job,会给硬盘带来很大的压力。所以Hive强烈建议使用“strict”,即当用户的查询语句不加where条件时,是禁止对分区表进行查询的。你能改成“nonstrict”模式(默认的模式)取消这种限制。

hive (mydb)>set hive.mapred.mode=strict;

hive (mydb)>select * from employees;   

FAILED: SemanticException[Error 10041]: No partition predicate found for Alias "employees"Table "employees"

 

 

 

外部分区表:

一个分区表实例:

CREATE EXTERNAL TABLE IF NOT EXISTS log_messages (

hms INT,

severity STRING,

server STRING,

process_id INT,

message STRING)

PARTITIONED BY(year INT, month INT, day INT)

ROW FORMATDELIMITED FIELDS TERMINATED BY '\t';

 

上面创建外部表语句可以看到,我们没有加像非分区表那样的LOCATION子句。

外部分区表在创建时是不需要加LOCATION子句的,代替的是通过ALTER TABLE语句添加各自的分区。如下:

 

--添加外部表的分区

ALTER TABLE log_messages ADD PARTITION(year = 2012, month = 1, day = 2)

LOCATION 'hdfs://master_server/data/log_messages/2012/01/02';

 

 

7. 删除表

 

DROP TABLE IFEXISTS employees;

 

如果启用hadoop回收站(.Trash)功能,删除的会移动到.Trash目录,通过设置fs.trash.interval参数回收站的回收周期。但不是能保证所有版本的都能使用这咱方法。如果不小删除了重要的管理表,可以重新创建一个相同表名的空表,然后把回收站的移回原来的目录,这样就能恢复数据。

 

8. 修改分区表

--重命名

ALTER TABLE log_messages RENAME TO logmsgs;

 

--添加外部分区表分区

ALTER TABLE log_messages ADD IF NOT EXISTS

PARTITION (year= 2011, month = 1, day = 1) LOCATION '/logs/2011/01/01'

PARTITION (year= 2011, month = 1, day = 2) LOCATION '/logs/2011/01/02'

PARTITION (year= 2011, month = 1, day = 3) LOCATION '/logs/2011/01/03'

...;

 

注意:当添加单个分区时,分区目录会动创建,但如果同时添加多个分区时,只会创建第一个分区的目录。如上面的语句,只会创建/logs/2011/01/01目录,其它两个不会创建。


 

--改变分区的位置

ALTER TABLE log_messages PARTITION(year = 2011, month = 12, day = 2)

SET LOCATION 's3n://ourbucket/logs/2011/01/02';

 

--删除分区

ALTER TABLE log_messages DROP IF EXISTS PARTITION(year = 2011, month = 12, day = 2);

 

9. 列的修改

--修改列的名字并改变列的位置

ALTER TABLE log_messages

CHANGE COLUMN hms hours_minutes_seconds INT

COMMENT 'Thehours, minutes, and seconds part of the timestamp'

AFTER severity;

 

上面的语句作用是,修改hms列的名字为hours_minutes_seconds,并把它放在severity列之后。

 

改之前:

hive学习笔记之-数据定义_第1张图片

改之后:

hive学习笔记之-数据定义_第2张图片

 

--添加列

ALTER TABLE log_messages ADD COLUMNS (

app_name  STRING COMMENT 'Application name',

session_id STRING  COMMENT 'The current sessionid');

 

--替换列

ALTER TABLE log_messages REPLACE COLUMNS (

hours_mins_secs INT  COMMENT 'hour, minute, seconds fromtimestamp',

severity  STRING COMMENT 'The message severity'

message  STRING COMMENT 'The rest of the message');

 

上面的语句是重命名原来的hms列为hours_mins_secs,删除掉原来的server和process_id列。

但注意REPLACE语句只有在本地的SerDe 模式的表上使用,后面的章节会提到。

 

--修改表的属性测试报错

ALTER TABLE log_messages SET TBLPROPERTIES

('notes' = The process idis no longer captured; this column is always NULL');

 

 

--修改存储属性

ALTER TABLE log_messages

PARTITION(year =2011, month = 1, day = 1)

SET FILEFORMAT SEQUENCEFILE;

 

ALTER TABLE stocks

CLUSTERED BY(exchange, symbol)

SORTED BY(symbol)

INTO 48 BUCKETS;

 

 

10 .其它修改表语句

--钩回语句

ALTER TABLE log_messages TOUCH

PARTITION (year =2012, month = 1, day = 1);

 

执行上面的语句后,当hive的外部文件被修改时,会触发一个钩回操作

 

--归档分区语句

ALTER TABLE log_messages ARCHIVE

PARTITION(year =2012, month = 1, day = 1);

 

归档分区仅是减少文件系统文件的数量,减少namenode的压力,不会减少空间使用。反操作语句是NOARCHIVE

 

--保护分区不会被删除

ALTER TABLE log_messages

PARTITION(year =2012, month = 1, day = 1) ENABLE NO_DROP;

 

hive (mydb)>ALTER TABLE logmsgs

           > PARTITION(year = 2014, month =1, day = 21) ENABLE NO_DROP;

hive (mydb)>ALTER TABLE logmsgs DROP IF EXISTS PARTITION(year = 2014, month = 1, day = 21);

FAILED:SemanticException [Error 30011]: Partition protected from being droppedmydb@logmsgs@year=2014/month=1/day=21

hive (mydb)>ALTER TABLE logmsgs

           > PARTITION(year = 2014, month =1, day = 21) disABLE NO_DROP;

OK

Time taken: 0.25seconds

hive (mydb)>ALTER TABLE logmsgs DROP IF EXISTS PARTITION(year = 2014, month = 1, day = 21);

Dropping thepartition year=2014/month=1/day=21

OK

Time taken:0.429 seconds

hive (mydb)>show partitions logmsgs;

OK

year=2014/month=1/day=20

year=2014/month=1/day=22

Time taken:0.105 seconds, Fetched: 2 row(s)

 

--保护分区不能被查询

ALTER TABLE log_messages

PARTITION(year =2012, month = 1, day = 1) ENABLE OFFLINE;

 

 

你可能感兴趣的:(Hive)