hive原本不是用來做簡單的crud的,但有時候我們就是有可能這么干,怎么辦呢?
hive 還是提供了相應的功能的,查詢是最必須的,就無須多說了。
插入數據一般來說都是大批量的插入,一般用於從源數據中導入數據到hive中,然后經過hive加工后,寫入到一張新的結果表。而這個表的數據一般也會很大,具體看業務復雜性。
更新數據一般是不會被支持的,尤其是想更新某一條數據,但我們可以通過重新刷入數據的方式,達到更新數據的目的。一般hive表會有相應的分區要求,這樣就可以做一定程度上的數據索引效果,以及減少大數據的量。而其底層存儲為一個分區,一系列分組文件。
刪除數據就更是沒有了,不過與更新數據一樣的道理,我們可以通過重新進行數據加工,刷入新數據集即可完成刪除的目的。不過,要想剔除其中一條數據,這個加工邏輯得好好想想了。
1. select查詢
這個最復雜的,也是最核心的。基本遵循sql92協議,也就是說基本上你會寫sql, 就可以搞hive了。差別在於,hive會有很多自己支持的數據結構,以及很多特有的函數調用。另外,就是可以很方便地讓用戶自定義一些函數,以便滿足業務需求。即udf. 因此,如果你不清楚這些udf如何使用,那么你就缺失了這方面的技能了。
舉一個例子說明即可:
with a as ( select * from test_001 where pt='20210101' ), b as ( select * from test_002 where pt='20200101' ) select trim(a.name) name, a.t_map['field1'] map_f1, COALESCE(t1.f2, t2.f2) f2, case when t1.money>1000 then 'G' else 'H' end from a join b on a.uid = b.uid
總之一句話,你可以用sql表達非常復雜的業務邏輯。比如數據開發同學的重要利器就是這玩意。從一定角度上說,sql也是一門編程開發語言!驕傲了!
2. insert數據插入
hive之類的大數據處理工具,一般只會支持大批量的插入。為什么呢?因為它的底層存儲就是一個個地大文件,方便實現啊,效率高啊啥的!所以,一般地,又會多出來一個概念,分區!因為是一個個地文件,在處理的時候,能做確定數據在哪個文件上,那么它效率就會很高了。
而像關系型數據庫的索引之類的東西,這些大數據工具就不太方便有了,為什么呢?因為有大量的數據存儲着,如果想要專門去建立索引,那么這個存儲成本啊運算成本啊啥的,肯定就上去了。而最后可能還沒有啥收益,因為我們更多地是做離線分析,並非差那幾秒的性能,所以干脆不要了。
先來看幾個map類型的數據操作方式:
-- 一個泛型的map, 只要給定的值類型正確,就會得到正確類型的map了 -- map<string,string>, map<string,double>, map<string,int> map('k', 'v1'); map('k', v1); map('k', v1); -- 將字符串轉換為map形式,需要自行定義明確的分隔符 -- 注意,json並不能很好地轉換為map形式 -- 以下結果為: {"\"b\"":"2}","{\"a\"":"\"1\""} select str_to_map('{"a":"1","b":2}') from dual; -- 以下結果為: {"a":"","b":"2"} select str_to_map('a:,b:2') from dual; -- 以下結果為: {"a":"1","b":"2"} select map('a','1','b','2') from dual; 接下來,我們來看下數據插入方式: -- 從加工數據集中寫入全量表 insert into table xxx select k1,k2,k3 from a_xxx; -- 從加工數據集中覆蓋式寫入全量表 insert overwrite table xxx select * from a_xxx; insert into table xxx partition(pt='xxx') select k1,k2,k3 from a_xxx; insert into table xxx partition(pt='xxx') select k1,k2,k3 from a_xxx; -- 將加工結果集創建一個新表寫入 create table tableName ROW FORMAT delimited fields terminated by ',' stored as textfile as with a as (select * from t1 where pt='xxx') select a.uid from a -- 插入一條條單獨的記錄 insert into values (v11, v12, v13), (v22, v22, v23); -- 另外一種插入單條記錄的方式,從虛表中選擇常量集 insert into table xxx select k1,k2,k3 from dual;
3. 數據更新
update數據與delete數據同sql標准協議,並無二致,但需要hive版本大於 0.14,且需要開啟相應選項才可以。即需要支持hive的事務特性。
-- update數據與delete數據同sql標准協議 UPDATE tablename SET column = value [, column = value ...] [WHERE expression] DELETE FROM tablename [WHERE expression]
4. 創建表操作
創建表的方式與sql標簽協議一致,只是有些特有類型可以使用,比如 map, struct...
-- 創建數據庫 CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [MANAGEDLOCATION hdfs_path] [WITH DBPROPERTIES (property_name=property_value, ...)]; -- 刪除數據庫 DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE]; -- 創建表 CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name -- (Note: TEMPORARY available in Hive 0.14.0 and later) [(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] [SKEWED BY (col_name, col_name, ...) -- (Note: Available in Hive 0.10.0 and later)] ON ((col_value, col_value, ...), (col_value, col_value, ...), ...) [STORED AS DIRECTORIES] [ [ROW FORMAT row_format] [STORED AS file_format] | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)] -- (Note: Available in Hive 0.6.0 and later) ] [LOCATION hdfs_path] [TBLPROPERTIES (property_name=property_value, ...)] -- (Note: Available in Hive 0.6.0 and later) [AS select_statement]; -- (Note: Available in Hive 0.5.0 and later; not supported for external tables) CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table_or_view_name [LOCATION hdfs_path]; data_type : primitive_type | array_type | map_type | struct_type | union_type -- (Note: Available in Hive 0.7.0 and later) primitive_type : TINYINT | SMALLINT | INT | BIGINT | BOOLEAN | FLOAT | DOUBLE | DOUBLE PRECISION -- (Note: Available in Hive 2.2.0 and later) | STRING | BINARY -- (Note: Available in Hive 0.8.0 and later) | TIMESTAMP -- (Note: Available in Hive 0.8.0 and later) | DECIMAL -- (Note: Available in Hive 0.11.0 and later) | DECIMAL(precision, scale) -- (Note: Available in Hive 0.13.0 and later) | DATE -- (Note: Available in Hive 0.12.0 and later) | VARCHAR -- (Note: Available in Hive 0.12.0 and later) | CHAR -- (Note: Available in Hive 0.13.0 and later) array_type : ARRAY < data_type > map_type : MAP < primitive_type, data_type > struct_type : STRUCT < col_name : data_type [COMMENT col_comment], ...> union_type : UNIONTYPE < data_type, data_type, ... > -- (Note: Available in Hive 0.7.0 and later) row_format : DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] [NULL DEFINED AS char] -- (Note: Available in Hive 0.13 and later) | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)] file_format: : SEQUENCEFILE | TEXTFILE -- (Default, depending on hive.default.fileformat configuration) | RCFILE -- (Note: Available in Hive 0.6.0 and later) | ORC -- (Note: Available in Hive 0.11.0 and later) | PARQUET -- (Note: Available in Hive 0.13.0 and later) | AVRO -- (Note: Available in Hive 0.14.0 and later) | JSONFILE -- (Note: Available in Hive 4.0.0 and later) | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname column_constraint_specification: : [ PRIMARY KEY|UNIQUE|NOT NULL|DEFAULT [default_value]|CHECK [check_expression] ENABLE|DISABLE NOVALIDATE RELY/NORELY ] default_value: : [ LITERAL|CURRENT_USER()|CURRENT_DATE()|CURRENT_TIMESTAMP()|NULL ] constraint_specification: : [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ] [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ] [, CONSTRAINT constraint_name FOREIGN KEY (col_name, ...) REFERENCES table_name(col_name, ...) DISABLE NOVALIDATE [, CONSTRAINT constraint_name UNIQUE (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ] [, CONSTRAINT constraint_name CHECK [check_expression] ENABLE|DISABLE NOVALIDATE RELY/NORELY ] -- 刪除表 DROP TABLE [IF EXISTS] table_name [PURGE]; -- 表更名 ALTER TABLE table_name RENAME TO new_table_name; -- 添加分區 ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location'][, PARTITION partition_spec [LOCATION 'location'], ...]; -- 刪除分區 ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec IGNORE PROTECTION;
本部分內容參考官網: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL
5. 總結
hive中對於數據類型要求還是比較嚴的,實際上大部分的關系型數據庫對類型要求都還是比較嚴的(mysql除外,它幾乎可以使用string型類型插入任意字段)。
在對數據進行插入操作時,需要注意數據類型,必要時做轉換,如果不能做轉換那么就需要換一種寫法了。不過好在,hive對於簡單類型的判定並不太嚴,比如 '1'與1 是相等的, 1.0 和 '1.0' 也都是可以的。而當我們使用presto進行操作時,則不會被支持,其要求的類型更嚴格。
總之,針對每種類型的數據庫,都有其特有的要求,我往往都需要為各自做相應的適配。所謂的標准協議,也只能從一定程度上約束大家的行為。但也已經非常不錯了,至少大家是在標准的周圍,擴展特有的能力,以滿足不同的業務場景。