達夢列儲存表(HUGE Table)

eric0435發表於2019-11-13

達夢資料庫中,表的資料儲存方式分為行儲存和列儲存。行儲存是以記錄為單位進行儲存的,資料頁面中儲存的是完整的若干條記錄;列儲存是以列為單位進行儲存的,每一個列的所有行資料都儲存在一起,而且一個指定的頁面中儲存的都是某一個列的連續資料。

Huge File System(檢查HFS)是達夢資料庫實現的,針對海量資料進行分析的一種高效、簡單的列儲存機制。列儲存表(也稱為HUGE表)就是建立在HFS儲存機制上的一種表。

HUGE表是建立在自己特有的表空間HTS(HUGE TABLESPACE,即HUGE表空間)上的。最多可建立32767個HUGE表空間,其相關資訊儲存在動態檢視V$HUGE_TABLESPACE中。

這個表空間與普通的表空間不同。普通的表空間,資料是透過段、簇、頁來管理的,並且以固定大小(4K、8K、16K、32K)的頁面為管理單位;而HUGE表空間是透過HFS儲存機制來管理的,它相當於一個檔案系統。建立一個HTS,其實就是建立一個空的檔案目錄(系統中有一個預設HTS,目錄名為HMAIN)。在建立一個HUGE表並插入資料時,資料庫會在指定的HTS表空間目錄下建立一系列的目錄及檔案。

HUGE表的儲存方式有以下幾個優點:
1. 同一個列的資料都是連續儲存的,可以加快某一個列的資料查詢速度;
2. 連續儲存的列資料,具有更大的壓縮單元和資料相似性,可以獲得遠優於行儲存的壓縮效率,壓縮的單位是區
3. 條件掃描藉助資料區的統計資訊進行精確過濾,可以進一步減少IO,提高掃描效率;
4. 允許建立二級索引;
5. 支援以ALTER TABLE的方式新增或者刪除PK和UNIQUE約束。

DM支援兩種型別的HUGE表:非事務型HUGE表和事務型HUGE表,下面分別進行介紹。
非事務型HUGE表
對非事務型HUGE表的增、刪、改是直接對HUGE表進行寫操作的,不寫UNDO日誌,不透過BUFFER快取,直接操縱檔案,速度快,但也因此導致不支援事務。另外,非事務型HUGE表中的ROWID是不固定的。

當非事務型HUGE表在操作過程中出現系統崩潰或者斷電等問題時,因為修改時採取的是直接寫的策略,所以有可能會出現資料不一致的問題。為了保證資料的一致性,在操作時可以適當地做一些日誌來保證資料的完整性,完整性保證策略主要是透過資料的映象來實現的,映象的不同程度可以實現不同程度的完整性恢復。映象檔案是放在表目錄中的以.mir為副檔名的檔案。DM提供三種方案:
1. LOG NONE:不做映象。相當於不做資料一致性的保證,如果出錯只能手動透過系統函式來修復表資料,當然速度是最快的,不需要額外的IO,這種選項如果使用者明確知道自己的環境不會出現問題可以採用,效率最高。

2. LOG LAST:做部分映象。但是在任何時候都只對當前操作的區做映象,如果當前區的操作完成了,那麼這個映象也就失效了,可能會被下一個被操作區覆蓋,這樣做的好處是映象檔案不會太大,同時也可以保證資料是完整的。但有可能遇到的問題是:一次操作很多的情況下,有可能一部分資料已經完成,另一部分資料還沒有來得及做的問題。如果使用者能接受這個問題的話這個選擇不失為最佳選擇,這也是系統預設的選擇

3. LOG ALL:全部做映象。在操作過程中,所有被修改的區都會被記錄下來,當一次操作修改的資料過多時,映象檔案有可能會很大,但好處是,能夠保證操作完整性。比如,在操作過程中失敗了,那麼這個操作會完整的撤消,不存在上面一部分修改部分還沒修改的問題。

