日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

postgres 把一个表的值转成另一个表的字段名_Phoenix系列创建Phoenix映射表

發布時間:2023/12/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 postgres 把一个表的值转成另一个表的字段名_Phoenix系列创建Phoenix映射表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目前,在公司小部分的業務場景中有用到 Phoenix,但也僅限基于 Phoenix 的二級索引機制來進行查詢上的優化。雖然使用的頻次不大,但偶爾用到時,有些語句的使用方式和注意事項總記不太熟,每次都需要一頓谷歌和百度,然后從五花八門的文章中攝取著自己需要的信息。

本文是 Phoenix 系列的第一篇文章,我打算從 Phoenix 映射表的創建開始說起。Phoenix 映射表的創建雖然看起來很簡單,但其中的細節和潛在的坑著實也不少,且容我慢慢道來。

本文詳細記錄了 Phoenix 映射表的基本創建方式,以及我自己額外的一些思考和測試,如果文章中有描述不當的地方,還望大家多多指教,也歡迎大家在留言區踴躍發言。

1. 我的軟件環境

在開始正式介紹之前,還是先來說明下我 Phoenix 的版本。文中涉及到的關于 Phoenix 的使用小示例,基于的版本分別是PHOENIX-4.14.0-cdh5.13.2和PHOENIX-5.0.0-cdh6.2.0,其中兩個 Phoenix 對應的 HBase 的版本分別是HBase 1.2.0-cdh5.13.1和HBase 2.1.0-cdh6.3.1。如果沒有特別的說明,所選示例在兩個版本中運行方式以及結果是一樣的。

2. 關于 Phoenix

Phoenix 是一款優秀的基于 HBase 的數據庫中間件,由 Apache 官方出品,圈內共識,Apache 出品,必屬精品,當然,爛尾的除外哈。Phoenix 把用戶輸入的 SQL 語句翻譯成 HBase 底層的查詢 API,簡化了 HBase 客戶端的查詢方式,讓用戶可以使用標準的 SQL 語句來查詢 HBase 表里的數據。配合 Phoenix 的二級索引機制,Phoenix 可以實現更加方便和復雜的 HBase 數據查詢場景。有關 Phoenix 更深入的介紹,可以前往其官網查看。http://phoenix.apache.org/

3. 在 Phoenix 中創建不存在的 HBase 表的映射表

Phoenix 創建表的語句與 MySql 的語法有點相似,但需要關注的細節也有很多。

create?table?"user"(
???"?id"?VARCHAR?PRIMARY?KEY,
????"info"."name"?VARCHAR,
????"info"."age"?VARCHAR)
?column_encoded_bytes=0;

把上述建表語句 copy 到 Phoenix 的 shell 下,運行后查看我們創建的表的信息。

同時,在 HBase 的 default 命名空間中,也自動創建出了一張名叫 user 的表。

跟以普通方式創建的 HBase 表相比,除了常規的表描述信息之外,Phoenix 創建的表還多了一些協處理器等的描述信息。望文生義,這些協處理器大致與 Scan、索引創建等等操作有關。

讓我們再來解讀下這個簡單的建表語句,“user”是表名,id 作為主鍵,也即是 HBase 表中的 RowKey,“info”最終在 HBase 中體現為表的列簇,“name","age"就是表的字段名,緊隨其后的是列的類型,統一都是 VARCHAR,也即字符串,字段名默認可以為空,如果強制不為空,則為其加上 NOT NULL。"id"因為要作為 RowKey,所以一定不能是空的。最后一行 column_encoded_bytes=0 表示需要禁用列映射規則,否則會降低查詢性能,所以一般情況下這里都置為 0。

到這里大家也許會發現,表名、字段名、列簇名都被引號包括,如果我不指定引號呢?讓我們先刪除表,然后重新運行如下的建表語句:

刪除表的操作是 drop table "user",如果待刪除的表不存在,就會拋出異常,如果想要避免表不存在的異常,則需要加上表是否存在的判斷,即運行 drop table if exists "user"。刪除表的同時,底層映射的 HBase 表也一同被刪除,這絕對是你刪庫跑路的利器,所以生產環境下還是謹慎使用吧。

create?table?user(
???id?VARCHAR?PRIMARY?KEY,
????info.name?VARCHAR,
????info.age?VARCHAR)
?column_encoded_bytes=0;

