Kudu之SQL操作(KUDU&Impala基本操作)

參考文章:KUDU&Impala基本操作

使用impala對kudu進行DML操作

kudu insert data api

kudu官網impala操作kudu表

說明

通過Java client等其他方式在kudu中創建了某個表,要想對該表進行操作,需要在impala中創建外部表,將其映射到impala當中

SQL操作

通過impala對kudu進行sql操作

數據庫操作

--描述表
DESCRIBE tabel_name;
	
--查看分區情況
SHOW PARTITIONS table_name;
	
--查看當前使用數據庫
SELECT current_database();
	
--查看建表語句
SHOW CREATE TABLE table_name

創建數據庫(creat db)

--impala創建數據庫與hive一樣,create database db_name, 
--但是這個數據庫只是一個impala端的namespace,
--kudu官網中沒有提到數據庫的概念,猜測可能是沒有這個概念
--impala中創建表的時候比如在test數據庫中創建table_test對應在kudu中爲 test:table_test

--創建數據庫
CREATE DATABASE IF NOT EXISTS POC_TEST;

創建表(creat table)

創建表的注意事項

(0) 創建外部表,內部表

--創建外部表

--假設已經通過Java client等其他方式在kudu中創建了某個表,
--要想對該表進行操作,需要在impala中創建外部表,將其映射到impala當中,例如:
CREATE EXTERNAL TABLE my_mapping_table
	STORED AS KUDU
	TBLPROPERTIES('kudu.table_name' = 'my_kudu_table');

--創建內部表
  --假設要通過impala創建一個新的kudu表,需要在impala中創建一個內部表,例如:
CREATE TABLE  testinkudu(…………)
	partition  by hash  partitions  8
	STORED AS  KUDU [AS SELECT * FROM OTHER_TABLE];

--注:創建內部表時,類似partition by ………stored as kudu的分區聲明語句是必須的。
--無論是 通過client創建的kudu表還是通過impala創建的表,
--都可以在master節點的UI界面的tables選項中查看

Kudu中的分區方法主要有兩種:partition by hash和partition by range 

(1) Hash分區

-- 基於hash的分區方法的基本原理是:基於primary key的hash值將每個row劃分到相應的tablet當中,
-- 分區的個數即tablet的個數必須在創建表語句中指定
-- 如果未指定基於某個字段的hash值進行分區,默認以主鍵的hash值進行分區

--主鍵兩個字段,分區字段未指定 hash分區
create table kudu_first_table(
  id int,
  name string,
  age int,
  gender string,
  primary key(id,name)
) 
partition by hash partitions 4
stored as kudu;

--主鍵一個字段,分區字段未指定 hash分區
CREATE TABLE my_first_table
(
  id BIGINT,
  name STRING,
  PRIMARY KEY(id)
)
PARTITION BY HASH PARTITIONS 16
STORED AS KUDU;

--表不存在則創建, 主鍵一個字段, 分區字段未指定 hash分區
CREATE TABLE IF NOT EXISTS POC_TEST.sdc(
  id string,
  name string,
  PRIMARY KEY (id)
) 
PARTITION BY HASH(id) PARTITIONS 2
STORED AS KUDU;
TBLPROPERTIES('kudu.master_addresses'='master.msxf.hadoop:7051','kudu.num_tablet_replicas' = '1');

--主鍵兩個字段,分區字段指定,hash分區
create table specify_partition_column(
  id int,
  name string,
  age int,
  gender string,
  primary key(id,name)
) partition by hash(id) partitions 3
stored as kudu;

--主鍵兩個字段,分區字段指定一個字段,hash分區
create table specify_partition_one_column(
  id int,
  name string,
  age int,
  gender string,
  primary key(id)
) partition by hash(id) partitions 3
stored as kudu;

--區別:未指定分區字段時,其分區字段默認是主鍵,若主鍵有兩個列則分區字段爲兩個,指定分區字段時,
--   需要分區列是主鍵的子集;否則會報錯「 Only key columns can be used in PARTITION BY」
--不指定分區:表依然會創建,但是隻有一個分區,會提示「Unpartitioned Kudu tables are ineff

(2) range分區:主要針對時間進行range分區 

-- 基於range的分區方法的基本原理是:基於指定主鍵的取值範圍將每個row劃分到相應的tablet當中,
-- 用於range分區的主鍵以及各個取值範圍都必須在建表語句中聲明