AUX輔助表
對於每個HUGE表,相應地配備一個AUX輔助表來管理其資料。因為在HUGE表檔案中只儲存了資料,輔助表用來管理以及輔助系統使用者操作這些資料,AUX輔助表是在建立HUGE表時系統自動建立的,表名為“表名$AUX”,如果該HUGE表為分割槽表,則輔助表名為“子表名$AUX”。輔助表的表名長度不能大於128個位元組。AUX輔助表中每一條記錄對應檔案中的一個資料區,包括下面15列:
1.COLID:表示當前這條記錄對應的區所在的列的列ID號;
2.SEC_ID:表示當前這個記錄對應的區的區ID號,每一個區都有一個ID號,並且唯一;
3.FILE_ID:表示這個區的資料所在的檔案號;
4.OFFSET:表示這個區的資料在檔案中的偏移位置,4K對齊;
5.COUNT:表示這個區中儲存的資料總數(有可能包括被刪除的資料);
6.ACOUNT:表示這個區中儲存的實際資料行數;
7.N_LEN:表示這個區中儲存的資料在檔案中的長度,4K對齊的;
8.N_NULL:表示這個區中的資料中包括的NULL值的行數;
9.N_DIST:表示這個區中所有資料互不相同的行數;
10.CPR_FLAG:表示這個區是否壓縮;
11.ENC_FLAG:表示這個區是否加密;
12.CHKSUM:用來較驗的,該功能暫未啟用;
13.MAX_VAL:表示這個區中的最大值,精確值;
14.MIN_VAL:表示這個區中的最小值,精確值;
15.SUM_VAL:表示這個區中所有值的和,精確值。
前面7列是用來控制資料存取的,根據這些資訊就可以知道這個區的具體儲存位置、長度及基本資訊。後面8列都是用來對這個區進行統計分析的。其中,COLID和SEC_ID的組合鍵為輔助表的聚集關鍵字。

事務型HUGE表
非事務型HUGE表在進行增、刪、改時直接對HUGE表進行寫操作,每次寫操作需要至少對一個區進行IO,導致IO量較大,且併發效能不高。為此,DM推出了事務型HUGE表,透過增加RAUX、DAUX和UAUX行輔助表,減少了事務型HUGE表增、刪、改操作的IO,
提高效率,同時提高並行效能。事務型HUGE表支援UNDO日誌,實現了事務特性。

RAUX行輔助表
RAUX行輔助表存放最後一個資料區(不夠存滿一個資料區)的資料,表名為“HUGE表名$RAUX”。如果該HUGE表為分割槽表,則輔助表名為“子表名$RAUX”。輔助表的表名長度不能大於128個位元組。

RAUX行輔助表中內容對應於HUGE表中的最後一部分記錄(不夠存滿一個資料區的)。RAUX表與HUGE表結構相同,不論資料在那個表中,每一行資料的ROWID固定不變。

DAUX行輔助表
DAUX行輔助表記錄HUGE表資料檔案中被刪除的資料,表名為“HUGE表名$DAUX”。如果該HUGE表為分割槽表,則輔助表名為“子表名$DAUX”。輔助表的表名長度不能大於128個位元組。

UAUX行輔助表
UAUX行輔助表記錄HUGE表被更新的資料的新值,表名為“HUGE表名$UAUX”。如果該HUGE表為分割槽表,則輔助表名為“子表名$UAUX”。輔助表的表名長度不能大於128個位元組。

建立HUGE表
當使用者確定自己要使用HUGE表的時候,首先需要在模式中建立新表,建立一個HUGE表需要有CREATE TABLE資料庫許可權,要想在其他使用者的模式中建立新表需要有CREATE ANY TABLE 資料庫許可權。

但是建立一個HUGE表時,如果不使用預設的表空間,則必須要先建立一個HUGE TABLESPACE(HTS),建立HTS語法如下:
CREATE HUGE TABLESPACE < 表空間名> PATH < 表空間路徑>;
引數說明:
1. < 表空間名> 表空間的名稱,表空間名稱最大長度128位元組;
2. < 表空間路徑> 指明新生成的表空間在作業系統下的路徑。
示例如下:

SQL> CREATE HUGE TABLESPACE HTS_NAME PATH '/dm_home/dmdba/dmdbms/data/jydm/htsspace';
executed successfully
used time: 183.066(ms). Execute id is 8.
SQL> select * from v$huge_tablespace;
LINEID     ID          NAME     PATHNAME                                
---------- ----------- -------- ----------------------------------------
1          0           HMAIN    /dm_home/dmdba/dmdbms/data/jydm/HMAIN
2          1           HTS_NAME /dm_home/dmdba/dmdbms/data/jydm/htsspace
used time: 0.723(ms). Execute id is 9.

在建立HUGE表時,根據WITH|WITHOUT DELTA區分建立非事務型HUGE表還是事務型HUGE表。指定WITH DELTA,建立事務型HUGE表;指定WITHOUT DELTA,則建立非事務型HUGE表,預設為WITHOUT DELTA。

例如,建立非事務型HUGE表T1

