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<STRING> COMMENT 'Names of subordinates',
deductions MAP<STRING, FLOAT>
COMMENT 'Keys are deductions names, values are percentages',
address STRUCT<street:STRING,city:STRING, state:STRING, zip:INT>
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. 外部表
下面是一個例子說明外部表的用法。
--檢視外部檔案
[[email protected]~]$ 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條記錄
內容如下:
[[email protected]~]$ 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<STRING>,
deductions MAP<STRING, FLOAT>,
address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>
)
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<string> None
deductions map<string,float> None
address struct<street:string,city:string,state:string,zip:int> 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列之後。
改之前:
改之後:
--新增列
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 [email protected]@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;