CREATE TABLE cust_behavior (
  _id BIGINT PRIMARY KEY,
  salary STRING,
  edu_level INT,
  usergender STRING,
  `group` STRING,
  city STRING,
  postcode STRING,
  last_purchase_price FLOAT,
  last_purchase_date BIGINT,
  category STRING,
  sku STRING,
  rating INT,
  fulfilled_date BIGINT
)
PARTITION BY RANGE (_id)
(
  PARTITION VALUES < 1439560049342,
  PARTITION 1439560049342 <= VALUES < 1439566253755,
  PARTITION 1439566253755 <= VALUES < 1439572458168,
  PARTITION 1439572458168 <= VALUES < 1439578662581,
  PARTITION 1439578662581 <= VALUES < 1439584866994,
  PARTITION 1439584866994 <= VALUES < 1439591071407,
  PARTITION 1439591071407 <= VALUES
)
STORED AS KUDU;

--優勢:可以根據數據的具體情況建立分區,比如:建立2017年之前的分區,2017-2018,2018-2019,2019-2020,2020-2021,。。。
--劣勢:如果使用單級range分區的話,容易產生數據熱點問題(可混合hash分區使用)、
--    在range分區中,如果有不止一個字段作爲分區字段的話也可以,語法暫時不清楚;
--    如果插入一條主鍵的值不落在任何range區間時會插入失敗,並報錯

(3) 混合分區 

create table tw_details4(
  user_id string,
  event_date string,
  event string,
  properties string,
  customer_id int,
  project_id int,
  primary key(event_date,event,user_id)
  ) partition by hash(user_id) partitions 3, range(event_date)(
  partition values < '2017-01-01',
  partition '2017-01-01' <= values < '2018-01-01',
  partition '2018-01-01' <= values < '2019-01-01',
  partition '2019-01-01' <= values < '2020-01-01',
  partition '2020-01-01' <= values < '2021-01-01'
) stored as kudu;

--優勢:可以根據時間進行檢索,來減少需要scan的tablet,插入的時候不會只有一個tabletserver產生熱點

(4) CTAS方式創建表

CREATE TABLE kudu_ti_event_fact_copy 
  primary key(user_id,event_date)
  partition by hash(user_id) partitions 3
  stored as kudu
as select user_id,event_date,properties from auto3.ti_event_fact;

刪除表和刪除數據庫

DROP TABLE [表名];
 
DROP DATABASE [數據庫名];

刪除試圖 

DROP VIEW [視圖名];

插入(insert)

impala 允許使用標準 SQL 語句將數據插入 Kudu

--單行插入:
insert into my_first_table(time, uid, event_id, action_value) values(123,"v2", "123", 2)
insert into table1 values(v1,v2,v3)

-- 多行插入:
INSERT INTO my_first_table(time, uid, event_id, action_value) VALUES (1, "john"), (2, "jane"), (3, "jim");

-- 批量插入(Batch Insert)
--從 Impala 和 Kudu 的角度來看,通常表現最好的方法通常是使用 Impala 中的 SELECT FROM 語句導入數據
INSERT INTO my_kudu_table SELECT * FROM legacy_data_import_table;
insert into table1 select v1,v2,v3 from table2;

插入(upsert) 

--根據主鍵判定,若已經存在則更新,若不存在則插入
upsert into table1 values(v1,v2,v3) 

更新(update)

--單行更新
UPDATE my_first_table SET name="bob" where id = 3;

--批量更新
UPDATE my_first_table SET name="bob" where id > 2;

--where條件後面的column不是主鍵也可以,但是更改的範圍會擴大
--主鍵中不支持更改,只能刪除後重新添加
UPDATE kudu_first_table set age = 32 where id= 2;
UPDATE kudu_first_table set age = 31 where gender= 'female';

查詢操作

Impala String函數大全

更多參考官網 

--獲取某一天的時間(時間類型轉string類型,在截取時間)
select substr(cast(CREATE_DATE as string),1,10) 
  from CBEE_ELIST WHERE substr(cast(CREATE_DATE as string),1,10) = '2001-02-01'

刪除(delete)

DELETE FROM my_first_table WHERE id < 3;

更改表

--修改表名,修改的只是表在impala中的映射名
  alter table kudu_ti_event_fact_copy rename to kudu_ti_event_fact_copy_rename;

--修改kudu存儲的表名,但是不會改變在impala端的映射表名,也就是在impala中依然訪問更改之前的表名
  ALTER TABLE kudu_ti_event_fact_copy_rename
  SET TBLPROPERTIES('kudu.table_name' = 'kudu_ti_event_fact_copy');

--修改列屬性
  -- --**不支持---

--添加列
  alter table kudu_ti_event_fact_copy_rename add columns(method string,time_stamp string);

--刪除列
  ALTER table kudu_ti_event_fact_copy_rename drop column method;

--刪除分區
  ALTER TABLE range_partition_table DROP RANGE PARTITION VALUES < '2017-01-01';

--添加分區
  alter table range_partition_table add range partition values < '2017-01-01';

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章