欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

达梦列存储表(HUGE Table)介绍

程序员文章站 2022-06-03 11:53:51
...

达梦数据库中,表的数据存储方式分为行存储和列存储。行存储是以记录为单位进行存储的,数据页面中存储的是完整的若干条记录;列存储是以列为单位进行存储的,每一个列的所有行数据都存储在一起,而且一个指定的页面中存储的都是某一个列的连续数据。

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表时系统自动创建的,表名为“表名AUXHUGEAUX”,如果该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表名RAUXHUGERAUX”。如果该HUGE表为分区表,则辅助表名为“子表名RAUX”。辅助表的表名长度不能大于128个字节。

RAUX行辅助表中内容对应于HUGE表中的最后一部分记录(不够存满一个数据区的)。RAUX表与HUGE表结构相同,不论数据在那个表中,每一行数据的ROWID固定不变。

DAUX行辅助表
DAUX行辅助表记录HUGE表数据文件中被删除的数据,表名为“HUGE表名DAUXHUGEDAUX”。如果该HUGE表为分区表,则辅助表名为“子表名DAUX”。辅助表的表名长度不能大于128个字节。

UAUX行辅助表
UAUX行辅助表记录HUGE表被更新的数据的新值,表名为“HUGE表名UAUXHUGEUAUX”。如果该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.
[[email protected] htsspace]# ls -lrt
总用量 0
drwxr-xr-x 4 dmdba dinstall 34 11月 13 01:07 SCH150994945
[[email protected] htsspace]# cd SCH150994945
[[email protected] SCH150994945]# ls
TAB1425  TAB1427
[[email protected] 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);

  1. 是否记录区统计信息,即在插入时是否记下其最大值最小值
    关于这一点有一个原则,如果这个列经常用作查询条件,并且数据不是很均匀,或者基本是有序的,那么做统计信息是非常有用的,反之则可以不做统计。缺省情况下,为记录区统计信息。如果想不记录,可通过设置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);

  1. 所属的表空间
    创建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.
  1. 文件大小
    创建HUGE表时还可以指定单个文件的大小,通过表的存储属性来指定,取值范围为16M~1024*1024M。不指定则默认为64M。文件大小必须是2的多少次方,如果不是则向上对齐。
    CREATE HUGE TABLE test(name VARCHAR, sno INT) STORAGE (filesize(64));

  2. 指定压缩级别
    为特定列指定压缩级别,取值范围010,分别代表不同的算法和级别。有两种压缩算法:SNAPPY和ZIP。10采用SNAPPY算法轻量级方式压缩。29采用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.
  1. 数据存储情况
    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.
相关标签: 达梦数据库