然后查看下我們重新創建的表:

首先我們的表名被轉成了大寫,再 select 下數據。

查看下 HBase 表:

如上圖所示,引號的作用應該很明顯了吧,Phoenix 中表名、列簇名、字段名如果不加引號,會被默認轉成大寫。

4. 在 Phoenix 中創建存在的 HBase 表的映射表

接著,我們刪除剛剛創建的 user 表。再來嘗試如下的建表方式。首先在 HBase 的命令行下創建一張名叫 user 的表,其列簇是 info,create user,info 。此時 user 表就是一個普普通通的 HBase 表,然后運行如下建表語句:

create?table?"user"(
???id?VARCHAR?PRIMARY?KEY,
????info.name?VARCHAR,
????info.age?VARCHAR)
?column_encoded_bytes=0;

上述建表語句中我故意把 user 加引號,是為了確保在 Phoenix 中創建的表就是小寫的名字,而不會在 HBase 中重新生成一張名叫 USER 的表。運行完查看下我們的 HBase 表。多了一個名叫 INFO 的列簇。所以,我們只有嚴格保證這些大小寫一一對應,才能保證 Phoenix 表與 HBase 確立正確一致的映射關系,重新運行如下建表語句。

create?table?"user"(
???"?id"?VARCHAR?PRIMARY?KEY,
????"info"."name"?VARCHAR,
????"info"."age"?VARCHAR)
?column_encoded_bytes=0;

所以,我們可以先提前創建 HBase 表,再去創建該表的 Phoenix 映射表,保證大小寫一一對應,同樣可以達到如小節 3 中的效果。

5. 創建帶有 schema 的 Phoenix 表

直接運行如下建表語句:

create?table?"person"."user"(
???"?id"?VARCHAR?PRIMARY?KEY,
????"info"."name"?VARCHAR,
????"info"."age"?VARCHAR)
?column_encoded_bytes=0;

如果這個名叫 person 的 schema 不存在就會遇到建表的異常。

運行 create schema "person"來創建 schema,同樣需要注意大小寫。能正確創建 schema 的前提是需要在 HBase 的服務端和 Phoenix 的客戶端增加如下配置:

<property>
????????<name>phoenix.schema.isNamespaceMappingEnabledname>
????????<value>truevalue>
property>
<property>
????????<name>phoenix.schema.mapSystemTablesToNamespacename>
????????<value>truevalue>
property>

schema 創建完成之后,我們的表就能被正常創建了,Phoenix 的表創建完畢后,HBase 中會自動創建名為 person 的 namespace 和名為 person:user 的表。

6. 創建 Phoenix 表指定預分區

默認情況下創建的 Phoenix 表映射的 HBase 底層表只有一個分區,但是如果你的表數據很大,導數據時一個分區能把你急的肝疼。創建 Phoenix 表時預分區的方法有兩種,一種是提前創建一個具有預分區的 HBase 表,然后再創建 Phoenix 表來映射已經存在的表;另一種則是創建 Phoenix 表的同時指定好預分區的信息。

示例語句如下:

?create?table?"person"."user"(
???"id"?VARCHAR?PRIMARY?KEY,
????"info"."name"?VARCHAR,
????"info"."age"?VARCHAR)?column_encoded_bytes=0
????SPLIT?ON?('1','2','3','4','5','6','7','8','9');

然后在 HBase 的表監控界面上,你就可以看到如下的分區信息:

還有一種比較糟糕情況是,你的 HBase 表提前創建好了,大量數據也導入了表中,此時你才想起來需要創建 Phoenix 表。在大量數據存在的前提下,在 Phoenix shell 中直接創建映射表,十有八九會遇到客戶端超時的異常,貌似不太影響使用,只是不知道會不會數據映射不完整。目前對于這種情況還沒找到合適的解決辦法,只能在創建表的開始階段就好好規劃下是否需要創建 Phoenix 表以及創建表時的預分區等,盡量避免出現這樣的尷尬狀況。

7. 各種數據寫入后的映射情況

在這一小節里將說明 HBase 的各種寫入方式寫入的數據能否在 Phoenix 中正常綁定,以及 Phoenix 端數據寫入后能否在 HBase 表中順利查到。

