1、Hive的數據存儲
Hive的數據存儲基於Hadoop HDFS
Hive沒有專門的數據存儲格式
存儲結構主要包括:數據庫、文件、表、試圖
Hive默認可以直接加載文本文件(TextFile),還支持sequence file
創建表時,指定Hive數據的列分隔符與行分隔符,Hive即可解析數據。
2、Hive的數據模型-數據庫
類似傳統數據庫的DataBase
默認數據庫"default"
使用#hive命令后,不使用hive>use <數據庫名>,系統默認的數據庫。可以顯式使用hive> use default;
創建一個新數據庫
hive > create database test_dw;
3、Hive的數據模型-表
- Table 內部表
與數據庫中的 Table 在概念上是類似
每一個 Table 在 Hive 中都有一個相應的目錄存儲數據。例如,一個表 test,它在 HDFS 中的路徑為:$HIVE_HOME/warehouse/test。warehouse是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的數據倉庫的目錄
所有的 Table 數據(不包括 External Table)都保存在這個目錄中。
內部表,刪除表時,元數據與數據都會被刪除
具體操作如下:
創建數據文件inner_table.dat
創建表
hive>create table inner_table (key string);
加載數據
hive>load data local inpath '/usr/local/inner_table.dat' into table inner_table;
查看數據
select * from inner_table
select count(*) from inner_table
刪除表
drop table inner_table
- External Table 外部表
- 指向已經在 HDFS 中存在的數據,可以創建 Partition
- 它和 內部表 在元數據的組織上是相同的,而實際數據的存儲則有較大的差異
- 內部表 的創建過程和數據加載過程(這兩個過程可以在同一個語句中完成),在加載數據的過程中,實際數據會被移動到數據倉庫目錄中;之后對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除
- 外部表只有一個過程,加載數據和創建表同時完成,並不會移動到數據倉庫目錄中,只是與外部數據建立一個鏈接。當刪除一個 外部表 時,僅刪除該鏈接
具體實例如下:
CREATE EXTERNAL TABLE page_view
( viewTime INT,
userid BIGINT,
page_url STRING,
referrer_url STRING,
ip STRING COMMENT 'IP Address of the User',
country STRING COMMENT 'country of origination‘
)
COMMENT 'This is the staging page view table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '44' LINES TERMINATED BY '12'
STORED AS TEXTFILE
LOCATION 'hdfs://hadoop:9000/user/data/staging/page_view';
創建數據文件external_table.dat
創建表
hive>create external table external_table1 (key string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
location '/home/external';
在HDFS創建目錄/home/external:
#hadoop fs -put /home/external_table.dat /home/external
加載數據
LOAD DATA INPATH '/home/external_table1.dat' INTO TABLE external_table1;
查看數據
select * from external_table
select count(*) from external_table
刪除表
drop table external_table
內部表與外部表的區別:
外部表只刪除表信息(元數據信息),不刪除數據;內部表會刪除表信息和數據信息
- Partition 分區表
分區表相關命令:
SHOW TABLES; # 查看所有的表
SHOW TABLES '*TMP*'; #支持模糊查詢
SHOW PARTITIONS TMP_TABLE; #查看表有哪些分區
DESCRIBE TMP_TABLE; #查看表結構
Partition 對應於數據庫的 Partition 列的密集索引
在 Hive 中,表中的一個 Partition 對應於表下的一個目錄,所有的 Partition 的數據都存儲在對應的目錄中
例如:test表中包含 date 和 city 兩個 Partition,
則對應於date=20130201, city = bj 的 HDFS 子目錄為:
/warehouse/test/date=20130201/city=bj
對應於date=20130202, city=sh 的HDFS 子目錄為;
/warehouse/test/date=20130202/city=sh
具體操作:
CREATE TABLE tmp_table #表名
(
title string, # 字段名稱 字段類型
minimum_bid double,
quantity bigint,
have_invoice bigint
)COMMENT '注釋:XXX' #表注釋
PARTITIONED BY(pt STRING) #分區表字段(如果你文件非常之大的話,采用分區表可以快過濾出按分區字段划分的數據)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001' # 字段是用什么分割開的
STORED AS SEQUENCEFILE; #用哪種方式存儲數據,SEQUENCEFILE是hadoop自帶的文件壓縮格式
創建數據文件partition_table.dat
創建表
create table partition_table(rectime string,msisdn string)
partitioned by(daytime string,city string)
row format delimited
fields terminated by '\t' stored as TEXTFILE;
加載數據到分區
load data local inpath '/home/partition_table.dat' into table partition_table partition (daytime='2013-02-01',city='bj');
查看數據
select * from partition_table
select count(*) from partition_table
刪除表
drop table partition_table
alter table partition_table add partition (daytime='2013-02-04',city='bj');
通過load data 加載數據
alter table partition_table drop partition (daytime='2013-02-04',city='bj')
元數據,數據文件刪除,但目錄daytime=2013-02-04還在
- Bucket Table 桶表
桶表是對數據進行哈希取值,然后放到不同文件中存儲。
創建表
create table bucket_table(id string) clustered by(id) into 4 buckets;
加載數據
set hive.enforce.bucketing = true;
insert into table bucket_table select name from stu;
insert overwrite table bucket_table select name from stu;
數據加載到桶表時,會對字段取hash值,然后與桶的數量取模。把數據放到對應的文件中。
抽樣查詢
select * from bucket_table tablesample(bucket 1 out of 4 on id);
- 視圖的創建
create view v1 AS select * from t1;
- 表的操作
表的修改
Alter table target_tab add columns(cols,string);
表的刪除
Drop table;
- 導入數據
當數據被加載至表中時,不會對數據進行任何轉換。Load 操作只是將數據復制/移動至 Hive 表對應的位置。
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE]
INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)]
把一個Hive表導入到另一個已建Hive表
INSERT OVERWRITE TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement FROM from_statement
CTAS
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
(col_name data_type, ...) …
AS SELECT …
例:create table new_external_test as select * from external_table1;
- 表的查詢
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] | [ORDER BY col_list] ]
[LIMIT number]
基於Partition的查詢
一般 SELECT 查詢是全表掃描。但如果是分區表,查詢就可以利用分區剪枝(input pruning)的特性,類似“分區索引“”,只掃描一個表中它關心的那一部分。Hive 當前的實現是,只有分區斷言(Partitioned by)出現在離 FROM 子句最近的那個WHERE 子句中,才會啟用分區剪枝。例如,如果 page_views 表(按天分區)使用 date 列分區,以下語句只會讀取分區為‘2008-03-01’的數據。
SELECT page_views.* FROM page_views WHERE page_views.date >= '2013-03-01' AND page_views.date <= '2013-03-01'
LIMIT Clause
Limit 可以限制查詢的記錄數。查詢的結果是隨機選擇的。下面的查詢語句從 t1 表中隨機查詢5條記錄:
SELECT * FROM t1 LIMIT 5
Top N查詢
下面的查詢語句查詢銷售記錄最大的 5 個銷售代表。
SET mapred.reduce.tasks = 1
SELECT * FROM sales SORT BY amount DESC LIMIT 5
- 表的連接
導入ac信息表
hive> create table acinfo (name string,acip string) row format delimited fields terminated by '\t' stored as TEXTFILE;
hive> load data local inpath '/home/acinfo/ac.dat' into table acinfo;
內連接
select b.name,a.* from dim_ac a join acinfo b on (a.ac=b.acip) limit 10;
左外連接
select b.name,a.* from dim_ac a left outer join acinfo b on a.ac=b.acip limit 10;