- 数据库迁移:技术革新的必经之路
在数字化转型的浪潮中,数据库作为企业数据的核心载体,其迁移工作至关重要。从DB2到南大通用GBase 8s的迁移,不仅是技术的升级,更是业务发展的重要推手。本文将深入探讨这一过程中的关键技术点,为读者提供一份详尽的迁移指南。
- 数据类型映射:构建迁移的桥梁
数据类型是数据库迁移中的基础,正确映射DB2与GBase 8s的数据类型是确保数据完整性和一致性的前提。
1、数字类型
DB2中的SMALLINT、INTEGER、BIGINT等类型在GBase 8s中有着直接的对应关系,包括DECIMAL和FLOAT等类型,为迁移提供了便利。
GBase 8s | DB2 | |
SMALLINT | Integer/ Smallint/ Bigint/ Real/ Double/ Float/ Numeric(p,s)/ Decimal(p,s) | |
size : 2字节 | 范围:-32,767 to 32,767 | |
INTEGER | ||
size : 4 | -2,147,483,647 到 2,147,483,647 | |
BIGINT | ||
size : 8 | -9,223,372,036,854,775,807 到9,223,372,036,854,775,807 | |
DECIMAL | ||
size : | 最多32位有效位的浮点精度 | |
NUMERIC(p,s) | ||
size : p/2+1 | 32位精度浮点数-10E-130 到 10E124 | |
FLOAT | ||
size : 4 | 与C语言中double数据类型的精度相同 | |
SMALLFLOAT/REAL | ||
size : 2 | 与C语言中float数据类型的精度相同 | |
REAL | ||
size : 4 | 与C语言中float数据类型的精度相同 | |
DOUBLE | ||
size : 8 | 与C语言中double数据类型的精度相同 | |
LONG | ||
size : | 与C语言中long数据类型精度相同 | |
SERIAL | ||
size : 2 | 1到 2,147,483,647 | |
BIGSERIAL | ||
size : 8 | 1到 9,223,372,036,854,775,807 | |
MONEY | ||
size : (精度+ 3/4) / 2 | 32位精度浮点数 -10E-130 到 10E124 |
2、字符类型
CHAR | Char(size)/ Varchar(size)/ Long Varchar/ Graphic(size)/ Vargraphic(size)/ Long Vargraphic/ | |
size :n | 1-32767 | |
VARCHAR | ||
size :n | 1-255 | |
LVARCHAR | ||
size :n | 1-32767 | |
NCHAR | ||
size :n | 1-32767 | |
NVARCHAR | ||
size :n | 1-255 | |
CHARACTER VARYING | ||
size :n | 1-255 |
3、日期类型
DATE | Timestamp/ Date/ Time/ | |
size : | YEAR TO DAY | |
DATETIME | ||
size : 总位数/2 + 1 | YEAR TO SECOND YEAR TO FRACTIONS(5) | |
INTERVAL | ||
size : 总位数/2 + 1 | YEAR TO FRACTIONS(5) |
4、大对象类型:
TEXT | Clob/ DbClob | |
size :n | 1-2GB | |
BYTE | ||
size :n | 1-2GB | |
CLOB | ||
size :n | 1-4TB | |
BLOB | Blob | |
size :n | 1-4TB |
5、其它类型:
BOOLEAN | ||
size :1 | T或F | |
ROW | ||
size :n | 自定义 |
6、字符类型
CHAR、VARCHAR等类型在两种数据库中均得到良好支持,简化了迁移过程。
7、时间类型
GBase 8s的DATE和DATETIME类型与DB2中的对应类型在精度上有所差异,需要特别注意TIMESTAMP类型在迁移时的时间精度损失问题。
具体请参考DB2到GBase 8s的数据类型映射
DB2数据类型 | GBase 8s数据类型 | 精度/范围 | 存储长度(字节) |
Char(size) | CHAR(n) | 1≤n≤32,767 | |
Varchar(size) | VARCHAR(n) | 1-255字节 | |
Long Varchar | LVARCHAR(n) | 255-32767字节 | |
Graphic(size) | NCHAR(n) | 1到32,767字节 | |
Vargraphic(size) | NVARCHAR(n) | 1-255字节 | |
Long Vargraphic | NVARCHAR(n) | 1-255字节 | |
Timestamp | DATETIME | year to fraction(5) | 总位数/2+1 |
Date | Date | year to day | 4 |
Time | Datetime | year to fraction(5) | 总位数/2+1 |
Integer | INTEGER | -2,147,483,647 | 4 |
Smallint | SMALLINT | –32,767到32,767 | 2 |
Bigint | BIGINT | –9,223,372,036,854,775,807 到 | 8 |
Real | Real | 2 | |
Double | Double | 8 | |
Float | Float | 4 | |
Numeric(p,s) | Numeric(min(p,32), min(s,32)) | p/2+1 | |
Decimal(p,s) | DECIMAL(min(p,32), min(s,32)) | p/2+1 | |
Clob | Text | 1-2G | |
DbClob | Clob | 1-4T | |
Blob | Blob | 1-4T |
- 表结构的巧妙迁移
1、建表语句
GBase 8s中建表语句与DB2是非常相似的。
语法
CREATE [TEMP] TABLE table-name
(
column-name
{
datatype
| {BYTE|TEXT} [IN {TABLE | BLOBspace-name]}]
}
[DEFAULT default_opts]
[table-constraint-definition][,...]
[column-constraint-definition][,...]
[NOT NULL] [UNIQUE [CONSTRAINT constr-name]][,...]
[UNIQUE (unique-column-list) [CONSTRAINT constr-name]][,...]
[[COLUMN] SECURED WITH label-name]
)
[SECURITY POLICY policy-name]
[WITH NO LOG] [IN DBspace-name] [EXTENT SIZE extent-size]
[NEXT SIZE next-size] [LOCK MODE {PAGE | ROW }]
GBase 8s目前不直接支持中文的表名和字段名。
DB2支持基于查询结果定义一个表,类似物化视图的概念,当在基表中插入数据时,在物化视图表中也有了相应的数据。目前GBase 8s 350版本也支持物化视图的概念。
2、表的分片
GBase 8s的表分片技术允许把表级数据存储在不同的物理位置,将大表分片可以提高用户相应时间,并发性能,存储性能,备份恢复性能和数据装载性能。GBase 8s可以并行地扫描多个磁盘上的分片数据,从而实现内部查询的并行操作,因此采用“分片”技术可以提高查询效率。内部查询的并行化有助于减少对一个复杂查询的响应时间。“表分片”技术与并行数据查询(PDQ)特征联系在一起使用,数据库可以分配多个线程,从所有数据分片上并行地选取数据。此外,还可以仅仅对包含“目标数据”的数据分片进行扫描,从而大幅度地提高了整个系统效率。
表分片方式有两种:轮转分片(Round-Robin) 和表达式分片(Expression-Based)
表达式分片语法对比:
GBase 8s | DB2 |
CREATE TABLE dept (deptno SMALLINT, dname VARCHAR(14), loc VARCHAR(13) ) FRAGMENT BY EXPRESSION deptno < 11 IN dbspace1, deptno >= 11 AND deptno < 21 IN dbspace2, deptno >= 21 AND deptno < 31 IN dbspace3, REMAINDER IN dbspace4; | CREATE TABLE dept (deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13) ) partition by range (deptno) (partition PART1 STARTING MINVALUE IN dbspace1, partition PART2 STARTING 11 ENDING 21 IN dbspace2, partition PART3 STARTING 21 ENDING 31 IN dbspace3, partition PART4 ENDING MAXVALUE IN dbspace4); |
GBase 8s可以使用partition方式来指定分片表的存储位置,这样可以把多个分区放置在同一个dbspace中,避免了太多dbspace,简化维护管理。
Partition语法示例:
CREATE TABLE dept
(
deptno SMALLINT,
dname VARCHAR(14),
loc VARCHAR(13)
)
PARTITION BY EXPRESSION
partition p1 (deptno < 11) IN dbspace1,
partition p2 (deptno >= 11 AND deptno < 21) IN dbspace2,
partition p3 (deptno >= 21 AND deptno < 31) IN dbspace2;
间隔分片,是指分片数据是基于一个间隔值,比如,一个分片是基于一个月,一年或几百万顾客的记录。数据表有一个最初的分片,它是基于一个range语句来定义的。当一条记录不能满足最初的分片时,IDS系统将会自动创建一个分片来存储这条记录,数据库表和索引都可以用这种策略来进行分片。这个过程是不需要DBA参与的。
间隔分片语法示例:
create table order
(
order_num integer not null,
order_date DATE
)fragment by RANGE(order_date)
interval(NUMTOYMINTERVAL(3,'MONTH')) store in (dbs1, dbs2,dbs3, dbs4)
partition Q0 VALUES<'01/01/2014' in dbs1,
partition Q1 VALUES<'04/01/2014' in dbs2,
partition Q2 VALUES<'07/01/2014' in dbs3,
partition Q3 VALUES<'10/01/2014' in dbs4;
GBase 8s的每个分片是一个独立的tablespace,按照tablespace的存储特性,每个分片使用的页上限为16777215,如果dbspace使用16K数据页,那么这个最大值应是256G,超过这个限制将无法向该分片插入数据。
- 索引与性能优化:保障数据检索效率
1、语法
CREATE [UNIQUE|DISTINCT] [CLUSTER] INDEX index-name
ON table-name (column-name [ASC|DESC],...) storage option[online]
语法示例:
GBase 8s | DB2 |
create index zip_ix on customer (zipcode); | create table customer(…) in tabspace index in tabidxspace; |
create index zip_ix on customer (zipcode)in idxdbs; | create index zip_ix on customer (zipcode); |
默认使用btree索引,默认dbspace和表所使用的dbspace一致。而DB2的索引表空间如果需要和表所在的表空间不一致时需要在创建表时指定。
在线创建索引:
create index idx_name on table_name(col_name1,colname2,…) ONLINE;
在创建索引时,使用online关键字,可以在用户访问这张表的同时,进行创建索引操作,而不会造成锁表。online关键字在删除索引时同样有效。
2、索引限制
GBase 8s的索引长度限制于使用的数据页大小相关
常用页大小 | 索引长度限制 |
2K | 387字节 |
4K | 796字节 |
8K | 1615字节 |
12K | 2435字节 |
16K | 3254字节 |
每个索引分片的最大页数2,147,483,647。
3、复合索引
GBase 8s中一个复合索引最多可以使用16个字段做键值,或最多341个键值作为UDR的返回值。这在不同的语言中有不同的上限限制。
4、索引分片
GBase 8s和DB2同样支持索引分片。
创建分片索引的语法与创建分片表的语法非常相似:
CREATE [UNIQUE|DISTINCT] [CLUSTER] INDEX index-definition indexname
on table-name (column-name[,...]) [FILLFACTOR percent] [IN dbspace] [fragment-clause]
FRAGMENT|PARTITION BY
EXPRESSION Expression Fragment Clause|
RANGE (fragment_key) Interval Fragment Clause|
LIST (fragment_key) List Fragment Clause
5、其它
GBase 8s可以根据应用需要,用CLUSTER选项来建立聚集索引,这个选项会对表中的数据按索引的顺序排序。每个表只能建立一个聚集索引。DML语句的数量是判断能否可以建立聚集索引的重要因素,聚集索引上的大量的DML语句会导致性能问题。
- 约束与完整性:确保数据准确无误
GBase 8s在建立约束的语法上与DB2略有不同,需要在迁移过程中进行适当的调整。
语法
CREATE [TEMP] TABLE table-name
(
column-name
{ datatype }
[table-constraint-definition][,...]
[column-constraint-definition][,...]
[NOT NULL] [UNIQUE [CONSTRAINT constr-name]][,...]
[UNIQUE (unique-column-list) [CONSTRAINT constr-name]][,...]
)
[WITH NO LOG][IN DBspace-name] [EXTENT SIZE extent-size]
[NEXT SIZE next-size] [LOCK MODE {PAGE | ROW }]
ALTER TABLE table-nameADD CONSTRAINT UNIQUE (old-column-name[,...])[table-constraint-definition]
GBase 8s建立约束的语法与DB2有所不同。
GBase 8s | DB2 |
PRIMARY KEY(CUST_NUM) CONSTRAINT PK_NUMBER CHECK (EMP_CODE > 100) CONSTRAINT CK_EMPCD | CONSTRAINT PK_NUMBER PRIMARY KEY(CUST_NUM) CONSTRAINT CK_EMPCD CHECK(EMP_CODE>100) |
- 视图与触发器:业务逻辑的抽象与自动化
1、视图
GBase 8s创建视图的语法与DB2类似,但在特有选项上需要进行调整。
创建视图语法:
CREATE VIEW view-name [(column-list)] AS SELECT-statement [WITH CHECK OPTION]
创建视图示例:
create view v_dept (deptno,dname) as
select x0.deptno ,x0.dname from dept x0 ;
GBase 8s建立视图的语句与DB2类似,但DB2中一些特有选项需要删除,如READ ONLY。
由于视图并不是一张实体表,不能对其使用ALTER操作,如果有视图名或字段需要修改,需要将其重建。
2、触发器
GBase 8s在触发器中只支持SQL语句和存储过程,这要求DB2中的逻辑语句在迁移时转换为GBase 8s的存储过程。
DB2允许SQL语句,逻辑语句和存储过程,在触发器中调用。GBase 8s只允许SQL语句和存储过程在触发器内调用。所以,DB2触发器包含的逻辑语句必须转换为GBase 8s的存储过程,然后存储过程由触发执行。
GBase 8s创建触发器常用语法
INSERT触发器的语法:
CREATE TRIGGER trigger_name INSERT ON table_name
BEFORE [WHEN (condition)] (trig_action1,trig_action2,...)|
FOR EACH ROW [WHEN (condition)] (trig_action1,trig_action2,...)|
AFTER [WHEN (condition)] (trig_action1,trig_action2,...)|
[DISABLED|ENABLED]
DELET触发器的语法:
CREATE TRIGGER trigger_name DELETE ON table_name
BEFORE [WHEN (condition)] (trig_action1,trig_action2,...)|
FOR EACH ROW [WHEN (condition)] (trig_action1,trig_action2,...)|
AFTER [WHEN (condition)] (trig_action1,trig_action2,...)|
[DISABLED|ENABLED]
UPDATE触发器的语法:
CREATE TRIGGER trigger_name UPDATE [OF (column,column,...)] ON table_name
BEFORE [WHEN (condition)] (trig_action1,trig_action2,...)|
FOR EACH ROW [WHEN (condition)] (trig_action1,trig_action2,...)|
AFTER [WHEN (condition)] (trig_action1,trig_action2,...)|
[DISABLED|ENABLED]
- 序列与数据一致性:维护数据的有序性
GBase 8s中的序列与DB2的序列在功能上是相同的。
GBase 8s 支持DML语句(CREATE SEQUENCE, ALTER SEQUENCE, RENAMESEQUENCE, DROP SEQUENCE)来操纵序列,多用户可以并发访问同一个序列,每个序列占用8个字节,GRANT和REVOKE语句可以用来更改序列的访问权限。可以为本地数据库中的序列建立同义词。用于调整序列值的CURRVAL和NEXTVAL在同义词中同样适用。
- 数据库结构的导出与导入:简化迁移流程
1、导出数据库结构
从DB2数据库抽取表结构,可以使用db2look工具进行导出。示例:
本地:db2look –d DB_NAME –e -x –o db_dll.sql
远程:db2look –d DB_NAME –e -x –i user_name –w password –o db_dll.sql
-d: 数据库名称:这必须指定
-e: 抽取复制数据库所需要的 DDL 文件
-x: 将生成授权 DDL
2、导入数据库结构
准备工作:
1.导入数据库结构前,必须按照GBase 8s语法格式修改创建对象脚本。
2.创建数据库database_name
导入数据库结构:
执行命令dbaccess database_name schema_file.sql 来将修改好的脚本文件执行,将数据库对象建立。
为了加快数据导入,建议索引和主外键约束等在这里先不要建立,等待数据全部导入后,再开PDQ一并建立。
数据库迁移是一项复杂的系统工程,需要周密的计划和精细的操作。本文提供的DB2至南大通用GBase 8s迁移指南,希望能为正在进行或计划进行数据库迁移的企业和技术人员提供参考和帮助。下一篇我们来说说从DB2至南大通用GBase 8s的数据迁移。