SQL> CREATE HUGE TABLE T1 (A INT, B INT) STORAGE(WITHOUT DELTA) tablespace HTS_NAME;
executed successfully
used time: 49.058(ms). Execute id is 13.
SQL> desc t1;
LINEID     NAME TYPE$   NULLABLE
---------- ---- ------- --------
1          A    INTEGER Y
2          B    INTEGER Y
used time: 14.603(ms). Execute id is 14.
SQL> select owner,table_name,tablespace_name from dba_tables where table_name='T1';
LINEID     OWNER  TABLE_NAME TABLESPACE_NAME
---------- ------ ---------- ---------------
1          SYSDBA T1         HTS_NAME
used time: 57.166(ms). Execute id is 17.

建立事務型HUGE表T2。

SQL> CREATE HUGE TABLE T2 (A INT, B INT) STORAGE(WITH DELTA) tablespace hts_name;
executed successfully
used time: 37.888(ms). Execute id is 18.
SQL> select owner,table_name,tablespace_name from dba_tables where table_name='T2';
LINEID     OWNER  TABLE_NAME TABLESPACE_NAME
---------- ------ ---------- ---------------
1          SYSDBA T2         HTS_NAME
used time: 27.566(ms). Execute id is 19.
[root@shard1 htsspace]# ls -lrt
總用量 0
drwxr-xr-x 4 dmdba dinstall 34 11月 13 01:07 SCH150994945
[root@shard1 htsspace]# cd SCH150994945
[root@shard1 SCH150994945]# ls
TAB1425  TAB1427
[root@shard1 SCH150994945]# ls -lrt
總用量 0
drwxr-xr-x 2 dmdba dinstall 6 11月 13 01:01 TAB1425
drwxr-xr-x 2 dmdba dinstall 6 11月 13 01:07 TAB1427

需要注意的是,當指定建立事務型HUGE表時,指定HUGE表映象檔案方案的選項LOG NONE|LOG LAST|LOG ALL失效。另外,在建立表HUGE表時,可以指定表的儲存屬性,儲存屬性包括如下幾個方面:

另外,在建立表HUGE表時,可以指定表的儲存屬性,儲存屬性包括如下幾個方面:
1. 區大小(一個區的資料行數)
區大小可以透過設定表的儲存屬性來指定,區的大小必須是2的多少次方,如果不是則向上對齊。取值範圍:1024行~1024*1024行。預設值為65536行。例如,建立HUGE表test,指定區的大小為2048,其它預設。
CREATE HUGE TABLE test(name VARCHAR, sno INT) STORAGE(SECTION (2048));

例如,建立HUGE表test,所有列都採用預設值。
CREATE HUGE TABLE test(name VARCHAR, sno INT);

2. 是否記錄區統計資訊,即在插入時是否記下其最大值最小值
關於這一點有一個原則,如果這個列經常用作查詢條件,並且資料不是很均勻,或者基本是有序的,那麼做統計資訊是非常有用的,反之則可以不做統計。預設情況下,為記錄區統計資訊。如果想不記錄,可透過設定STAT NONE實現。例如,建立HUGE表test,透過列儲存屬性指定統計資訊屬性(不記錄區統計資訊)。
CREATE HUGE TABLE test(name VARCHAR STORAGE (STAT NONE), sno INT);

又如,建立HUGE表test,透過表儲存屬性指定統計資訊屬性(不記錄區統計資訊)。
CREATE HUGE TABLE test(name VARCHAR, sno INT) STORAGE (STAT NONE);

3. 所屬的表空間
建立HUGE表,需要透過儲存屬性指定其所在的表空間,不指定則儲存於預設表空間HMAIN中。HUGE表指定的表空間只能是HTS表空間,例如HTS_NAME為已指定HTS表空間。

SQL> CREATE HUGE TABLE t3 (name VARCHAR, sno INT) STORAGE (ON HTS_NAME);
executed successfully
used time: 31.424(ms). Execute id is 25.
SQL> select owner,table_name,tablespace_name from dba_tables where table_name='T3';
LINEID     OWNER  TABLE_NAME TABLESPACE_NAME
---------- ------ ---------- ---------------
1          SYSDBA T3         HTS_NAME
used time: 14.911(ms). Execute id is 27.

還可以在建立語句中透過tablespace選項來指定表空間

SQL> CREATE HUGE TABLE T2 (A INT, B INT) STORAGE(WITH DELTA) tablespace hts_name;
executed successfully
used time: 37.888(ms). Execute id is 18.
SQL> select owner,table_name,tablespace_name from dba_tables where table_name='T2';
LINEID     OWNER  TABLE_NAME TABLESPACE_NAME
---------- ------ ---------- ---------------
1          SYSDBA T2         HTS_NAME
used time: 27.566(ms). Execute id is 19.

