达梦数据库 DCP(DM Certified Professional)测试中,理论考试考完后立刻出成绩,但因为刷题较多的情况,因此理论考试通过较为简单,因此简单叙述下,对于上机测试中,重点的分区表部分以及在工作中使用较少的dmfdr和dmdis工具进行详细的叙述以及考试中常见的问题进行说明,希望能让后来者少踩坑、通过率更高。
一、官方把认证分成 DCA(管理员)、DCP(专业人士)、DCM(大师)三级。DCP 的定位是“能独立部署、优化、容灾”。
理论:200 题,单选 、多选、判断 ,2 小时,70 分及格。
一句话总结:多练习,就是刷题。
二、理论题备考:
用官方大纲拉出八根主干:体系结构、对象管理、安全管理、高可用、备份恢复、性能优化、数据迁移、DEM 监控。每根主干再细分叶子节点,例如“高可用”展开为数据守护、读写分离、DMDSC。
刷题而不是背题
理论题库官方给 10次模拟机会,正确用法是:先刷7-8遍后,记录题型,总结错题,最后几次用来练速度和正确率,也可以几个人看对方有哪些题是自己没有刷到的补充下。
三、上机题备考
需要对分区表有一定的了解,熟悉达梦的审计功能,备份恢复,导入导出,以及dmfldr和dmdis工具的使用,对于审计和备份恢复,导入导出的基础内容不在赘述,以下仅对平时接触的最少的这部分以及重点的分区表的使用进行说明。
一定一定要有兜底分区,不然会存在数据找不到分区的情况。或者采用间隔分区的形式对分区表进行创建。
1.创建分区数据文件和用户
--查看当前数据文件路径
select path from v$datafile ;
--创建分区表
create TABLESPACE DMTBS1 datafile '/dmdata/data/DMTBS_01.DBF' size 128 ;
create TABLESPACE DMTBS2 datafile '/dmdata/data/DMTBS_02.DBF' size 128 ;
create TABLESPACE DMTBS3 datafile '/dmdata/data/DMTBS_03.DBF' size 128 ;
create TABLESPACE DMTBS4 datafile '/dmdata/data/DMTBS_04.DBF' size 128 ;
--创建用户并赋权
create user DMTEST IDENTIFIED by Dameng123 default TABLESPACE DMTBS1 ;
grant public ,resource ,dba to DMTEST;
2.创建范围分区表
--创建范围分区表
drop table IF EXISTS DMTEST.fanwei_t1;
create table DMTEST.fanwei_T1(
id int ,
name VARCHAR(20)
)
PARTITION BY RANGE (id)
(
PARTITION p1 VALUES LESS THAN (100) STORAGE( INITIAL 1 ,NEXT 1 ,MINEXTENTS 1 ,FILLFACTOR 0 , on DMTBS1), --99
PARTITION p2 VALUES LESS THAN (200) STORAGE( INITIAL 1 ,NEXT 1 ,MINEXTENTS 1 ,FILLFACTOR 0 , on DMTBS2), --199
PARTITION p3 VALUES LESS THAN (300) STORAGE( INITIAL 1 ,NEXT 1 ,MINEXTENTS 1 ,FILLFACTOR 0 , on DMTBS3), --299
PARTITION pN VALUES LESS THAN (MAXVALUE) STORAGE( INITIAL 1 ,NEXT 1 ,MINEXTENTS 1 ,FILLFACTOR 0 , on DMTBS4)
)
STORAGE( INITIAL 1 ,NEXT 1 , MINEXTENTS 1 ,FILLFACTOR 0)
;
select a.TABLE_NAME ,a.PARTITIONING_TYPE ,a.PARTITION_COUNT from ALL_PART_TABLES a ;
select table_name,partition_name,high_value ,ALL_TAB_PARTITIONS.TABLESPACE_NAME from all_tab_partitions;
--循环插入
BEGIN
FOR i IN 1..500 LOOP
INSERT INTO DMTEST.FANWEI_T1 VALUES(i, 'AAA' || i);
COMMIT;
END LOOP;
END;
/
commit ;
select count(*) from DMTEST.FANWEI_T1_PN ;
3.创建list分区表
--创建 LIST 分区表
drop table if EXISTS DMTEST.list_sales ;
create table DMTEST.list_sales
(
sales_id int,
salman char(20),
saledate datetime,
city char(10)
)
partition by list
(
city
)
( partition p1 values ('合肥','巢湖')
STORAGE (on DMTBS1), partition p2 values ('安庆','怀宁','太湖')
STORAGE (on DMTBS2), partition p3 values ('广州','深圳')
STORAGE (on DMTBS3), partition p_default values (default) STORAGE(on DMTBS4) );
insert into DMTEST.LIST_SALES (sales_id,city) VALUES (1,'合肥') ;
insert into DMTEST.LIST_SALES (sales_id,city) VALUES (2,'安庆') ;
insert into DMTEST.LIST_SALES (sales_id,city) VALUES (3,'广州') ;
insert into DMTEST.LIST_SALES (sales_id,city) VALUES (4,'aa') ;
insert into DMTEST.LIST_SALES (sales_id,city) VALUES (5,'北京') ;
commit;
select T.OWNER, table_name,partitioning_type ,partition_count from all_part_tables t WHERE t.TABLE_NAME = upper('list_sales');
select table_name,partition_name,high_value, TABLESPACE_NAME from all_tab_partitions where TABLE_NAME = upper('list_sales');
4.创建HASH分区表
--创建哈希分区表
drop table if EXISTS DMTEST.hash_SALES01 ;
create table DMTEST.hash_sales01
(
sales_id int,
saleman char(20),
saledate datetime,
city char(10)
)
partition by hash
(city)
(
partition p1 STORAGE (on DMTBS1),
partition p2 STORAGE (on DMTBS2),
partition p3 STORAGE (on DMTBS3),
partition p4 STORAGE (on DMTBS4)) ;
drop table if EXISTS DMTEST.hash_SALES02 ;
create table DMTEST.hash_sales02(
id int,
name varchar(20)
)
partition by hash (id)
partitions 3 STORE in (DMTBS1,DMTBS2,DMTBS3,DMTBS4);
--分区数量不大于表空间数数匹配
select table_name,partitioning_type ,partition_count from all_part_tables t;
select table_name,partition_name,high_value H,TABLESPACE_NAME from all_tab_partitions
where table_name like 'HASH%';
5.创建组合分区表
--创建组合分区表
drop table if EXISTS DMTEST.SALES ;
create table DMTEST.sales(
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 ('2012-04-01'),
subpartition p12 values less than ('2012-07-01'),
subpartition p13 values less than ('2012-10-01'),
subpartition p14 values equ or less than (maxvalue))
(
partition p1 values ('北京', '天津')
(
subpartition p11_1 values less than ('2012-10-01'),
subpartition p11_2 values equ or less than (maxvalue)
),
partition p2 values ('上海', '南京', '杭州'),
partition p3 values (default)
);
select table_name,partitioning_type ,partition_count from all_part_tables t where t.TABLE_NAME = 'SALES';
select table_name,partition_name,high_value,subpartition_count from all_tab_partitions where table_name= 'SALES' ;
--DM 支持最多八层多级分区
--三级分区的例子:
drop TABLE If EXISTS DMTEST.student ;
CREATE TABLE DMTEST.student
(
name VARCHAR(20),
age INT,
sex VARCHAR(10) CHECK (sex IN ('mail', 'femail')),
grade INT CHECK (grade IN (7, 8, 9))
)
PARTITION BY LIST (grade)
SUBPARTITION BY LIST (sex)
SUBPARTITION TEMPLATE
(
SUBPARTITION q1 VALUES ('mail'),
SUBPARTITION q2 VALUES ('femail'),
SUBPARTITION q_default VALUES (DEFAULT) -- 关键:子分区模板增加兜底分区
)
(
PARTITION p1 VALUES (7),
PARTITION p2 VALUES (8),
PARTITION p3 VALUES (9),
PARTITION p4 VALUES (DEFAULT) -- 主分区已有兜底分区
);
select table_name,partitioning_type ,partition_count from all_part_tables t where table_name='STUDENT';
select table_name,partition_name,high_value,subpartition_count from all_tab_partitions where table_name='STUDENT';
6.创建间隔分区
--创建间隔分区
--如果用了间隔函数做分区,在数据插入的时候,如果没有适合的分区,数据库分自动给你创建一个新的分区。
drop table if EXISTS DMTEST.t_interval_year ;
create table DMTEST.t_interval_year (
employee_id int ,
empoyee_name VARCHAR(20),
bir date
) PARTITION BY RANGE (bir) INTERVAL
(
numtoyminterval(1,'YEAR')
)
(
PARTITION P1990 VALUES LESS THAN (TO_DATE('1991-01-01','YYYY-MM-DD')) STORAGE(on DMTBS1),
PARTITION P1991 VALUES LESS THAN (TO_DATE('1992-01-01','YYYY-MM-DD')) STORAGE(on DMTBS2),
PARTITION P1992 VALUES LESS THAN (TO_DATE('1993-01-01','YYYY-MM-DD')) STORAGE(on DMTBS3),
PARTITION P1993 VALUES LESS THAN (TO_DATE('1994-01-01','YYYY-MM-DD')) STORAGE(on DMTBS4)
) ;
select table_name,partitioning_type ,partition_count from all_part_tables t where table_name='T_INTERVAL_YEAR';
select table_name,partition_name,high_value from all_tab_partitions where table_name='T_INTERVAL_YEAR';
INSERT INTO DMTEST.T_INTERVAL_YEAR VALUES(1,'dave','1997-10-24');
INSERT INTO DMTEST.T_INTERVAL_YEAR VALUES(2,'anxy','1998-10-24');
INSERT INTO DMTEST.T_INTERVAL_YEAR VALUES(3,'njin','1999-10-24');
INSERT INTO DMTEST.T_INTERVAL_YEAR VALUES(4,'cqin','2000-11-24');
select table_name,partition_name,high_value, TABLESPACE_NAME from all_tab_partitions where table_name='T_INTERVAL_YEAR';
--ROLLBACK ;
select * from DMTEST.T_INTERVAL_YEAR ;
commit;
–分区重命名
alter table DMTEST.T_INTERVAL_YEAR RENAME PARTITION SYS_P1209_1218 TO P2000 ;
维护内容:
增加分区
删除分区
合并分区:将相邻的两个列表和范围分区合并为一个分区。只能在范围分区上进行合并分区。
拆分分区:将某一个列表和范围分区拆分为相邻的两个分区。只能在范围分区上进行拆分分区;
交换分区:将分区数据跟普通表数据交换功能,普通表必须跟分区表同构(拥有相同的列和索引)。不支持含有加密列的分区表交换分区。
--增加分区
--范围表 如果有maxvalue ,不允许添加分区,可以通过拆分分区
select table_name,partition_name,high_value from all_tab_partitions where table_name='FANWEI_T1';
alter table DMTEST.FANWEI_T1 add PARTITION p4 VALUES less THAN (400) STORAGE (on DMTBS1) ;
--alter table DMTEST.FANWEI_T1 DROP PARTITION pN ;
alter table DMTEST.FANWEI_T1 add PARTITION pn VALUES LESS THAN (maxvalue) ;
--列表 在 DEFAULT 分区已存在时无法添加分区 ,拆分分区
select table_name,partition_name,high_value,TABLESPACE_NAME from all_tab_partitions where table_name='LIST_SALES';
alter table DMTEST.LIST_SALES ADD PARTITION p4 VALUES ('北京','上海') STORAGE (on DMTBS1) ;
--alter table DMTEST.LIST_SALES drop PARTITION P_DEFAULT ;
alter table DMTEST.LIST_SALES ADD PARTITION p_default VALUES (DEFAULT) STORAGE (on DMTBS4) ;
--删除分区
--范围
select table_name,partition_name,high_value from all_tab_partitions where table_name like 'FANWEI%';
alter table DMTEST.FANWEI_T1 drop PARTITION p3 ;
--list
select table_name,partition_name,high_value from all_tab_partitions where table_name like 'LIST%';
alter table DMTEST.LIST_SALES drop PARTITION p4 ;
--合并分区
--仅范围,列表分区表支持合并分区,并且合并的分区必须是范围相邻的两分区。
--范围
select table_name ,partition_name,high_value,TABLESPACE_NAME from all_tab_partitions where table_name like 'FANWEI%';
alter table DMTEST.FANWEI_T1 merge partitions p1, p2 into partition p1_2;
--list
select table_name ,partition_name,high_value,TABLESPACE_NAME from all_tab_partitions where table_name like 'LIST%';
alter table DMTEST.LIST_SALES MERGE PARTITIONS p2 ,p1 INTO PARTITION p2_1 ;
--拆分分区 : 范围,list
--范围
select table_name,partition_name,high_value,TABLESPACE_NAME from all_tab_partitions where table_name like 'FANWEI%';
alter table DMTEST.FANWEI_T1 split partition p1_2 at(100) into (partition p1,partition p2);
--maxvalue
select max(id) ,min(id) from DMTEST.FANWEI_T1_PN ;
alter table DMTEST.FANWEI_T1 split partition pN at(400) into (partition p4 STORAGE (on DMTBS1),partition pN);
--LIST
select table_name ,partition_name,high_value,TABLESPACE_NAME from all_tab_partitions where table_name like 'LIST%';
alter table DMTEST.LIST_SALES split partition P2_1 VALUES ('合肥','太湖') into
(partition p1 STORAGE (ON DMTBS1) ,
partition P2 STORAGE (ON DMTBS2)
);
--default
select * from DMTEST.LIST_SALES_P_DEFAULT ;
alter table DMTEST.LIST_SALES split partition P_DEFAULT VALUES ('北京','上海') into --‘上海’
(partition p4 STORAGE (ON DMTBS1) ,
partition P_DEFAULT STORAGE (ON DMTBS2)
);
select * from DMTEST.LIST_SALES_P4 ;
--交换分区-- 范围 ,list
/*
相同的表结构,索引,相同的分布方式.
几乎不涉及io,效率高.
*/
--范围
drop table if EXISTS DMTEST.jiaohuan_DMTEST ;
create table DMTEST.jiaohuan_DMTEST(
name char(15),
salary int)
partition by range(salary)(
partition p1 values less than (5000),
partition p2 values less than (10000),
partition p3 values less than (15000),
partition p5 values equ or less than (maxvalue)
);
drop table if EXISTS DMTEST.DMTEST_TMP ;
create table DMTEST.DMTEST_TMP(
name char(15),
salary int
)
;
insert into DMTEST.DMTEST_tmp values('dave',8888);
commit ;
select * from DMTEST.JIAOHUAN_DMTEST_P2 ;
select * from DMTEST.DMTEST_TMP ;
alter table DMTEST.JIAOHUAN_DMTEST exchange partition p2 with table DMTEST.DMTEST_TMP;
delete from DMTEST.JIAOHUAN_DMTEST_P2 ;
commit ;
alter table DMTEST.JIAOHUAN_DMTEST exchange partition p3 with table DMTEST.DMTEST_TMP;
1.概述
1.1 功能简介
dmfldr(DM Fast Loader)是 DM 提供的快速数据装载命令行工具。用户通过使用
dmfldr 工具能够把按照一定格式排序的文本数据以简单、快速、高效的方式载入到 DM 数
据库中,或把 DM 数据库中的数据按照一定格式写入文本文件。
1.2 启动dmfldr
安装好 DM 数据库管理系统后,在安装目录的“bin”子目录下可找到 dmfldr 执行文件。
启动操作系统的命令行窗口,进入“dmfldr”所在目录,可以准备启动 dmfldr 工具了。
dmfldr 的使用必须指定必要的参数,否则工具会报错“无效的参数个数”并退出。为dmfldr 指定参数的格式为:
dmfldr keyword=value [keyword=value …]
例如:
dmfldr USERID=SYSDBA/SYSDBA CONTROL=‘c:\fldr.ctl’
如例子所示,USERID 和 CONTROL 是启动 dmfldr 必须要指定的参数,且 USERID 必 须是第一个参数,CONTROL 必须是第二个参数。查看相关参数可以使用 “dmfldr help””查看各参数的简单信息。
1.3 dmfldr 控制文件
控制文件 CONTROL 是启动 dmfldr 必须要指定的参数,用于指定数据文件中数据的格
式。在数据载入时,dmfldr 根据控制文件指定的格式来解析数据文件;导出数据时,
dmfldr 也会根据控制文件指定的列分隔符、行分隔符等生成数据文件。
2.数据装载
2.1基础数据导入装载
2.1.1创建测试表
首先创建测试表 TEST1,4 个字段均为变长字符串类型。
CREATE TABLE "SYSDBA"."TEST1"
(
"C1" VARCHAR2(20),
"C2" VARCHAR2(20),
"C3" VARCHAR2(20),
"C4" VARCHAR2(20)
);
2.1.2准备数据文件与控制文件
准备文本数据文件 test1.txt,编写装载控制文件 test1.ctl。
OPTIONS
(
SKIP = 0
IGNORE_BATCH_ERRORS = TRUE
DIRECT = FALSE
)
LOAD DATA
INFILE '/home/dmdba/dmdbms/test/test1.txt'
INTO TABLE TEST1
FIELDS ','
(
C1,
C2 ENCLOSE BY '"',
C3,
C4
)
--关键参数说明
--SKIP=0:不跳过任何行,从文件第一行开始加载;
--IGNORE_BATCH_ERRORS=TRUE:忽略批量加载错误,不会因为部分行异常终止整个装载任务;
--DIRECT=FALSE:关闭直接路径装载,走常规 SQL 路径;
--FIELDS ',':字段分隔符为逗号;(切记,分隔符使用“,”则为,使用|则为“|”)
--C2 ENCLOSE BY '"':C2 字段内容被双引号包裹,自动去除字段两端引号。
--执行 dmfldr 命令完成装载后,查询表即可看到文本文件内全部数据成功入库。
2.2使用 dmfldr 实现数据导出
dmfldr 不仅支持导入,设置 MODE='OUT' 即可实现表数据导出为文本文件。
2.2.1 业务表准备
CREATE TABLE "SALES"."CUSTOMER"
(
"CUSTOMERID" INT NOT NULL,
"PERSONID" INT NOT NULL
);
SELECT * FROM "SALES"."CUSTOMER";
2.2.2 导出控制文件 test2.ctl
OPTIONS (
MODE = 'OUT'
CHARACTER_CODE = 'UTF-8'
)
LOAD DATA
INFILE '/home/dmdba/dmdbms/test/test2.bat'
REPLACE
INTO TABLE SALES.CUSTOMER
FIELDS '|'
(
CUSTOMERID,
PERSONID
)
--参数说明
--MODE='OUT':开启导出模式,把表数据输出到 INFILE 指定的文件;
--CHARACTER_CODE='UTF 8' 指定输出文件编码;
--FIELDS '|' 使用竖线作为导出字段分隔符。
--执行装载命令后,查看输出文件 test2.bat,数据以|分隔完成导出。
2.3不同字段类型混合装载
实际业务中表经常同时包含数字、字符串字段,演示 INT + VARCHAR 混合表的装载。
2.3.1 创建混合类型表
CREATE TABLE TEST(C1 INT,C2 INT,C3 varchar(100));
2.3.2 控制文件
INFILE '/home/dmdba/dmdbms/test/test.txt'
INTO TABLE test
FIELDS '|'
(
C1 TERMINATED BY ' ',
C2,
C3
)
--TERMINATED BY ' ':指定字段以空格作为结束分隔标记。
执行装载命令,需要指定字符集参数:
dmfldr USERID=SYSDBA/xxx@localhost:5236 CONTROL='/home/dmdba/dmdbms/test/test.ctl' CHARACTER_CODE='UTF‑8'
执行完成查询表,int、varchar 字段均正常写入。
2.4按条件过滤,只加载符合条件的数据
dmfldr 支持 WHEN 语法,只载入满足条件的数据行。案例:只导入 CUSTOMERID 以数字 9 开头的数据。
2.4.1 控制文件 test3.ctl
OPTIONS (
CHARACTER_CODE = 'UTF-8'
)
LOAD DATA
INFILE '/home/dmdba/dmdbms/test/test2.bat'
INTO TABLE SALES.CUSTOMER1
WHEN (1:1) = '9'
FIELDS '|'
(
CUSTOMERID ,
PERSONID
)
--WHEN (1:1) = '9':读取每行第 1 个字符,如果等于 9,才会加载这一行,其余行直接过滤丢弃。
--执行装载之后查询 CUSTOMER1,表里只保留 CUSTOMERID 以 9 开头的记录,实现数据行过滤。
2.5 Shell 环境下转义与引用踩坑重点
在 Linux Shell 调用 dmfldr,引号、特殊分隔符会被 Shell 先行解析
2.6总结
dmfldr 通过控制文件 ctl 统一管理导入导出逻辑,MODE='OUT'切换导出模式;
支持ENCLOSE BY / OPTIONALLY ENCLOSE BY处理带引号的字段;
WHEN条件可以直接在装载阶段过滤行,不需要入库再删除,提升性能;
混合数字、字符串字段时,要注意源文件编码,CHARACTER_CODE参数要和文本文件编码对齐,避免乱码;
Linux Shell 执行命令,特殊符号(引号)要做好转义,Shell 会优先解析命令行符号,很多装载报错根源在这里。
考试中很容易出错的点在于不注意FIELDS参数,导致导入数据时报错参数分析出错,确定好正确的参数分隔符即可,报错如下:
1、dmdis安装
1.创建用户
useradd -g dinstall -m -d /home/dmdis -s /bin/bash dmdis
passwd dmdis
2.创建临时目录(避免系统 /tmp 空间不足)
mkdir -p /home/dmdis/tmp
chown -R dmdis:dinstall /home/dmdis/tmp
3.把安装包所有者改为 dmdis,方便后续操作
chown dmdis:dinstall /opt/dmdis_rev226131_x86_linux_64_20260703.bin
4.切换到 dmdis 用户
su - dmdis
5.设置临时目录环境变量
export DMDIS_INSTALL_TMPDIR=/home/dmdis/tmp
6.进入 /opt,给安装包执行权限,启动安装
cd /opt
chmod +x dmdis_rev226131_x86_linux_64_20260703.bin
./dmdis_rev226131_x86_linux_64_20260703.bin -i
7.启动DMDIS服务
8.访问http://192.168.10.123:8082,输入安装时配置的管理员账号、密码登录管理后台。
考试时登录用户名为admin而非sysdba
2、数据脱敏
2.1 创建数据源:
考试时要求从一个表进行数据脱敏,然后导入另外一个表,因此使用同一个数据源的不同表。
2.2 新建工程:
清洗完成后检查表的数据,按照规则清洗完成即为清洗成功。
文章
阅读量
获赞
