01.29 2. HIVE 基本操作


2. HIVE 基本操作


2.1 create table

2.1.1 總述

l CREATE TABLE 創建一個指定名字的表。如果相同名字的表已經存在,則拋出異常;用戶可以用 IF NOT EXIST 選項來忽略這個異常。

l EXTERNAL 關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION),Hive 創建內部表時,會將數據移動到數據倉庫指向的路徑;若創建

外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的時候,內部

表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。

l LIKE 允許用戶複製現有的表結構,但是不復制數據。 l 用戶在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW

FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,用戶還

需要為表指定列,用戶在指定表的列的同時也會指定自定義的 SerDe,Hive 通過 SerDe

確定表的具體的列的數據。

l 如果文件數據是純文本,可以使用 STORED AS TEXTFILE。如果數據需要壓縮,使用 STORED AS SEQUENCE 。

l 有分區的表可以在創建的時候使用 PARTITIONED BY 語句。一個表可以擁有一個或者多個分區,每一個分區單獨存在一個目錄下。而且,表和分區都可以對某個列進行

CLUSTERED BY 操作,將若干個列放入一個桶(bucket)中。也可以利用 SORT BY 對數據進行排序。這樣可以為特定應用提高性能。

l 表名和列名不區分大小寫,SerDe 和屬性名區分大小寫。表和列的註釋是字符串。


目前在 hive 中常用的數據類型有:

BIGINT – 主要用於狀態,類別,數量的字段, 如

status/option/type/quantity

DOUBLE – 主要用於金額的字段, 如 fee/price/bid

STRING – 除上述之外的字段基本都使用 String, 尤其是 id 和日期時間這

樣的字段


2.1.3 基本例子

1、如果一個表已經存在,可以使用 if not exists

2、 create table xiaojun(id int,cont string) row format delimited fields terminated

by '\\005' stored as textfile;

terminated by:關於來源的文本數據的字段間隔符

如果要將自定義間隔符的文件讀入一個表,需要通過創建表的語句來指明輸入文件間隔符,

然後 load data 到這個表。

4、Alibaba 數據庫常用間隔符的讀取

我們的常用間隔符一般是 Ascii 碼 5,Ascii 碼 7 等。在 hive 中 Ascii 碼 5 用'\\005'表示,

Ascii 碼 7 用'\\007'表示,依此類推。

5、裝載數據

查看一下:Hadoop fs -ls

LOAD DATA INPATH '/user/admin/xiaojun/a.txt' OVERWRITE INTO TABLE xiaojun;

6、如果使用 external 建表和普通建表區別

A、指定一個位置,而不使用默認的位置。如:

create EXTERNAL table xiaojun(id int,cont string) row format delimited fields

terminated by '\\005' stored as textfile location '/user/admin/xiaojun/';

B、對於使用 create table external 建表完成後,再 drop 掉表,表中的數據還在文件系統

中。如:

hive> create EXTERNAL table xiaojun(id int,cont string) row format delimited

fields terminated by '\\005' stored as textfile;

hive> LOAD DATA INPATH '/user/admin/xiaojun' OVERWRITE INTO TABLE xiaojun;

hive> drop table xiaojun;

[admin@hadoop1 bin]$ ./hadoop fs -ls

hdfs://hadoop1:7000/user/hive/warehouse/xiaojun

Found 1 items

使用普通的建表 DROP 後則找不到

2.1.4 創建分區

HIVE 的分區通過在創建表時啟用 partition by 實現,用來 partition 的維度並不是實

際數據的某一列,具體分區的標誌是由插入內容時給定的。當要查詢某一分區的內容時可以

採用 where 語句,形似 where tablename.partition_key > a 來實現。

創建含分區的表。

命令原型:

CREATE TABLE page_view(viewTime INT, userid BIGINT,

page_url STRING, referrer_url STRING,

ip STRING COMMENT 'IP Address of the User')

COMMENT 'This is the page view table'

PARTITIONED BY(dt STRING, country STRING)

CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\\001'


外部表和內部表內部表由hive管理,外部表是hdfs管理,內部表存儲在hive/warehouse下,外部表存儲是在創建時用戶設置的,drop時,兩個表的元數據都會被刪除,外部表的表數據不被刪除,目錄文件還在。


6、如果使用external建表和普通建表區別A、指定一個位置,而不使用默認的位置。如:create EXTERNAL table xiaojun(id int,cont string) row format delimited fields terminated by '\\005' stored as textfile location '/user/admin/xiaojun/';B、對於使用create table external建表完成後,再drop掉表,表中的數據還在文件系統中。如:hive>create EXTERNAL table xiaojun(id int,cont string) row formatdelimited fields terminated by '\\005' stored as textfile; hive> LOADDATA INPATH '/user/admin/xiaojun' OVERWRITE INTO TABLE xiaojun; hive> drop table xiaojun; [admin@hadoop1bin]$ ./hadoop fs -ls hdfs://hadoop1:7000/user/hive/warehouse/xiaojunFound 1 items使用普通的建表DROP後則找不到版權聲明:

