LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
LOCAL
關鍵字表明從本地文件系統加載文件,省略則表明從 HDFS 上加載文件:從本地文件系統加載文件時, filepath
能夠是絕對路徑也能夠是相對路徑 (建議使用絕對路徑);node
從 HDFS 加載文件時候,filepath
爲文件完整的 URL 地址:如 hdfs://namenode:port/user/hive/project/ data1
git
filepath
能夠是文件路徑 (在這種狀況下 Hive 會將文件移動到表中),也能夠目錄路徑 (在這種狀況下,Hive 會將該目錄中的全部文件移動到表中);github
若是使用 OVERWRITE 關鍵字,則將刪除目標表(或分區)的內容,使用新的數據填充;不使用此關鍵字,則數據以追加的方式加入;sql
加載的目標能夠是表或分區。若是是分區表,則必須指定加載數據的分區;shell
加載文件的格式必須與建表時使用 STORED AS
指定的存儲格式相同。數據庫
使用建議:express
不管是本地路徑仍是 URL 都建議使用完整的。雖然可使用不完整的 URL 地址,此時 Hive 將使用 hadoop 中的 fs.default.name 配置來推斷地址,可是爲避免沒必要要的錯誤,建議使用完整的本地路徑或 URL 地址;apache
加載對象是分區表時建議顯示指定分區。在 Hive 3.0 以後,內部將加載 (LOAD) 重寫爲 INSERT AS SELECT,此時若是不指定分區,INSERT AS SELECT 將假設最後一組列是分區列,若是該列不是表定義的分區,它將拋出錯誤。爲避免錯誤,仍是建議顯示指定分區。app
新建分區表:oop
CREATE TABLE emp_ptn( empno INT, ename STRING, job STRING, mgr INT, hiredate TIMESTAMP, sal DECIMAL(7,2), comm DECIMAL(7,2) ) PARTITIONED BY (deptno INT) -- 按照部門編號進行分區 ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";
從 HDFS 上加載數據到分區表:
LOAD DATA INPATH "hdfs://hadoop001:8020/mydir/emp.txt" OVERWRITE INTO TABLE emp_ptn PARTITION (deptno=20);
emp.txt 文件可在本倉庫的 resources 目錄中下載
加載後表中數據以下,分區列 deptno 所有賦值成 20:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement; INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;
Hive 0.13.0 開始,建表時能夠經過使用 TBLPROPERTIES(「immutable」=「true」)來建立不可變表 (immutable table) ,若是不能夠變表中存在數據,則 INSERT INTO 失敗。(注:INSERT OVERWRITE 的語句不受 immutable
屬性的影響);
能夠對錶或分區執行插入操做。若是表已分區,則必須經過指定全部分區列的值來指定表的特定分區;
從 Hive 1.1.0 開始,TABLE 關鍵字是可選的;
從 Hive 1.2.0 開始 ,能夠採用 INSERT INTO tablename(z,x,c1) 指明插入列;
能夠將 SELECT 語句的查詢結果插入多個表(或分區),稱爲多表插入。語法以下:
FROM from_statement INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 [INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2] [INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...;
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement; INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;
在向分區表插入數據時候,分區列名是必須的,可是列值是可選的。若是給出了分區列值,咱們將其稱爲靜態分區,不然它是動態分區。動態分區列必須在 SELECT 語句的列中最後指定,而且與它們在 PARTITION() 子句中出現的順序相同。
注意:Hive 0.9.0 以前的版本動態分區插入是默認禁用的,而 0.9.0 以後的版本則默認啓用。如下是動態分區的相關配置:
配置 | 默認值 | 說明 |
---|---|---|
hive.exec.dynamic.partition |
true |
須要設置爲 true 才能啓用動態分區插入 |
hive.exec.dynamic.partition.mode |
strict |
在嚴格模式 (strict) 下,用戶必須至少指定一個靜態分區,以防用戶意外覆蓋全部分區,在非嚴格模式下,容許全部分區都是動態的 |
hive.exec.max.dynamic.partitions.pernode |
100 | 容許在每一個 mapper/reducer 節點中建立的最大動態分區數 |
hive.exec.max.dynamic.partitions |
1000 | 容許總共建立的最大動態分區數 |
hive.exec.max.created.files |
100000 | 做業中全部 mapper/reducer 建立的 HDFS 文件的最大數量 |
hive.error.on.empty.partition |
false |
若是動態分區插入生成空結果,是否拋出異常 |
CREATE TABLE emp( empno INT, ename STRING, job STRING, mgr INT, hiredate TIMESTAMP, sal DECIMAL(7,2), comm DECIMAL(7,2), deptno INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"; -- 加載數據到 emp 表中 這裏直接從本地加載 load data local inpath "/usr/file/emp.txt" into table emp;
完成後 emp
表中數據以下:
emp_ptn
表中加載的數據:TRUNCATE TABLE emp_ptn;
emp
表中查詢部門編號爲 20 的員工數據,並插入 emp_ptn
表中,語句以下:INSERT OVERWRITE TABLE emp_ptn PARTITION (deptno=20) SELECT empno,ename,job,mgr,hiredate,sal,comm FROM emp WHERE deptno=20;
完成後 emp_ptn
表中數據以下:
-- 因爲咱們只有一個分區,且仍是動態分區,因此須要關閉嚴格默認。由於在嚴格模式下,用戶必須至少指定一個靜態分區 set hive.exec.dynamic.partition.mode=nonstrict; -- 動態分區 此時查詢語句的最後一列爲動態分區列,即 deptno INSERT OVERWRITE TABLE emp_ptn PARTITION (deptno) SELECT empno,ename,job,mgr,hiredate,sal,comm,deptno FROM emp WHERE deptno=30;
完成後 emp_ptn
表中數據以下:
INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES ( value [, value ...] )
更新和刪除的語法比較簡單,和關係型數據庫一致。須要注意的是這兩個操做都只能在支持 ACID 的表,也就是事務表上才能執行。
-- 更新 UPDATE tablename SET column = value [, column = value ...] [WHERE expression] --刪除 DELETE FROM tablename [WHERE expression]
1. 修改配置
首先須要更改 hive-site.xml
,添加以下配置,開啓事務支持,配置完成後須要重啓 Hive 服務。
<property> <name>hive.support.concurrency</name> <value>true</value> </property> <property> <name>hive.enforce.bucketing</name> <value>true</value> </property> <property> <name>hive.exec.dynamic.partition.mode</name> <value>nonstrict</value> </property> <property> <name>hive.txn.manager</name> <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value> </property> <property> <name>hive.compactor.initiator.on</name> <value>true</value> </property> <property> <name>hive.in.test</name> <value>true</value> </property>
2. 建立測試表
建立用於測試的事務表,建表時候指定屬性 transactional = true
則表明該表是事務表。須要注意的是,按照官方文檔 的說明,目前 Hive 中的事務表有如下限制:
CREATE TABLE emp_ts( empno int, ename String ) CLUSTERED BY (empno) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES ("transactional"="true");
3. 插入測試數據
INSERT INTO TABLE emp_ts VALUES (1,"ming"),(2,"hong");
插入數據依靠的是 MapReduce 做業,執行成功後數據以下:
4. 測試更新和刪除
--更新數據 UPDATE emp_ts SET ename = "lan" WHERE empno=1; --刪除數據 DELETE FROM emp_ts WHERE empno=2;
更新和刪除數據依靠的也是 MapReduce 做業,執行成功後數據以下:
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 [ROW FORMAT row_format] [STORED AS file_format] SELECT ... FROM ...
OVERWRITE 關鍵字表示輸出文件存在時,先刪除後再從新寫入;
和 Load 語句同樣,建議不管是本地路徑仍是 URL 地址都使用完整的;
寫入文件系統的數據被序列化爲文本,其中列默認由^A 分隔,行由換行符分隔。若是列不是基本類型,則將其序列化爲 JSON 格式。其中行分隔符不容許自定義,但列分隔符能夠自定義,以下:
-- 定義列分隔符爲'\t' insert overwrite local directory './test-04' row format delimited FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ',' MAP KEYS TERMINATED BY ':' select * from src;
這裏咱們將上面建立的 emp_ptn
表導出到本地文件系統,語句以下:
INSERT OVERWRITE LOCAL DIRECTORY '/usr/file/ouput' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' SELECT * FROM emp_ptn;
導出結果以下:
更多大數據系列文章能夠參見 GitHub 開源項目: 大數據入門指南