oracle 临时表存在哪里_openGauss魔改PG?它能兼容Oracle的数据库表吗?
作者介紹
洪燁,openGauss Contributor,多年銀行業系統架構設計及DBA實戰經驗,《DB2數據庫內部解析與性能調優》作者。
openGauss的前世今生上一篇看到很多朋友留言對openGauss的歷史疑問較多,本文開頭就先把筆者道聽途說來的openGauss歷史作為雜談在這里聊聊。
華為數據庫最早誕生于運營商的需求,最初版本名稱為GMDB,后來基于PostgreSQL-XC進行整體改造,再配合自研的存儲引擎,發布了FusionInsight ?LibrA(天枰座),也就是大家聽過較多的MPPDB,目前官網上還能找到一些FusionInsight LibrA的資料。
同時在2015年,華為成立了另一項目組,純自研了一款與Oracle非常相似的數據庫,引擎名稱為Zenith。在2015-2016年左右,華為基于MySQL研發了一款云原生數據庫TaurusDB(這個時間段貌似有三款并行的數據庫產品)。
2018年左右,華為開始進行數據庫整合,對數據庫產品名定義為GaussDB。針對不同的場景,分為GaussDB 100(簡單OLTP場景,單節點架構,基于Zenith引擎)、GaussDB 200(OLAP及數倉場景,MPPDB架構,基于Libra引擎)、GaussDB 300(HTAP場景,分布式架構,貌似是基于PostgreSQL-XL改造)三個對外的產品,在2019年又進行了再次整合,將GaussDB 100、GaussDB 300合并,產品名稱變為GaussDB T(OLTP、HTAP場景)、GaussDB A(OLAP場景,原Gauss 200)。
之后又基于華為云整體策略,Zenith內核貌似是棄用了,啟用原Libra內核(內核名稱改成了軒轅),GaussDB A變成了目前的華為云上DWS服務,GaussDB T變成了GaussDB for openGauss服務,同時也將openGauss開源。由于openGauss是基于GMDB發展而來(也就是基于PostgreSQL的產品路線),所以命令行和元數據庫的信息看起來還是Postgres,不過底層的存儲引擎與PostgreSQL有不少改動
openGauss對Oracle表的兼容性驗證書接正傳,接著上一篇,本文繼續基于openGauss 1.0.0版本對于Oracle中數據庫表的兼容性進行驗證。
數據庫的邏輯對象總共包含表、索引、約束、視圖、序列、別名、函數、存儲過程等。
表是數據庫最基本的邏輯對象,也是作為承載數據的邏輯對象。在Oracle數據庫中,數據庫表分為堆表、臨時表、表壓縮、索引組織表、簇表、分區表以及嵌套表等7種類型。
一、堆表(heap table)
堆表是Oracle和openGauss默認表類型,堆表在數據寫入時無需考慮行存放的順序(按照寫入的時間先后順序存放),因此寫入速度較高,但由于是無序存放,讀取效率較低。在Oracle中,表的創建通常采用以下兩種方式,openGauss都可以兼容:
在語句中定義表的字段結構:例如create table test(id int),這種方式也是最常見的方式;在openGauss中,執行結果如下:
postgres=# CREATE TABLE T_HEAP_TABLE
(
ID NUMBER,
NAME VARCHAR2(32)
);
CREATE TABLE
通過select語句的查詢結果創建表:例如create table test as select * from tmp_table,openGauss中執行結果如下:
postgres=# CREATE TABLE T_HEAP_TABLE
AS
SELECT * FROM TMP_TEST;
INSERT 0 0
二、臨時表
臨時表可以理解為是一種特殊類型的表,用來保存臨時數據的一個數據庫對象。它只能存儲在臨時表空間,而非用戶的表空間,對臨時表的DML操作通常不記錄事務日志。
Oracle臨時表分為事務級臨時表和會話級臨時表。事務級臨時表的數據只保存在事務的生命周期中,會話級臨時表能支持會話的完整生命周期。對于這兩種級別的臨時表,openGauss都可以支持,實測結果如下:
1、事務級臨時表此類型的臨時表中的數據僅在事務過程中有效,當事務提交后,臨時表中的數據將被自動清除,但是臨時表的結構以及元數據還存儲在用戶的數據字典中。在事務結束后,最好顯式刪除臨時表,否則數據庫會殘留臨時表的表結構和元數據。
在語句中定義表的字段結構方式創建
postgres=# CREATE GLOBAL TEMPORARY TABLE T_TRANS_TMP
(
ID NUMBER,
NAME VARCHAR2(32)
) ON COMMIT DELETE ROWS;
CREATE TABLE
通過select語句的查詢結果創建表
postgres=# CREATE GLOBAL TEMPORARY TABLE T_TRANS_TMP ON COMMIT DELETE ROWS
AS
SELECT * FROM TMP_TEST;
INSERT 0 0
2、會話級臨時表會話級臨時表中的數據可以跨事務而存在,不過當該會話結束時,臨時表中的數據將隨著會話的結束而被丟棄。與事務級臨時表相同,在會話結束后,會話級臨時表的結構以及元數據還存儲在用戶的數據字典中,需顯式手動清除。
在語句中定義表的字段結構方式創建
postgres=# CREATE TEMPORARY TABLE T_CONN_TMP
(
ID NUMBER,
NAME VARCHAR2(32)
) ON COMMIT PRESERVE ROWS;
CREATE TABLE
通過select語句的查詢結果創建表
postgres=# CREATE TEMPORARY TABLE T_CONN_TMP ON COMMIT PRESERVE ROWS
AS
SELECT * FROM TMP_TEST;
INSERT 0 0
三、表壓縮
表壓縮是對表數據進行壓縮,達到節省空間的目的,壓縮對于數據裝載和DML操作有一定的CPU消耗。然而,這些消耗可以為I/O的減少而抵消。Oracle常用的壓縮方式有兩種:基礎壓縮以及OLTP壓縮。
1、基礎壓縮基礎壓縮只在direct path load的時候才會生效,對于普通的dml語句insert、update不會發生壓縮,openGauss可以支持基礎壓縮。
postgres=# create table t_compress (id number) compress;
CREATE TABLE
2、OLTP壓縮OLTP壓縮會對所有的DML生效,所以適用于OLTP系統。只有當新的block中的數據存放到達了閾值的時候才會引發塊內的壓縮操作,然后更多的數據加入到塊中,再一次達到閾值,整個block會重新壓縮,以達到最大程度的壓縮級別。
這個過程會一直重復,直到Oracle數據庫確定無法再從壓縮上獲得更高的效益。所以多數OLTP事務作用在壓縮的塊上面,會和未壓縮的表上擁有相同的性能。只有部分操作會引發塊內的壓縮動作。OLTP壓縮功能openGauss目前無法支持。
postgres=# create table t_oltp_compress (id number) compress for oltp;
ERROR:? syntax error at or near "for"
LINE 1: create table t_oltp_compress (id number) compress for oltp;
四、索引組織表
索引組織表是以索引的方式保存表的數據,數據根據主鍵的順序進行排列的,這樣就提高了訪問的速度。缺點是由于索引塊保存所有的字段的信息,就需要更多的葉子頁面來保存數據,數據量較大的時候會造成訪問效率降低。
此外,如果主鍵頻繁修改,對應的行也就需要磁盤位置頻繁修改,行需要在不同的塊之間相互移動。通常在以下情況,會考慮使用索引組織表:
表的寬度(即一行的數據長度)有限;
表的主鍵不會或極少更改;
表主要用于查詢,DML操作較少;
大部分的業務需求是根據主鍵查詢行中其它列上的信息。
openGauss目前版本不支持索引組織表,對于應用程序來說,索引組織表的使用方式與堆表并無差異。
postgres=# CREATE TABLE T_ORG_INDEX
(? ?
ID NUMBER,
NAME VARCHAR2(32),
PRIMARY KEY(ID)?
)organization index;?
ERROR:? syntax error at or near "organization index"
LINE 6: )organization index;
五、簇表
簇表也稱為Cluster,在沒有數據表和索引的時候,Cluster段是可以單獨存在的。依據一定的規則,如連接鍵(Join Key),可以將多個數據表數據保存在同一個段中。并且依據一定場景實現快速檢索連接。在openGauss中,無法兼容此功能。
postgres=# create cluster t_cluster (id number) size 600;
ERROR:? syntax error at or near "cluster"
LINE 1: create cluster t_cluster (id number) size 600;
在某些為了提高連接性能的情況下,可以考慮用列存與partial cluster key結合的方式替代,表定義中可以選取某一列或幾列設置為partial cluster key。
在導入數據時,按設置的列進行局部排序(默認每70個CU即420萬行排序一次),生成的CU會聚集在一起,即CU的min,max會在一個較小的區間內。當查詢時,where條件含有這些列時,可產生良好的過濾效果。
postgres=# CREATE TABLE WAREHOUSE
(
? ? W_WAREHOUSE_SK? ? ? ? ? ? INTEGER? ? ? ? ? ? ? ?NOT NULL,
? ? W_WAREHOUSE_ID? ? ? ? ? ? CHAR(16)? ? ? ? ? ? ? NOT NULL,
? ? W_WAREHOUSE_NAME? ? ? ? VARCHAR(20)? ? ? ? ? ? ? ? ? ?,
? ? PARTIAL CLUSTER KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID)
) WITH (ORIENTATION = COLUMN);
六、分區表
分區表是將一個大表按照一定的規則分解成多張具有獨立存儲空間的實體表。對于應用來說,邏輯上只有一個表,但在物理上這個表由多個物理分區組成。每個分區都是一個獨立的對象,可以獨自處理,也可以作為一個更大對象的一部分進行處理。分區表通常分為范圍分區、列表分區、哈希分區以及復合分區。
1、范圍分區范圍分區就是對數據表中的某個值的范圍進行分區,根據某個值的范圍,決定將該數據存儲在哪個分區上。如根據序號分區,根據業務記錄的創建日期進行分區等(聯通每個月的賬單記錄就用的分區表存儲)。在openGauss中,可以支持范圍分區。
postgres=# CREATE TABLE t_range_partition
? ( prod_id? ? ? ?NUMBER(6)??
? , cust_id? ? ? ?NUMBER??
? , time_id? ? ? ?DATE??
? , channel_id? ? CHAR(1)??
? , promo_id? ? ? NUMBER(6)??
? , quantity_sold NUMBER(3)??
? , amount_sold? ?NUMBER(10,2)??
)? PARTITION BY RANGE (time_id)??
(PARTITION sales_q1_2006 VALUES LESS THAN (TO_DATE('01-APR-2006','dd-MON-yyyy')) TABLESPACE pg_default, PARTITION sales_q2_2006 VALUES LESS THAN (TO_DATE('01-JUL-2006','dd-MON-yyyy')) TABLESPACE pg_default, PARTITION sales_q3_2006 VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy')) TABLESPACE pg_default, PARTITION sales_q4_2006 VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy'))? TABLESPACE pg_default );
CREATE TABLE??
2、列表分區列表分區是根據所有可能的值,指定應該插入相應的分區,openGauss當前版本無法支持列表分區。
postgres=# CREATE TABLE t_list_partition_table??
(id number,? ?
name varchar2(20),??
sales number(10, 2),??
state varchar2(2))??
PARTITION BY LIST (state)??
(PARTITION q1_northwest VALUES ('OR', 'WA'),??
PARTITION q1_southwest VALUES ('AZ', 'UT', 'NM'),??
PARTITION q1_northeast VALUES? ('NY', 'VM', 'NJ'),??
PARTITION q1_southeast VALUES ('FL', 'GA'),??
PARTITION q1_northcentral VALUES ('SD', 'WI'),??
PARTITION q1_southcentral VALUES ('OK', 'TX'));??
ERROR:? syntax error at or near "LIST"
LINE 6:? ? PARTITION BY LIST (state)??
3、散列分區散列(HASH)分區通過在分區鍵值上執行一個散列函數來說決定數據的物理位置。散列分區把記錄分布在比范圍分區更多的分區上,這減少了I/O爭用的可能性。openGauss當前版本無法支持散列(HASH)分區。
postgres=# CREATE TABLE t_hash_partition
(deptno NUMBER, deptname VARCHAR(32))??
PARTITION BY HASH(deptno)??
(PARTITION p1 TABLESPACE pg_default, PARTITION p2 TABLESPACE pg_default,??
PARTITION p3 TABLESPACE pg_default, PARTITION p4 TABLESPACE pg_default);? ?
ERROR:? syntax error at or near "HASH"
LINE 2:? ? ? PARTITION BY HASH(deptno)?
4、復合分區對于分區表來說,數據傾斜的問題通常是最頭疼的。為了解決這個問題,Oracle提供了復合分區的功能。復合分區是先使用范圍分區,然后在每個分區內再使用散列分區/列表分區的一種分區方法。不過目前版本openGauss無法支持復合分區。
postgres=# CREATE TABLE t_sub_partition
( dept_no number, country varchar2(20), sale_date date)? ?
PARTITION BY RANGE(sale_date)? ?
SUBPARTITION BY LIST(country)??
( PARTITION q1_2012 VALUES LESS THAN('2012-Apr-01')? ?
( SUBPARTITION q1_europe VALUES ('FRANCE', 'ITALY'),? ?
SUBPARTITION q1_asia VALUES ('INDIA', 'PAKISTAN'),? ?
SUBPARTITION q1_americas VALUES ('US', 'CANADA') ),? ?
PARTITION q2_2012 VALUES LESS THAN('2012-Jul-01')? ?
( SUBPARTITION q2_europe VALUES ('FRANCE', 'ITALY'),? ?
SUBPARTITION q2_asia VALUES ('INDIA', 'PAKISTAN'),? ?
SUBPARTITION q2_americas VALUES ('US', 'CANADA') ),? ?
PARTITION q3_2012 VALUES LESS THAN('2012-Oct-01')? ?
( SUBPARTITION q3_europe VALUES ('FRANCE', 'ITALY'),? ?
SUBPARTITION q3_asia VALUES ('INDIA', 'PAKISTAN'),? ?
SUBPARTITION q3_americas VALUES ('US', 'CANADA') ),? ?
PARTITION q4_2012 VALUES LESS THAN('2013-Jan-01')? ?
( SUBPARTITION q4_europe VALUES ('FRANCE', 'ITALY'),? ?
SUBPARTITION q4_asia VALUES ('INDIA', 'PAKISTAN'),? ?
SUBPARTITION q4_americas VALUES ('US', 'CANADA') ) );?
ERROR:? syntax error at or near "SUBPARTITION"
LINE 3: SUBPARTITION BY LIST(country)
七、嵌套表
嵌套表類似C語言中的結構體,可以把一個表結構定義為一個類型,在創建其他表的時候,可以將字段類型指向這個自定義類型。openGauss中可以通過create type進行嵌套表定義。
postgres=# CREATE TYPE t_type AS (f1 int, f2 text);
CREATE TYPE
postgres=# CREATE TABLE t_compfoo(a int, b t_type);
CREATE TABLE
總結總體而言,openGauss兼容Oracle常用表類型,索引組織表需要用集群索引方式進行改造。對于少數非常用數據類型,需要進行少量代碼改造,可采取下列替代方案進行替換。
表類型 | 是否兼容 | 備注 |
堆表 | 全部兼容 | |
臨時表 | 全部兼容 | |
表壓縮 | 部分兼容 | 支持普通壓縮模式,有DELTA、PREFIX、DICTIONARY、NUMSTR四種壓縮算法供選擇 |
索引組織表 | 不兼容 | 不支持 |
簇表 | 不兼容 | 不支持,部分情況可以考慮用partial cluster key替代 |
分區表 | 部分兼容 | 只支持范圍分區 |
嵌套表 | 功能兼容,但語法有部分改變 |
相關閱讀:
openGauss可替代Oracle嗎?從字段類型說起……
2020 DAMS中國數據智能管理峰會即將于10月30日在上海舉辦,部分精彩議題先睹為快:
騰訊《騰訊游戲大數據資產管理實戰:元數據管理與數據治理》
京東《京東EB級全域大數據平臺建設和治理之路》
阿里《大規模容器云基礎設施環境架構、管理與運維》
工商銀行《DevOps轉型的探索與實踐》
中國銀聯《從自研演進看分布式數據庫》
民生銀行《開源數據庫MySQL在民生銀行的應用實踐》
平安銀行《“傳統+互聯網”混合CMDB及運營中臺實踐》
中國聯通《大數據資產管理平臺的設計、研發、運營實踐》
AWS《基于數據湖構建云上的數據分析架構》
今日頭條《字節跳動數據治理實踐》
蘇寧《蘇寧大規模智能告警收斂與告警根因的實踐》
滴滴《萬億級消息隊列Kafka在滴滴的實踐》
總結
以上是生活随笔為你收集整理的oracle 临时表存在哪里_openGauss魔改PG?它能兼容Oracle的数据库表吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python列表、集合、字典、元祖用途_
- 下一篇: linux cmake编译源码,linu