COLLECTION ITEMS TERMINATED BY '\\002'

MAP KEYS TERMINATED BY '\\003'

STORED AS SEQUENCEFILE;

查看錶名,部分匹配

SHOW TABLES 'page.*';

SHOW TABLES '.*view';

查看某表的所有 Partition,如果沒有就報錯:

SHOW PARTITIONS page_view;

查看某表結構:

DESCRIBE invites;

看分區內容

SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';

查看有限行內容,同 Greenplum,用 limit 關鍵詞

SELECT a.foo FROM invites a limit 3;

查看錶分區定義

DESCRIBE EXTENDED page_view PARTITION (ds='2008-08-08');

2.5 Load

HIVE 裝載數據沒有做任何轉換加載到表中的數據只是進入相應的配置單元表的位置移

動數據文件。純加載操作複製/移動操作。


3.1 語法

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename

[PARTITION (partcol1=val1, partcol2=val2 ...)]

Load 操作只是單純的複製/移動操作,將數據文件移動到 Hive 表對應的位置。

• filepath 可以是: o 相對路徑,例如:project/data1

hdfs://namenode:9000/user/hive/project/data1

• 加載的目標可以是一個表或者分區。如果表包含分區,必須指定每一個分區的分區名。

• filepath 可以引用一個文件(這種情況下,Hive 會將文件移動到表所對應的目錄中)或者是一個目錄(在這種情況下,Hive 會將目錄中的所有

文件移動至表所對應的目錄中)。

• 如果指定了 LOCAL,那麼: o load 命令會去查找本地文件系統中的 filepath。如果發現是相對

路徑,則路徑會被解釋為相對於當前用戶的當前路徑。用戶也可以

為本地文件指定一個完整的 URI,比如:

file:///user/hive/project/data1.

o load 命令會將 filepath 中的文件複製到目標文件系統中。目標文件系統由表的位置屬性決定。被複制的數據文件移動到表的數據

對應的位置。

• 如果沒有指定 LOCAL 關鍵字,如果 filepath 指向的是一個完整的 URI,hive 會直接使用這個 URI。 否則:

o 如果沒有指定 schema 或者 authority,Hive 會使用在 hadoop 配置文件中定義的 schema 和 authority,fs.default.name 指定

了 Namenode 的 URI。

o 如果路徑不是絕對的,Hive 相對於 /user/ 進行解釋。 o Hive 會將 filepath 中指定的文件內容移動到 table (或者

partition)所指定的路徑中。

• 如果使用了 OVERWRITE 關鍵字,則目標表(或者分區)中的內容(如果有)會被刪除,然後再將 filepath 指向的文件/目錄中的內容添加到表/

分區中。

• 如果目標表(分區)已經有一個文件,並且文件名和 filepath 中的文件名衝突,那麼現有的文件會被新文件所替代。

從本地導入數據到表格並追加原表

LOAD DATA LOCAL INPATH `/tmp/pv_2008-06-08_us.txt` INTO TABLE c02

PARTITION(date='2008-06-08', country='US')

從本地導入數據到表格並追加記錄

LOAD DATA LOCAL INPATH './examples/files/kv1.txt' INTO TABLE pokes;

從 hdfs 導入數據到表格並覆蓋原表

LOAD DATA INPATH

'/user/admin/SqlldrDat/CnClickstat/20101101/18/clickstat_gp_fatdt0/0'

INTO table c02_clickstat_fatdt1 OVERWRITE PARTITION (dt='20101201');

關於來源的文本數據的字段間隔符

如果要將自定義間隔符的文件讀入一個表,需要通過創建表的語句來指明輸入文件間隔符,

然後 load data 到這個表就 ok 了。

2.6 Insert

2.6.1 Inserting data into Hive Tables from queries

Insert 時,from 子句既可以放在 select 子句後,也可以放在 insert 子句前,下面兩句是

等價的

hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar,

count(*) WHERE a.foo > 0 GROUP BY a.bar;

hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(*) FROM invites

a WHERE a.foo > 0 GROUP BY a.bar;

hive 沒 有 直 接 插 入 一 條 數 據 的 sql , 不 過 可 以 通 過 其 他 方 法 實 現 : 假設有一張表 B 至少有一條數據,我們想向表 A(int,string)中插入一條數據,可以用下面 的 方 法 實 現 : from B insert table A select 1,'abc' limit 1; 我覺得 hive 好像不能夠插入一個記錄,因為每次你寫 insert 語句的時候都是要將整個表的值overwrite。我想這個應該是與 hive 的 storage layer 是有關係的,因為它的存儲層是 HDFS,插入一個數據要全表掃描,還不如用整個表的替換來的快些。

mysql 也可以從一個表中查詢數據插入到另一個表中,也可以一條數據的插入

Hive 不支持一條一條的用 insert 語句進行插入操作,也不支持 update 的操作。數據是以 load的方式,加載到建立好的表中。數據一旦導入,則不可修改。要麼 drop 掉整個表,要麼建立新的表,導入新的數據。


分享到:


相關文章: