1、达梦支持的表类型
达梦数据库支持的表类型有:普通表、堆表、列存储表(HUGE)、分区表、临时表、外部表等。
2、普通表
即索引组织表,也是达梦默认创建的表,有且仅有一个聚簇索引键,表数据按照聚簇索引键排序,数据是有序的,插入有序,rowid 是逻辑 rowid,占用存储空间,所以索引组织表比堆表占用较多空间。
DM 创建表时如果指定了主键,则主键为聚簇索引键;如果创建表示未指定主键,则 rowid 为聚簇索引键。
如果要在所属模式中创建新表,需要有 CREATE TABLE 数据库权限;而要在其他用户的模式中创建新表,则需要有 CREATE ANY TABLE 数据库权限。创建表时,应当为表指定一个表空间,否则,表将默认在 MAIN 创建。
2.1创建普通表
CREATE TABLE t1 (
EMPNO INT PRIMARY KEY,
ENAME VARCHAR(15) NOT NULL,
JOB VARCHAR(10),
MGR INT,
HIREDATE DATE DEFAULT (SYSDATE),
SALARY FLOAT,
DEPTNO TINYINT NOT NULL )
STORAGE (
INITIAL 50,
NEXT 50,
MINEXTENTS 10,
FILLFACTOR 80,
ON main);
2.2修改普通表
SQL> ALTER TABLE t1 MODIFY ENAME VARCHAR(29) DEFAULT '' NOT NULL;
操作已执行
已用时间: 8.638(毫秒). 执行号:2511.
SQL> ALTER TABLE t1 ADD GENDER CHAR(1) CHECK (GENDER IN ('M','F'));
操作已执行
已用时间: 8.084(毫秒). 执行号:2512.
SQL> ALTER TABLE t1 DROP GENDER CASCADE;
操作已执行
已用时间: 8.996(毫秒). 执行号:2513.
SQL> DESC t1;
行号 NAME TYPE$ NULLABLE
---------- -------- ----------- --------
1 EMPNO INTEGER N
2 ENAME VARCHAR(29) N
3 JOB VARCHAR(10) Y
4 MGR INTEGER Y
5 HIREDATE DATE Y
6 SALARY DOUBLE Y
7 DEPTNO TINYINT N
7 rows got
已用时间: 1.012(毫秒). 执行号:2514.
SQL> TRUNCATE TABLE t1;
操作已执行
已用时间: 4.759(毫秒). 执行号:2515.
SQL> DROP TABLE t1;
操作已执行
已用时间: 10.288(毫秒). 执行号:2516.
3、堆表
3.1创建堆表
create table t2
(
"COLUMN_1" CHAR(10),
"COLUMN_2" CHAR(10)
)
storage(initial 1, next 1, minextents 1, fillfactor 0, branch(6,2));
凡是 DDL 中带有 branch/no branch 关键字的表就是堆表:no branch: 不带分支的堆表Branch(6,2): 表示 6 个并发分支,2 个非并发分支。(1<=Branch<=64)。
3.2修改堆表
SQL> ALTER TABLE t2 ADD GENDER CHAR(1) CHECK (GENDER IN ('M','F'));
操作已执行
已用时间: 9.625(毫秒). 执行号:2522.
SQL> ALTER TABLE t2 DROP GENDER CASCADE;
操作已执行
已用时间: 8.849(毫秒). 执行号:2523.
SQL> desc t2;
行号 NAME TYPE$ NULLABLE
---------- -------- -------- --------
1 COLUMN_1 CHAR(10) Y
2 COLUMN_2 CHAR(10) Y
已用时间: 5.555(毫秒). 执行号:2524.
4、HUGE表
达梦数据库中,表的数据存储方式分为行存储和列存储。行存储是以记录为单位进行存
储的,数据页面中存储的是完整的若干条记录;列存储是以列为单位进行存储的,每一个列
的所有行数据都存储在一起,而且一个指定的页面中存储的都是某一个列的连续数据。
Huge File System(检查 HFS)是达梦数据库实现的,针对海量数据进行分析的一种高效、简单的列存储机制。列存储表(也称为 HUGE 表)就是建立在 HFS 存储机制上的一种表。
HUGE 表是建立在混合表空间上的。HUGE 数据文件存储在混合表空间定义中指定的
HUGE 数据文件路径下,一个混合表空间最多可以添加 255 个 HUGE 数据文件路径,混合表空间的 HUGE 数据文件路径相关信息存储在动态视图 V$HUGE_TABLESPACE 中。普通的表空间,数据是通过段、簇、页来管理的,并且以固定大小(4K、8K、16K、32K)的页面为管理单位;而混合表空间存储 HUGE 表是通过 HFS 存储机制来管理的,它相当于一个文件系统。为混合表空间指定一个 HUGE 数据文件路径,其实就是创建一个空的HUGE 数据文件目录(系统中有一个默认的混合表空间 MAIN,其 HUGE 数据文件目录名为HMAIN)。在创建一个HUGE 表并插入数据时,数据库会在指定的混合表空间的 HUGE 数据文件目录下创建一系列的目录及文件。
DM 支持两种类型的 HUGE 表:非事务型 HUGE 表和事务型 HUGE 表。
4.1非事务型HUGE表
对非事务型 HUGE 表的增、删、改是直接对 HUGE 表进行写操作的,不写 UNDO 日志,不通过 BUFFER 缓存,直接操纵文件,速度快,但也因此导致不支持事务。为了保证数据的一致性,在操作时可以适当地做一些日志来保证数据的完整性,完整性保证策略主要是通过数据的镜像来实现的,镜像的不同程度可以实现不同程度的完整性恢复。
DM 对于镜像提供三种方案:
1.LOG NONE
不做镜像。相当于不做数据一致性的保证,如果出错只能手动通过系统函数来修复表数据,当然速度是最快的,不需要额外的 IO,如果用户明确知道自己的环境不会出现问题可以采用该方案,效率最高。
2.LOG LAST
做部分镜像。但是在任何时候都只对当前操作的区做镜像,如果当前区的操作完成了,那么这个镜像也就失效了,可能会被下一个被操作区覆盖。这样做的好处是镜像文件不会太大,同时也可以保证数据是完整的。但有可能遇到的问题是:一次操作很多的情况下,有可能一部分数据做镜像已经完成,另一部分数据还没有来得及开始做的问题。如果用户能接受这个问题的话这个选择不失为最佳选择,这也是系统默认的选择。
3.LOG ALL
全部做镜像。在操作过程中,所有被修改的区都会被记录下来,当一次操作修改的数据过多时,镜像文件有可能会很大,但好处是,能够保证操作完整性。比如,在操作过程中失败了,那么这个操作会完整的撤消,不存在 LOG LAST方案中一部分修改部分还没修改的问题。需要注意的是,若创建数据库时使用参数 HUGE_WITH_DELTA 的缺省值 1 ,则不支持创建非事务型 HUGE 表。
4.2事务型HUGE表
非事务型 HUGE 表在进行增、删、改时直接对 HUGE 表进行写操作,每次写操作需要至少对一个区进行 IO,导致 IO 量较大,且并发性能不高。为此,DM 推出了事务型 HUGE 表,通过增加 RAUX、DAUX 和 UAUX 行辅助表,减少了事务型 HUGE 表增、删、改操作的 IO,提高效率,同时提高并行性能。事务型 HUGE 表支持 UNDO 日志,实现了事务特性。
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.PK 和 UNIQUE 约束不检查唯一性,对应的索引都为虚索引;UNIQUE 索引也不检查唯一性,为实索引,索引标记中不包含唯一性标记,即和普通二级索引相同;
12.不允许对分区子表设置 SECTION 和 WITH/WITHOUT DELTA;
13.当事务型 HUGE 表进行了较多增删改操作时,应对其进行数据重整操作,以提高性能。
5、分区表
分区是指将表、索引等数据库对象划分为较小的可管理片段的技术,每一个片段称为分区子表或分区索引。一个表被分区后,对表的查询操作可以局限于某个分区进行,而不是整个表,这样可以大大提高查询速度。在 DM 分区表中,主表本身不存储数据,所有数据只存储在子表中,从而实现不同分区的完全独立性。 水平分区子表删除后,会将子表上的数据一起删除。
由于每一个分区都以一个子表作为实体,那么不同分区可以存储于相同表空间,也可以位于不同的表空间中。将这些分区放在不同的表空间中具有以下的好处:
1.减少所有数据都损坏的可能性,一个表空间损坏不影响其他表空间,提高可用性;
2.恢复时间大大减少;
3.可以将同一个表中的数据分布在不同的磁盘上,从而均衡磁盘上的 I/O 操作;
4.提高了表的可管理性、可利用性和访问效率。
达梦数据库 DM 支持对表进行水平分区。对于水平分区,提供以下分区方式:
1.范围(range)水平分区:对表中的某些列上值的范围进行分区,根据某个值的范围,决定将该数据存储在哪个分区上;
2.哈希(hash)水平分区:通过指定分区编号来均匀分布数据的一种分区类型,通过在 I/O 设备上进行散列分区,使得这些分区大小基本一致;
3.列表(list)水平分区:通过指定表中的某个列的离散值集,来确定应当存储在一起的数据。例如,可以对表上的 status 列的值在(‘A’,‘H’,‘O’)放在一个分区,值在(‘B’,‘I’,‘P’)放在另一个分区,以此类推;
多级分区表:按上述三种分区方法进行任意组合,将表进行多次分区,称为多级分区表。
5.1范围分区表
创建范围分区表,以HIRE_DATE作为分区列
CREATE TABLE t3
(
EMPLOYEE_ID INT,
EMPLOYEE_NAME VARCHAR (20),
IDENTITY_CARD VARCHAR (18),
EMAIL VARCHAR (50) NOT NULL,
PHONE_NUM VARCHAR (20),
HIRE_DATE DATE NOT NULL,
JOB_ID VARCHAR (10) NOT NULL,
SALARY INT,
COMMISSION_PCT INT,
MANAGER_ID INT,
DEPARTMENT_ID INT,
CHECK (SALARY > 0)
)
PARTITION BY RANGE (HIRE_DATE)
(PARTITION P1 VALUES LESS THAN ('2015-01-01') TABLESPACE TBS_P1,
PARTITION P2 VALUES LESS THAN ('2018-01-01') TABLESPACE TBS_P2,
PARTITION P3 VALUES LESS THAN ('2021-01-01') TABLESPACE TBS_P3,
PARTITION PMAX VALUES LESS THAN (MAXVALUE) TABLESPACE TBS_PMAX)
/
5.2哈希分区表
创建以city列作为分区键值的HASH分区表
CREATE TABLE t4(
sales_id INT,
saleman CHAR(20),
saledate DATETIME,
city CHAR(10)
)
PARTITION BY HASH(city)(
PARTITION p1,
PARTITION p2,
PARTITION p3,
PARTITION p4
)
/
5.3列表分区表
创建列表分区表,以city作为分区键值
CREATE TABLE t5(
sales_id INT,
saleman CHAR(20),
saledate DATETIME,
city CHAR(10)
)
PARTITION BY LIST(city)(
PARTITION p1 VALUES ('北京', '天津'),
PARTITION p2 VALUES ('上海', '南京', '杭州'),
PARTITION p3 VALUES ('武汉', '长沙'),
PARTITION p4 VALUES ('广州', '深圳'),
PARTITION p5 VALUES (DEFAULT)
)
/
5.4多级分区表
创建多级分区表,按照CITY和SALEDATE进行分区
CREATE TABLE SALES1(
SALES_ID INT,
SALEMAN CHAR(20),
SALEDATE DATETIME,
CITY CHAR(10)
)
PARTITION BY LIST(CITY)
SUBPARTITION BY RANGE(SALEDATE) SUBPARTITION TEMPLATE(
SUBPARTITION P11 VALUES LESS THAN ('2023-04-01'),
SUBPARTITION P12 VALUES LESS THAN ('2023-07-01'),
SUBPARTITION P13 VALUES LESS THAN ('2023-10-01'),
SUBPARTITION P14 VALUES EQU OR LESS THAN (MAXVALUE))
(
PARTITION P1 VALUES ('北京', '天津')
(
SUBPARTITION P11_1 VALUES LESS THAN ('2023-10-01'),
SUBPARTITION P11_2 VALUES EQU OR LESS THAN (MAXVALUE)
),
PARTITION P2 VALUES ('上海', '南京', '杭州'),
PARTITION P3 VALUES (DEFAULT)
)
/
6、临时表
当处理复杂的查询或事务时,由于在数据写入永久表之前需要暂时存储一些行信息或需要保存查询的中间结果,可能需要一些表来临时存储这些数据。DM 允许创建临时表来保存会话甚至事务中的数据。在会话或事务结束时,这些表上的数据将会被自动清除。临时表中的数据不能像在其它永久表中的数据那样进行备份,当事务结束或会话断开时,数据就会被清空。在临时表创建过程中,不会像永久表和索引那样自动分配数据段,而是仅当第一次执行 DML 语句时,才会为临时表在临时表空间中分配空间。并且,对于不同的会话,临时表上的数据是独享的,不会互相干扰,即会话 A 不能访问会话 B 临时表上的数据。
DM 临时表支持以下功能:
1.在临时表中,会话可以像普通永久表一样更新、插入和删除数据;
2.临时表的 DML 操作产生较少的 REDO 日志;
3.临时表支持建索引,以提高查询性能;
4.在一个会话或事务结束后,数据将自动从临时表中删除;
5.不同用户可以访问相同的临时表,每个用户只能看到自己的数据;
6.临时表的数据量很少,意味着更高效的查询效率;
7.临时表的表结构在数据删除后仍然存在,便于以后的使用;
临时表的权限管理跟普通表一致。临时表 ON COMMIT 关键词指定表中的数据是事务级还是或会话级的,默认情况下是事务级的。
- ON COMMIT DELETE ROWS:
指定临时表是事务级的,每次事务提交或回滚之后,表中所有数据都被删除;
- ON COMMIT PRESERVE ROWS:
指定临时表是会话级的,会话结束时才清空表,并释放临时 B事务。
6.1事务级临时表
CREATE GLOBAL TEMPORARY TABLE TMP_t1(
EMPNO INT PRIMARY KEY,
ENAME VARCHAR(15) NOT NULL,
JOB VARCHAR(10))
ON COMMIT DELETE ROWS;
SQL> INSERT INTO TMP_t1 VALUES (1,'lei','IT');
影响行数 1
已用时间: 1.268(毫秒). 执行号:2529.
SQL> INSERT INTO TMP_t1 VALUES (2,'lei','IT');
影响行数 1
已用时间: 0.491(毫秒). 执行号:2530.
SQL> SELECT * FROM TMP_t1;
行号 EMPNO ENAME JOB
---------- ----------- ----- ---
1 1 LEI IT
2 2 LEI IT
tmp_t临时表依旧存在,数据依旧存在
6.2会话级临时表
SQL> CREATE GLOBAL TEMPORARY TABLE TMP_t2(
2 EMPNO INT PRIMARY KEY,
3 ENAME VARCHAR(15) NOT NULL,
4 JOB VARCHAR(10))
5 ON COMMIT PRESERVE ROWS ;
操作已执行
已用时间: 5.765(毫秒). 执行号:3302.
SQL> INSERT INTO TMP_t2 VALUES (1,'lei','IT');
影响行数 1
已用时间: 1.046(毫秒). 执行号:3303.
SQL> INSERT INTO TMP_t2 VALUES (2,'lei','IT');
影响行数 1
已用时间: 0.521(毫秒). 执行号:3304.
SQL> SELECT * FROM TMP_t2;
行号 EMPNO ENAME JOB
---------- ----------- ----- ---
1 1 lei IT
2 2 lei IT
已用时间: 0.720(毫秒). 执行号:3305.
SQL> COMMIT;
操作已执行
已用时间: 0.803(毫秒). 执行号:3306.
SQL> SELECT * FROM TMP_t2;
行号 EMPNO ENAME JOB
---------- ----------- ----- ---
1 1 lei IT
2 2 lei IT
已用时间: 0.322(毫秒). 执行号:3307.
SQL> EXIT
[dmdba@lei2 ~]$ disql lei/leileilei
服务器[LOCALHOST:5236]:处于普通打开状态
登录使用时间 : 3.827(ms)
disql V8
SQL> SELECT * FROM TMP_t2;
未选定行
已用时间: 1.565(毫秒). 执行号:3501.
SQL> DESC TMP_t2;
行号 NAME TYPE$ NULLABLE
---------- ----- ----------- --------
1 EMPNO INTEGER N
2 ENAME VARCHAR(15) N
3 JOB VARCHAR(10) Y
已用时间: 18.954(毫秒). 执行号:3502.
退出会话后重新开启新的会话,临时表数据被清空,但是表还在。
7、外部表
外部表是表的数据不会放在数据库里面,会放在操作系统的文件里面。通过数据库外部表可以查看外部文件的数据。
1.建立外部表时,不会产生页、簇、段等存储结构;
2.只能与表相关的定义放在数据库字典中,不能对外部表的内容进行修改(update、instert、 delete);
3.不能对外部表创建索引;
4.外部表可以通过SQL语句解码器来完成。而不需要将外部表装载到数据库中。
创建外部表
[dmdba@lei2 ~]$ vi ext.txt
添加:
1|2|3|4
5|6|7|8
[dmdba@lei2 ~]$ vi ctl.txt
添加:
LOAD DATA
INFILE 'ext.txt'
INTO TABLE EXT
FIELDS '|'
[dmdba@lei2 ~]$ disql lei/leileilei
服务器[LOCALHOST:5236]:处于普通打开状态
登录使用时间 : 4.115(ms)
disql V8
SQL> CREATE OR REPLACE DIRECTORY "EXTDIR" AS '/home/dmdba/';
操作已执行
已用时间: 2.352(毫秒). 执行号:3701.
SQL> CREATE EXTERNAL TABLE EXT(
2 C1 INT,
3 C2 INT,
4 C3 INT,
5 C4 INT
6 ) FROM DEFAULT DIRECTORY EXTDIR LOCATION ('ctl.txt');
操作已执行
已用时间: 5.356(毫秒). 执行号:3702.
SQL> SELECT * FROM EXT;
行号 C1 C2 C3 C4
---------- ----------- ----------- ----------- -----------
1 1 2 3 4
2 5 6 7 8
已用时间: 7.536(毫秒). 执行号:3703.
SQL> INSERT INTO EXT VALUES(9,10,11,12);
INSERT INTO EXT VALUES(9,10,11,12);
第1 行附近出现错误[-2609]:外部表不支持的操作.
已用时间: 0.335(毫秒). 执行号:0.
[dmdba@lei2 ~]$ vi ext.txt
添加:
1|2|3|4
5|6|7|8
9|10|11|12
SQL> SELECT * FROM EXT;
行号 C1 C2 C3 C4
---------- ----------- ----------- ----------- -----------
1 1 2 3 4
2 5 6 7 8
3 9 10 11 12
8、总结
达梦数据库支持多种表类型,开发人员应根据业务需求来选择表类型,要对业务有合适的预估,提前规划表分区;
-
HUGE表在海量数据分析有优势,但是在删除和更新方面性能不如行表
-
一般情况下,堆表的插入效率优于索引组织表,查询速度索引组织表优于堆表,索引组织表比堆表更节省磁盘空间,使用主键来查询的表比较适合索引组织表。
更多内容请参考:https://eco.dameng.com