4. 檔案大小
建立HUGE表時還可以指定單個檔案的大小,透過表的儲存屬性來指定,取值範圍為16M~1024*1024M。不指定則預設為64M。檔案大小必須是2的多少次方,如果不是則向上對齊。
CREATE HUGE TABLE test(name VARCHAR, sno INT) STORAGE (filesize(64));

5. 指定壓縮級別
為特定列指定壓縮級別,取值範圍0~10,分別代表不同的演算法和級別。有兩種壓縮演算法:SNAPPY和ZIP。10採用SNAPPY演算法輕量級方式壓縮。2~9採用ZIP演算法壓縮,2~9代表壓縮級別,值越小表示壓縮比越低、壓縮速率越快;值越大表示壓縮比越高、壓縮速度越慢。0和1為快捷使用,預設值為0。0等價於LEVEL 2;1等價於LEVEL 9。

例如,建立HUGE表test,指定sno列按照最大壓縮比壓縮。
CREATE HUGE TABLE test(name VARCHAR, sno INT) COMPRESS LEVEL 1 (sno);

下面是一個綜合的建立HUGE表的例子:

SQL> CREATE HUGE TABLE orders
2   (
3   o_orderkey INT,
4   o_custkey INT,
5   o_orderstatus CHAR(1),
6   o_totalprice FLOAT,
7   o_orderdate DATE,
8   o_orderpriority CHAR(15),
9   o_clerk CHAR(15),
10  o_shippriority INT,
11  o_comment VARCHAR(79) STORAGE(stat none)
12  )
13  STORAGE(section(65536) ,filesize(64), with delta,on HTS_NAME) 
14  COMPRESS LEVEL 9 FOR 'QUERY HIGH' (o_comment);
executed successfully
used time: 32.537(ms). Execute id is 28.

這個例子建立了一個名為ORDERS的事務型HUGE表,ORDERS表的區大小為65536行,檔案大小為64M,指定所在的表空間為HTS_NAME,o_comment列指定的區大小為不做統計資訊,其它列(預設)都做統計資訊,指定列o_comment列壓縮型別為查詢高壓縮率,壓縮級別為9。

HUGE表使用說明
HUGE表與普通行表一樣,可以進行增、刪、改操作,操作方式也是一樣的。但HUGE表的刪除與更新操作的效率會比行表低一些,併發操作效能也會比行表差一些,因此在HUGE中不宜做頻繁的刪除及更新操作。總之,HUGE表比較適合做分析型表的儲存。另外,使用HUGE表時應注意存在以下一些限制:
1.建HUGE表時僅支援定義NULL、NOT NULL、UNIQUE約束以及PRIMARY KEY,後兩種約束也可以透過ALTER TABLE的方式新增,但這兩種約束不檢查唯一性;
2.HUGE不允許建立聚簇索引,允許建立二級索引,不支援建點陣圖索引,其中UNIQUE索引不檢查唯一性;
3.不支援SPACE LIMIT(空間限制);
4.不支援建立全文索引;
5.不支援使用自定義型別;
6.不支援引用約束;
7.不支援IDENTITY自增列;
8.不支援大欄位列;
9.不支援建觸發器;
10.不允許垂直分割槽;
11.不支援遊標的修改操作;
12.PK和UNIQUE約束不檢查唯一性,對應的索引都為虛索引;UNIQUE索引也不檢查唯一性,為實索引,索引標記中
不包含唯一性標記,即和普通二級索引相同;
13.不允許對分割槽子表設定SECTION和WITH/WITHOUT DELTA;
14.當事務型HUGE表進行了較多增刪改操作時,應對其進行資料重整操作,以提高效能。

檢視有關HUGE表的資訊
1.表定義
對一個HUGE表,使用者可以透過CALL SP_TABLEDEF('SYSDBA', 'ORDERS');得到這個表的定義語句,可以具體瞭解表的各個列的資料型別資訊、儲存屬性等,還可以檢視在這個表上是否有壓縮等等。

