set hive.exec.model.local.auto=true;
若想默認使用這個配置,能夠將這個命令添加到$HOME/.hiverc
文件中java
hadoop
dfs
命令時,最好爲這個命令定義一個別名alias hdfs="hadoop dfs"
file:///user/hive/warehouse
hdfs://namenode_server/user/hive/warehouse
set hive.metastore.warehouse.dir=/user/myname/hive/warehouse;
能夠將這條語句寫入到$HOME/.hiverc
文件中node
set hive.cli.print.current.db=true;
hive -e 後面直接跟HiveQL正則表達式
hive -S -e "select name from person;"shell
Hive會將輸出寫到標準輸出中,可使用shell中的輸出重定向將輸出重定向到本地文件中,而不是hdfs中數據庫
hive -S -e "set" | grep warehouse 查詢數據倉庫的位置
hive -f /user/scott/hive.hql
或者在hive shell
中使用source
命令來執行腳本文件apache
hive > source /user/scott/hive.hql
hive啓動後默認會在當前用戶home目錄下尋找名爲.hiverc
的文件,且自動執行文件中的命令編程
一個典型的.hiverc文件中的內容爲安全
ADD JAR /user/scott/hive-examples.jar; #增長一個jar文件 set hive.cli.print.current.db=true; #顯示當前所在工做數據庫 set hive.exec.model.local.auto=true; #設置以本地文件模式運行(當hadoop是以分佈式模式或者僞分佈式模式執行時的話,就在本地執行,能夠加快小數據集的查詢速度)
注:每行語句結尾的分號不可省略session
用戶不須要退出hive就能夠執行shell命令,只須要在命令前加上!而且以;結尾就能夠,如:app
hive > !pwd; #查看當前目錄
注:hive shell中使用shell命令時,不能使用須要用戶進行輸入交互的命令,且不支持shell的管道功能和文件名自動補全功能。
hive > dfs -ls /;
-- 用戶使用以--
開頭的字符表示註釋。該註釋只能放在hiveql腳本中若直接在hive shell中使用的話會報錯
hive > set hive.cli.print.header=true;
同理能夠將該語句添加到$home/.hiverc
文件中
若是用戶沒有顯式指定數據庫,默認數據庫是default
下面這個例子展現瞭如何建立數據庫
CREATE DATABASE simple;
若數據庫simple
已經存在的話,將會報錯誤消息。可使用下面的語句避免錯誤信息
CREATE DATABASE IF NOT EXISTS simple;
使用SHOW DATABASES
命令查看hive中所包含的數據庫
SHOW DATABASES;
若是數據庫比較多,可使用正則表達式匹配篩選所須要的數據庫名
SHOW DATABASES LIKE 'sim.*';
Hive爲每一個數據庫建立一個目錄,數據庫中的表將會以這個數據庫目錄的子目錄形式存儲。有一個例外就是default數據庫中的表。由於這個數據庫自己沒有本身的目錄。數據庫所在的目錄位於屬性hive.metastore.warehouse.dir
所指定的頂層目錄以後。倘若用戶使用的這個配置項的默認配置,也就是/user/hive/warehouse
,那麼當咱們建立數據庫simple
時,Hive將會對應地建立一個目錄爲/user/hive/warehouse/simple.db
。這裏請注意,數據庫的文件目錄名是以.db
結尾的。
用戶能夠經過以下的命令來修改這個默認的配置
hive > CREATE DATABASE simple LOCATION '/user/myname/directory';
用戶還能夠爲這個數據庫增長一個描述信息。這樣經過DESCRIBE DATABASE databasename
命令就能夠查看到該信息
hive > CREATE DATABASE simple COMMENT 'a simple database';
使用DESCRIBE DATABASE databasename
查看
hive > DESCRIBE DATABASE simple; simple a simple database hdfs://hostname/user/hive/warehouse/simple.db
從上面的例子能夠看出DESCRIBE DATABASE
不只會顯示這個數據庫的描述信息還會顯示這個數據庫所在文件的目錄位置。若Hadoop是本地模式的話前面的前綴爲file:///
如果分佈式模式則前綴爲hdfs://
此外用戶還能夠爲數據庫增長一些和其餘相關的鍵-值對屬性信息。可使用DESCRIBE DATABASE EXTENDED databasename
語句顯示這些信息,如:
hive > CREATE DATABASE simple WITH DBPROERTIES ('creator'='scott','date'='2014-05-05'); hive > DESCRIBE DATABASE simple; hive > DESCRIBE DATABASE EXTENDED simple;
命令USE
用於將某個數據庫設置爲當前的工做數據庫。如:
USE simple;
此時能夠用SHOW TABLES
顯示當前數據庫下全部的表。不幸的是,沒有那個命令讓用戶查看當前所在的庫。幸運的是在Hive中能夠重複使用USE
,這是由於在Hive中沒有嵌套數據庫的概念。
hive > set hive.cli.print.current.db=true; hive (simple) > USE default; hive (default) > set hive.cli.print.current.db=false;
最後用戶能夠刪除數據庫
hive > DROP DATABASE IF EXISTS simple;
IF EXISTS
子句是可選的。能夠避免因數據庫不存在而拋出警告信息。默認狀況下Hive是不容許用戶刪除一個包含有表的數據倉庫。要麼用戶先刪除庫中的表,而後再刪數據庫。要麼在刪除命令的最後面加上關鍵字CASCADE
,這樣Hive先自行刪除數據庫中的表
hive > DROP DATABASE IF EXISTS simple CASCADE;
若使用的是RESTRICT
這個關鍵字,而不是CASCADE
這個關鍵字的話,那麼就和默認狀況同樣。
若是某個數據庫被刪除了,那麼其對應的目錄也同時會被刪除。
用戶可使用ALTER DATABASE
命令爲某個數據庫的DBPROPERTIES
設置鍵-值對屬性值,來描述數據庫的屬性信息。數據庫的其餘元數據信息是不可更改的,包括數據庫名和數據庫所在的目錄位置。
hive > ALTER DATABASE simple SET DBPROPERTIES ('edited-by'='Join');
沒有辦法刪除或者"重置"數據庫屬性。
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 of the table' TBLPROPERTIES ('creator'='me', 'created_at'='2012-01-02 10:00:00') LOCATION '/user/hive/warehouse/mydb.db/employees';
首先,咱們注意到,若是用戶當前所處的數據庫並不是是目標數據庫,那麼用戶是能夠在表名前增長一個數據庫名
來進行指定的,也就是例子中的mydb
若是用戶增長上選項IF NOT EXISTS
,那麼若表已經存在了,Hive就會忽略掉後面的執行語句。且不會有任何提示。用戶能夠在字段類型後使用COMMENT
爲每一個字段增長一個註釋。還能夠指定一個或多個表屬性。大多數狀況下TBLPROPERTIES
的主要做用是按鍵-值對的格式爲表增長額外的文檔說明。
Hive會自動增長兩個表屬性:一個是last_modified_by
,其保存着最後修改這個表的用戶的用戶名;另外一個是last_modified_time
其保存着最後一次修改這個表的新紀元時間秒。
使用SHOW TBLPROPERTIES table_name
列舉出某個表的TBLPROPERTIES
屬性信息
最後,能夠看到咱們根據狀況爲表中的數據指定一個存儲路徑。在這個例子中,咱們使用Hive默認的路徑/user/hive/warehouse/mydb.db/employees
,其中,/user/hive/warehouse
是默認的數據倉庫路徑,mydb.db
是數據庫目錄,employees
是表目錄。
默認狀況下。Hive老是將建立的表的目錄放置在這個表所屬的數據庫目錄之下。不過,default
數據庫是個例外,其在/user/hive/warehouse
下並無對應一個數據庫目錄。所以default
數據庫中的表目錄會直接位於/user/hive/warehouse
目錄下(用戶明確指定除外).
用戶還能夠拷貝一張已經存在的表的模式(無需拷貝數據):
CREATE TABLE IF NOT EXISTS mydb.employees2 LIKE mydb.employees;
該語句能夠接受可選的LOCATION
子句,可是注意其餘的屬性,包括模式都是不可能從新定義的。這些信息直接從原是表得到.
SHOW TABLES
命令能夠列舉出全部的表,若是不增長其餘參數,那麼只會顯示當前工做數據庫下的表。假設不在那麼數據庫下,仍是能夠列出指定數據庫下的表使用SHOW TABLES IN dbname
hive > USE default; hive > SHOW TABLES IN mydb; employees department
若是有不少的表,那麼可使用正則表達式來過濾出所須要的表名.
hive> USE mydb; hive> SHOW TABLES 'empl.*'; employees
注意:IN databasename
和表名使用正則表達式過濾這個兩個功能尚不支持同時使用.
咱們可使用DESCRIBE EXTENDED mydb.employees
命令來查看這個表的詳細結構信息(若是當前所處的工做數據庫就是mydb的話,能夠不加mydb這個前綴).
hive> DESCRIBE EXTENDED mydb.employees; name string Employee name salary float Employee salary subordinates array<string> Names of subordinates deductions map<string,float> Keys are deductions names, values are percentages address struct<street:string,city:string,state:string,zip:int> Home address Detailed Table Information Table(tableName:employees, dbName:mydb, owner:me, ... location:hdfs://master-server/user/hive/warehouse/mydb.db/employees, parameters:{creator=me, created_at='2012-01-02 10:00:00', last_modified_user=me, last_modified_time=1337544510, comment:Description of the table, ...}, ...)
使用FORMATTED
關鍵字替代EXTENDED
關鍵字的話,能夠提供更加可讀的輸出信息。在應用中多使用FORMATTED
關鍵字
DESCRIBE FORMATTED employees;
若是用戶只想查看某一個列的信息,那麼只要在表名後面增長這個字段的名稱便可.
hive> DESCRIBE mydb.employees.salary; salary float Employee salary
注:last_modified_by
和last_modified_time
兩個表屬性是自動建立的。若是用戶沒有定義任何的自定義表屬性的話,那麼這兩個表屬性也不會顯示在表的詳細信息中!
咱們目前所建立的表均屬於管理表,有時也被稱爲內部表.由於這種表,Hive會或多或少的控制着數據項的生命週期.如:Hive默認狀況下會將這些表的數據存儲在由配置項hive.metastore.warehouse.dir
(如/user/hive/warehouse
)所定義的目錄的子目錄下.
當咱們刪除一個管理表時,Hive也會刪除這個表中的數據.管理表不方便和其餘工做共享數據。
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';
關鍵字EXTERNAL
告訴Hive這個表是外部的。然後面的LOCATION
子句告訴Hive數據位於那個路徑下. 由於表是外部的,因此Hive並不是認爲其徹底擁有這份數據,所以,刪除該表並不會刪除掉這份數據,不過描述表的元數據信息將會被刪除掉.
用戶能夠在DESCRIBE EXTENDED tablename
語句的輸出中查看到表是管理表仍是外部表.在末尾的詳細表信息輸出中,對於管理表,用戶能夠看到以下信息:
tableType:MANAGED_TABLE
對於外部表
tableType:EXTERNAL_TABLE
對於管理表,用戶能夠對一張存在的表進行結構複製(不會複製數據)
CREATE EXTERNAL TABLE IF NOT EXISTS mydb.employees3 LIKE mydb.employees LOCATION '/path/to/data';
若語句中省略掉EXTERNAL
關鍵字,且源表是外部表的話,那麼新生成的表也將是外部表,若語句中省略掉EXTERNAL
關鍵字,且源表是管理表的話,那麼新生成的表也將是管理表。 若語句中含有EXTERNAL
關鍵字,且源表是管理表的話,那麼生成的新表將是外部表。 即便在這種場景下,LOCATION
子句一樣是可選的。
Hive中有分區表的概念。分區表將數據以一種符合邏輯的方式進行組織。好比分層存儲。
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);
若是表中的數據以及分區個數很是大的話,執行一個包含全部分區的查詢可能會觸發一個巨大的MapReduce任務。建議的安全措施是將Hive設置爲「strict」
模式,這樣對分區表查詢WHERE子句沒有加分區過濾的話,將會禁止提交這個任務.能夠按照下面的語句將屬性設置爲「nonstrict」
模式。
hive> set hive.mapred.mode=strict; hive> SELECT e.name, e.salary FROM employees e LIMIT 100; FAILED: Error in semantic analysis: No partition predicate found for Alias "e" Table "employees" hive> set hive.mapred.mode=nonstrict; hive> SELECT e.name, e.salary FROM employees e LIMIT 100;
能夠經過使用SHOW PARTITIONS
命令查看錶中存在的全部分區
hive> SHOW PARTITIONS employees; ... Country=CA/state=AB country=CA/state=BC ... country=US/state=AL country=US/state=AK
若是表中存在不少的分區,而只想查看是否存儲某個特定分區鍵的分區的話。能夠在這個命令上增長一個指定了一個或者多個特定分區字段值的PARTITION
子句,進行過濾
hive> SHOW PARTITIONS employees PARTITION(country='US'); country=US/state=AL country=US/state=AK ... hive> SHOW PARTITIONS employees PARTITION(country='US', state='AK'); country=US/state=AK
DESCRIBE EXTENDED employees
命令也會顯示出分區鍵
hive> DESCRIBE EXTENDED employees; name string, salary float, ... address struct<...>, country string, state string Detailed Table Information... partitionKeys:[FieldSchema(name:country, type:string, comment:null), FieldSchema(name:state, type:string, comment:null)],
在管理表中用戶能夠經過載入數據的方式建立分區。下面的例子將從本地目錄()載入數據到表中的時候.將會建立一個US和CA分區.用戶須要爲每一個分區字段指定一個值.注意在HiveQL中是如何引用HOME環境變量的:
LOAD DATA LOCAL INPATH '${env:HOME}/california-employees' INTO TABLE employees PARTITION (country = 'US', state = 'CA');
Hive將會建立這個分區對應的目錄/employees/country=US/state=CA
且$HOME/california-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 FORMAT DELIMITED FIELDS TERMINATED BY '\t';
分區外部表對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';
Hive並不控制這些數據,即便表被刪除,數據也不會被刪除.
和分區管理表同樣.經過SHOW PARTITIONS
查看外部表的分區。如:
hive> SHOW PARTITIONS log_messages; ... year=2011/month=12/day=31 year=2012/month=1/day=1 year=2012/month=1/day=2 ...
一樣,DESCRIBE EXTENDED log_messages
語句會將分區鍵做爲表的模式一部分和partitionKeys列表的內容同時顯示
hive> DESCRIBE EXTENDED log_messages; ... message string, year int, month int, day int Detailed Table Information... partitionKeys:[FieldSchema(name:year, type:int, comment:null), FieldSchema(name:month, type:int, comment:null), FieldSchema(name:day, type:int, comment:null)], ...
這個輸出少了一個很是重要的信息.那就是分區數據實際存在的路徑.
經過如下方式查看分區數據所在路徑
hive> DESCRIBE EXTENDED log_messages PARTITION (year=2012, month=1, day=2); ... location:s3n://ourbucket/logs/2011/01/02, ...
一般會使用分區外部表.
Hive默認的存儲格式是文本文件格式.能夠經過可選的子句STORED AS TEXTFILE
顯式指定.同時用戶能夠在建立表的時指定各類各樣的分隔符.
CREATE TABLE employees ( name STRING, salary FLOAT, subordinates ARRAY<STRING>, deductions MAP<STRING, FLOAT>, address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT> ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001' COLLECTION ITEMS TERMINATED BY '\002' MAP KEYS TERMINATED BY '\003' LINES TERMINATED BY '\n' STORED AS TEXTFILE;
注:TEXTFILE
意味着全部字段都使用字母、數字、字符編碼,包括那麼國際字符集.Hive默認是使用不可見字符來做爲分隔符的。使用TEXTFILE
意味着,每一行被認爲是一個單獨的記錄.可使用SEQUENCEFILE
和RCFILE
兩種文件格式來替換TEXTFILE
.這兩種文件格式都是使用二進制編碼和壓縮來優化磁盤空間及I/O帶寬性能的。
記錄編碼是經過一個input format
對象來控制的。Hive使用了一個名爲org.apache.hadoop.mapred.TextInputFormat
的java類.
記錄的解析是由序列化/反序列化(SerDe)來控制的,對於TEXTFILE
Hive所使用的SerDe
是org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
java類.
Hive使用一個叫作output format
的對象將查詢輸出寫入到文件中或者輸出到控制檯.對於TEXTFILE
Hive所使用的輸出類爲org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
可使用第三方的輸入輸出格式及SerDe,容許用戶自定義Hive自己不支持的其餘文件格式
CREATE TABLE kst PARTITIONED BY (ds string) ROW FORMAT SERDE 'com.linkedin.haivvreo.AvroSerDe' WITH SERDEPROPERTIES ('schema.url'='http://schema_provider/kst.avsc') STORED AS INPUTFORMAT 'com.linkedin.haivvreo.AvroContainerInputFormat' OUTPUTFORMAT 'com.linkedin.haivvreo.AvroContainerOutputFormat';
ROW FORMAT SERDE …
指定了使用的SerDe。Hive提供了WITH SERDEPROPERTIES
功能,容許用戶傳遞配置信息給SerDe。每一個屬性名稱和值都應該是帶引號的字符串.
STORED AS INPUTFORMAT … OUTPUTFORMAT
分別定義了用於輸入和輸出格式的java類。若是要指定,必須對輸入和輸出格式都指定.
DESCRIBE EXTENDED table
會列出輸入和輸出格式以及SerDe和SerDe所自帶的屬性信息。如:
hive> DESCRIBE EXTENDED kst ... inputFormat:com.linkedin.haivvreo.AvroContainerInputFormat, outputFormat:com.linkedin.haivvreo.AvroContainerOutputFormat, ... serdeInfo:SerDeInfo(name:null, serializationLib:com.linkedin.haivvreo.AvroSerDe, parameters:{schema.url=http://schema_provider/kst.avsc}) ...
DROP TABLE IF EXISTS employees;
對於管理表,表的元數據信息和表內的數據都被刪除
對於外部表,表的元數據信息會被刪除,可是表中的數據不會被刪除
大多數的表屬性能夠經過使用ALTER TABLE
語句來修改.該操做會修改元數據,但不會修改數據自己.用於修改表模式中的錯誤及分區路徑.
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' ...;
修改分區路徑
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);
對於管理表分區內的數據和元數據會一塊兒被刪除。對應外部表,分區內的數據不會被刪除
能夠對字段重命名、修改其位置、類型或者註釋:
ALTER TABLE log_messages CHANGE COLUMN hms hours_minutes_seconds INT COMMENT 'The hours, minutes, and seconds part of the timestamp' AFTER severity;
即便字段名和字段類型都沒有改變,也須要徹底指定舊的字段名。並給出新的字段名以及新的字段類型。若要將字段移動到第一個位置,只須要使用FIRST
關鍵字替代AFTER other_column
子句便可.
這個操做,只會修改元數據信息。要注意數據與模式匹配.
能夠在分區字段前增長新的字段到已有字段以後
ALTER TABLE log_messages ADD COLUMNS ( app_name STRING COMMENT 'Application name', session_id LONG COMMENT 'The current session id');
ALTER TABLE log_messages REPLACE COLUMNS ( hours_mins_secs INT COMMENT 'hour, minute, seconds from timestamp', severity STRING COMMENT 'The message severity' message STRING COMMENT 'The rest of the message');
ALTER TABLE log_messages SET TBLPROPERTIES ( 'notes' = 'The process id is no longer captured; this column is always NULL');
能夠增長附加的表屬性或者修改已經存在的表屬性。可是沒法刪除屬性。
ALTER TABLE log_messages PARTITION(year = 2012, month = 1, day = 1) SET FILEFORMAT SEQUENCEFILE;
若是是分區表,須要使用PARTITION
子句
ALTER TABLE table_using_JSON_storage SET SERDE 'com.example.JSONSerDe' WITH SERDEPROPERTIES ( 'prop1' = 'value1', 'prop2' = 'value2');
ALTER TABLE … TOUCH
語句用於觸發鉤子
ALTER TABLE log_messages TOUCH PARTITION(year = 2012, month = 1, day = 1);
ALTER TABLE … ARCHIVE PARTITION
將分區內的文件打成一個Hadoop壓縮包(HAR)文件.僅僅下降文件系統中的文件數和NameNode的壓力,不會減小存儲空間
ALTER TABLE log_messages ARCHIVE PARTITION(year = 2012, month = 1, day = 1);
最後Hive提供了保護,下面的語句防止分區被刪除和被查詢
ALTER TABLE log_messages PARTITION(year = 2012, month = 1, day = 1) ENABLE NO_DROP;
ALTER TABLE log_messages PARTITION(year = 2012, month = 1, day = 1) ENABLE OFFLINE;