對于 HBase 的數據寫入方式,我在這里主要分成 bulkload 和普通的 hbase client api 寫入,首先來測試下 client api 的數據寫入方式,簡單起見我直接在 shell 下 put 一些數據。

再來查看 Phoenix 中的數據,數據正常綁定。

接著測試在 phoenix 表插入一些數據,然后觀察 HBase 的數據變化。

?upsert?into?"person"."user"?("id","name","age")?values('2',?'leo2','17');

就不貼圖了,Phoenix 和 HBase 兩邊的數據是一一對應的。

那繼續來測試 bulkload 的方式導入數據,然后觀察 Phoenix 和 HBase 兩邊的數據情況吧!

測試之前,我們先用truncate_preserve 'person:user'命令清空 user 表里的數據。

準備一些測試數據,然后上傳至 hdfs 的某一個測試目錄。

使用如下命令先把 csv 文件轉換成 hfile:

hbase?org.apache.hadoop.hbase.mapreduce.ImportTsv?-Dimporttsv.separator=","?-Dimporttsv.bulk.output=/user/leo_jie/user_test_hfile?-Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:age?person:user?/user/leo_jie/user_test.csv

繼續運行如下命令,以 bulkload 的方式把數據導入 person:user 表里:

hbase?org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles?-Dcreate.table=no?/user/leo_jie/user_test_hfile?person:user

以上命令成功運行結束后我們來檢查下 HBase 和 Phoenix 兩邊的數據:HBase:

Phoenix:

上述的測試是為了說明,數據不同的寫入方式對 HBase 和 Phoenix 兩邊的數據綁定是否有不同的影響,而目前看來,似乎沒有什么特殊的地方。后續還會測試數據不同的寫入方式,對 Phoenix 索引數據的影響,在那種場景下,還會是一樣的結果嗎?讓我們拭目以待!

8. 創建多個列簇 Phoenix 映射表

這一小節補充下多列簇 Phoenix 映射表的創建,直接上建表語句:

create?table?"person"."user2"(
????"id"?VARCHAR?PRIMARY?KEY,
????"info"."name"?VARCHAR,
????"info"."age"??VARCHAR,
????"info2"."name"?VARCHAR,
????"info2"."age"?VARCHAR,
????"info2"."address"?VARCHAR)
?column_encoded_bytes=0;

以 put 的方式插入一些數據,然后在 Phoenix 中做以下查詢:

對于所屬不同列簇但名稱相同的字段的查詢,一定要顯示指定字段所屬的列簇名,不然查詢時會報異常。除此之外,跟單列簇創建方式相比,倒也沒啥特別之處了。

9. Phoenix 視圖

類似 MySql 等關系型數據庫中的視圖,Phoenix 也有自己的視圖概念,其視圖的創建方式與表的創建語句類似。如果單純只是為了查詢數據,強烈建議為 HBase 表創建 Phenix 的視圖映射,此時視圖的刪除對 HBase 的源表不會造成任何影響。

之前在倒騰 Phoenix 視圖的時候,頻繁遇到各種各樣的報錯,直至現在,對于其中的有些異常,依舊不明就里。下面先直接演示能正確創建視圖的語句吧!

首先創建一張 HBase 表,create 'USER','INFO'不要為這張表創建其 Phoenix 映射表,然后運行如下創建視圖的語句。

create?view?USER(
ID?VARCHAR?PRIMARY?KEY,
INFO.NAME?VARCHAR,
INFO.AGE?VARCHAR);
view

在 HBase 中插入一些數據,觀察視圖中的數據是否會實時更新。答案是,在 HBase 中插入數據,Phoenix 視圖會實時更新數據。

那么以 bulkload 的方式更新數據呢?根據上文中提到的測試方法,我們再來實施一下。答案是,以 bulkload 的方式把數據導入 HBase 中,Phoenix 依舊會實時更新數據。

反過來,我們是否可以在 Phoenix 中 upset 數據呢?

?upsert?into?USER?(ID,NAME,AGE)?values('111',?'leo111','17');
upsert

視圖是只讀的,不能做修改之類的操作。此時刪掉視圖,對 HBase 源表是沒有影響的。

drop view USER;

scan 'USER'

再來說明一下當初折騰視圖時遇到的各種各樣的異常。

「HBase 源表不存在而直接創建視圖」