SQL> CALL SP_TABLEDEF('SYSDBA', 'ORDERS');
LINEID     COLUMN_VALUE                                                                                                                                                                                                                   
---------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1          CREATE HUGE TABLE "SYSDBA"."ORDERS"  (  "O_ORDERKEY" INT,  "O_CUSTKEY" INT,  "O_ORDERSTATUS" CHAR(1),  "O_TOTALPRICE" FLOAT,  "O_ORDERDATE" DATE,  "O_ORDERPRIORITY" CHAR(15),  "O_CLERK" CHAR(15),  "O_SHIPPRIORITY" INT,  "O_COMMENT" VARCHAR(79) STORAGE(STAT NONE)) STORAGE(STAT ASYNCHRONOUS, WITH DELTA, SECTION(65536), FILESIZE(64), ON "HTS_NAME")    COMPRESS (     "O_COMMENT" LEVEL 9 ) LOG LAST ;
used time: 2.205(ms). Execute id is 31.
SQL> CALL SP_TABLEDEF('SYSDBA', 'T1');
LINEID     COLUMN_VALUE                                                                                                                          
---------- --------------------------------------------------------------------------------------------------------------------------------------
1          CREATE HUGE TABLE "SYSDBA"."T1"  (  "A" INT,  "B" INT) STORAGE(WITHOUT DELTA, SECTION(65536), FILESIZE(64), ON "HTS_NAME")  LOG LAST ;
used time: 1.063(ms). Execute id is 32.

2. 資料儲存情況
HUGE表有一個很好的特點就是有AUX輔助表,其中使用者可以利用的資訊很多,因為每一條記錄對應一個區,所以可以檢視每一個區的儲存情況,每一個列的儲存情況及每一個列中具有相同區ID的所有資料的情況等,還包括了很精確的統計資訊,使用者可以透過觀察AUX輔助表中的資訊對錶進行一些相應的操作。

非事務型huge表

SQL> insert into t1 values(2,2);
affect rows 1
used time: 33.110(ms). Execute id is 35.
SQL> commit;
executed successfully
used time: 16.240(ms). Execute id is 36.
SQL> select * from T1$AUX;
LINEID     COLID       SEC_ID      FILE_ID     OFFSET               COUNT       ACOUNT      N_LEN       N_NULL      N_DIST      CPR_FLAG ENC_FLAG CHKSUM      MAX_VAL    MIN_VAL    SUM_VAL           
---------- ----------- ----------- ----------- -------------------- ----------- ----------- ----------- ----------- ----------- -------- -------- ----------- ---------- ---------- ------------------
1          0           0           0           4096                 2           2           270336      0           0           N        N        0           0x02000000 0x01000000 0x0300000000000000
2          1           0           0           4096                 2           2           270336      0           0           N        N        0           0x02000000 0x01000000 0x0300000000000000
used time: 1.079(ms). Execute id is 44.
SQL>

事務刑huge表

SQL> insert into orders values(1,1,'F',50.5,sysdate,'1','1',1,'1');
affect rows 1
used time: 33.758(ms). Execute id is 46.
SQL> insert into orders values(2,2,'F',134.2,sysdate,'2','2',2,'2');
affect rows 1
used time: 1.499(ms). Execute id is 47.
SQL> commit;
executed successfully
used time: 21.297(ms). Execute id is 48.

在插入資料後RAUX輔助表中有資料,DAUX與UAUX輔助表中沒有資料

SQL> select * from orders$raux;
LINEID     O_ORDERKEY  O_CUSTKEY   O_ORDERSTATUS O_TOTALPRICE              O_ORDERDATE O_ORDERPRIORITY O_CLERK         O_SHIPPRIORITY O_COMMENT
---------- ----------- ----------- ------------- ------------------------- ----------- --------------- --------------- -------------- ---------
1          1           1           F             5.050000000000000E+01     2019-11-14  1               1               1              1
2          2           2           F             1.342000000000000E+02     2019-11-14  2               2               2              2
used time: 1.197(ms). Execute id is 50.
SQL> select * from orders$daux;
no rows
used time: 0.961(ms). Execute id is 51.
SQL> select * from orders$uaux;
no rows
used time: 1.007(ms). Execute id is 52.

當更新orders表中的資料後,UAUX輔助表中會記錄相關資料

SQL> update orders set O_ORDERSTATUS='D' where O_ORDERKEY=2;
affect rows 1
used time: 2.416(ms). Execute id is 53.
SQL> commit;
executed successfully
used time: 29.715(ms). Execute id is 54.
SQL> select * from orders$uaux;
LINEID     COLID       DTA_ROWID            VALUE
---------- ----------- -------------------- -----
1          2           2                    0x44
used time: 0.726(ms). Execute id is 55.

當刪除資料後,DAUX輔助表中會記錄相關資料

SQL> delete from orders where O_ORDERKEY=2;
affect rows 1
used time: 2.128(ms). Execute id is 57.
SQL> commit;
executed successfully
used time: 19.066(ms). Execute id is 58.
SQL> select * from orders$daux;
LINEID     START_ID             COUNT       INFO      
---------- -------------------- ----------- ----------
1          2                    1           NULL
used time: 0.590(ms). Execute id is 59.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-2664022/,如需轉載,請註明出處,否則將追究法律責任。

相關文章