error1

看來 Phoenix 視圖創建跟 Phoenix 表創建有很大不同啊。

「HBase 源表存在且 Phoenix 映射表也存在」

刪除掉原來的測試表,然后直接用創建 Phoenix 表的方式,同時創建出 HBase 的源表。

create?table?USER(
ID?VARCHAR?PRIMARY?KEY,
INFO.NAME?VARCHAR,
INFO.AGE?VARCHAR)
column_encoded_bytes=0;

此時我們再來運行視圖創建語句。

create?view?USER(
ID?VARCHAR?PRIMARY?KEY,
INFO.NAME?VARCHAR,
INFO.AGE?VARCHAR);

如果直接運行這個語句,不出意外一定會報錯,報錯信息如下:Error: ERROR 1036 (42J04): Cannot modify the primary key of a VIEW if last PK column of parent is variable length. columnName=USER.ID (state=42J04,code=1036)

table 的名字是 USER,view 的名字也是 USER,但這真的是報錯的根本原因嗎?那讓我們換一個名字來試試看。

create?view?USER_VIEW(
ID?VARCHAR?PRIMARY?KEY,
INFO.NAME?VARCHAR,
INFO.AGE?VARCHAR);

繼續報錯:

Error: ERROR 505 (42000): Table is read only. (state=42000,code=505),又回到了我們剛開始的異常,HBase 源表不存在而直接創建視圖。這時候如果你一頓谷歌加百度,十有八九會遇到類似這樣的視圖創建語句。

create?view?USER_VIEW(
ID?VARCHAR?PRIMARY?KEY,
INFO.NAME?VARCHAR,
INFO.AGE?VARCHAR)?as?select?*?from?USER;

指定查詢數據集,也就是 select 的語句,再映射到視圖 USER_VIEW 上,依舊報錯:

Error: ERROR 1036 (42J04): Cannot modify the primary key of a VIEW if last PK column of parent is variable length. columnName=USER_VIEW.ID (state=42J04,code=1036)

聰明的你一定會這樣修改上述的語句。

?create?view?USER_VIEW?as?select?*?from?USER;

這樣的創建語句其實很類似 hive 還有其他的一些關系型數據庫。如果,你還想創建指定列的視圖呢?

?create?view?USER_VIEW_NAME?as?select?NAME?from?USER;

你以為這樣寫就可以了嗎?臉黑的我又遇見了這樣的報錯。

Error: ERROR 604 (42P00): Syntax error. Mismatched input. Expecting "ASTERISK", got "NAME" at line 1, column 38. (state=42P00,code=604)

百度了一波,從大佬的博客里了解到,目前在 Phoenix 創建視圖時,子句中不能選擇字段,只能用*號,否則就會報如上錯誤。

是否可以創建語法更復雜的視圖呢?例如,我已經有了一張 USER 表,再創建一張 PAY 表,記錄每個用戶的花銷。然后以 JOIN 的方式創建視圖 USER_PAY_VIEW。

left join

當前版本的視圖支持的語法比較有限,SELECT 中不能有復雜的語法,否則解析時會無法判斷結束標記。

視圖使用時,一定要注意,在沒有創建索引的情況下,不要瞎寫 SQL 語句,什么 group by,order by。否則一旦表里的數據量過大,你十有八九能遇到全表掃描,嚴重情況下影響線上業務。這樣的規則,對表的查詢同樣適用。

10. 最后

最后來總結一下 Phoenix 的常規使用吧。Phoenix 表創建時要注意大小寫,如果需要使用小寫,那么請給表名,列簇名,字段名加上英文類型的雙引號;如果你的 HBase 表數據量過大,創建表時,請盡可能提前把對應的 Phoenix 映射表也創建出來吧,最后再導入數據;針對建表時的預分區操作,文中也提到了兩種方式。如果對表僅有查詢需要,那么請考慮創建視圖,但視圖的使用又有很大的限制,使用不當就會導致全表掃描,不僅影響查詢效率,還會影響線上的業務。

11. 參考鏈接

  • https://blog.csdn.net/github_39577257/article/details/95968727

據說,關注我的人都找到了對象?

總結

以上是生活随笔為你收集整理的postgres 把一个表的值转成另一个表的字段名_Phoenix系列创建Phoenix映射表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。