当前位置: 首页 > news >正文

使用DTS迁移工具迁移oracle到DM

文章目录

  • 1概述
  • 2Oracle数据迁移
    • 2.1迁移前准备
      • 2.1.1源端信息统计
        • 2.1.1.1确定迁移的用户和对象个数
        • 2.1.1.2查看源端的字符集、大小写敏感参数
      • 2.1.2目标端信息收集与设置
        • 2.1.2.1数据库初始化信息查询
        • 2.1.2.2设置oracle兼容性参数
    • 2.2迁移前评估
    • 2.3目标端创建表空间与用户
    • 2.4迁移
      • 2.4.1创建迁移并连接源端和目标端
      • 2.4.2配置获取对象的方式和迁移策略
      • 2.4.3进行表定义和注释迁移
      • 2.4.4进行表数据迁移
      • 2.4.5进行主键、索引和约束迁移
      • 2.4.6非表对象迁移
    • 2.5数据对比
      • 2.5.1简单对比
      • 2.5.2DTS对比
    • 2.6更新统计信息
    • 2.8迁移问题处理
      • 2.8.1迁移表定义和注释阶段
        • 2.8.1.1DEFAULT约束表达式无效
      • 2.8.2迁移主键、索引和约束阶段
        • 2.8.2.1表中已存在这样的唯一关键字或主键
      • 2.8.3无效的链接名

1概述

使用在非DM数据库迁移到DM数据库可以使用DTS迁移工具进行迁移,迁移的总体思路就是在DM端初始化一个数据库初始化参数相同的实例,然后评估数据量如果数据量比较大(大于100G)的话建议分批进行迁移,迁移完成后处理迁移过程中遇到的错误问题,在完成全部错误问题处理后,进行数据比对并更新统计信息。
在迁移数据前需要确认源端源端是静止的,不然迁移后的数据比对可能对不上。接着是根据源端的数据库类型设置对应的数据库兼容参数,并且确定迁移的对象数量。
建议迁移顺序:(如果有大表也可以先迁移大表)
(1)表定义和注释的迁移
(2)表数据的迁移
(3)索引约束主键的迁移
(4)非表对象的迁移

2Oracle数据迁移

2.1迁移前准备

目标端数据库在迁移前已经初始化好了,在迁移前需要先明确以下信息。

2.1.1源端信息统计

2.1.1.1确定迁移的用户和对象个数

本次迁移以迁移TEST用户的数据。
通过以下SQL可以判断迁移的对象个数:

select owner,object_type,count(*) 
from all_objects 
where OWNER = 'TEST' -- oracle不限定用户的话执行不出来
group by owner,object_type
order by owner,object_type;-- 或者改查dba_objects:
select owner,object_type,count(*) 
from dba_objects 
group by owner,object_type
order by owner,object_type;

在这里插入图片描述

2.1.1.2查看源端的字符集、大小写敏感参数

本次迁移以迁移TEST用户的数据。
通过以下SQL可以判断迁移的对象个数:

-- 方法1:
select value from nls_database_parameters where PARAMETER='NLS_CHARACTERSET';
-- 方法2:
select userenv('language') from dual;

在这里插入图片描述

可以看到源端是GBK。
在Oracle中表名、字段名、函数名是不区分大小写的,但是表中的数据是区分大小写的,也就是说查某个字段为a的记录可以查出A和a两种记录。也可以通过以下SQL进行查询:

SELECT parameter, value
FROM nls_database_parameters
WHERE parameter IN ('NLS_SORT', 'NLS_COMP');

在这里插入图片描述

NLS_SORT参数:排序规则,BINARY:区分大小写;BINARY_CI:不区分大小写;
NLS_COMP参数:比较规则,BINARY:区分大小写;ANSI:不区分大小写;

2.1.2目标端信息收集与设置

2.1.2.1数据库初始化信息查询

目标端的达梦数据库在初始化的时候一般是参照源端oracle的字符集和大小写敏感参数进行初始化。在迁移前在目标端查一下数据库的初始化信息,因为如果源端和目标端的字符集不一样的话迁移的时候需要进行批量放大,否则字段会超长。

SELECT '页大小',cast(PAGE()/1024 as varchar) union all   SELECT '簇大小',cast(SF_GET_EXTENT_SIZE() as varchar) union all   
SELECT '字符集',CASE SF_GET_UNICODE_FLAG() WHEN '0' THEN 'GBK18030' WHEN '1' then 'UTF-8' when '2' then 'EUC-KR' end union all
SELECT '大小写敏感',cast(SF_GET_CASE_SENSITIVE_FLAG() as varchar) union all
select 'VARCHAR类型长度是否以字符为单位',para_value from v$dm_ini where para_name='LENGTH_IN_CHAR' union all
select '空格兼容模式',para_value from v$dm_ini where para_name='BLANK_PAD_MODE' union all
select '实例名称' 数据库选项,INSTANCE_NAME 数据库集群相关参数值 FROM v$instance union all
select '数据库名',name from v$database union all
select '端口号',para_value from v$dm_ini where para_name='PORT_NUM' union all
select '数据库版本1',substr(svr_version,instr(svr_version,'(')) FROM v$instance union all 
select '数据库版本2', id_code from dual union all 
select '数据库模式',MODE$ from v$instance union all 
SELECT '数据库兼容模式', para_value FROM v$dm_ini WHERE para_name='COMPATIBLE_MODE' union all
select '唯一魔数',cast(permanent_magic as varchar) union all
select 'LSN',cast(cur_lsn as varchar) from v$rlog union all
select 'KEY文件属性',  cluster_type from v$license union all 
SELECT '日志文件大小',TO_CHAR(RLOG_SIZE/1024/1024) FROM V$RLOGFILE;

在这里插入图片描述

2.1.2.2设置oracle兼容性参数

修改参数前先查看参数值并进行备份:

select name,value from v$parameter where name in('USE_PLN_POOL','CALC_AS_DECIMAL','ORDER_BY_NULLS_FLAG','COMPATIBLE_MODE','NUMBER_MODE','VIEW_ACCESS_MODE','SUBQ_EXP_CVT_FLAG','DATETIME_FMT_MODE','DATETIME_FAST_RESTRICT','XA_COMPATIBLE_MODE','PL_SQLCODE_COMPATIBLE'
);

在这里插入图片描述

兼容Oracle数据库模式建议修改以下参数:

alter system set 'USE_PLN_POOL'=1 spfile;
alter system set 'CALC_AS_DECIMAL'=2 spfile;   --科学计算法
alter system set 'ORDER_BY_NULLS_FLAG'=1 both;
alter system set 'COMPATIBLE_MODE' = 2 spfile;
alter system set 'NUMBER_MODE'=1 spfile;--解决float聚合SUM函数小数太长问题
alter system set 'VIEW_ACCESS_MODE'=1 spfile;--指定视图的自主访问控制机制。0:兼容 DM;1:兼容 ORACLE
alter system set 'SUBQ_EXP_CVT_FLAG'=201 both;
alter system set 'DATETIME_FMT_MODE'=0 both;-- 1:19-7月-22 12.09.23. 上午 02022-06-18 00:09:11
alter system set 'DATETIME_FAST_RESTRICT'=0 both; --0的时候可以对时间做to_date
alter system set 'XA_COMPATIBLE_MODE'=1 both;
alter system set 'PL_SQLCODE_COMPATIBLE'=1 spfile;

修改参数后需要重启数据库实例服务。

2.2迁移前评估

如果源端是DM数据库的话大致是可以通过以下查询来判断数据量的:

-- 查询全库数据量:
select db_used_space/1024.0/1024/1024*page GB;
-- 对象个数
select owner,object_type,count(*) 
from all_objects group by owner,object_type
order by owner,object_type;

其他数据库可以查表空间或者数据文件大小来评估,也可以使用DTS工具里面的评估功能,迁移前评估一下迁移的对象数和兼容情况。
新建评估:
在这里插入图片描述

输入源端信息和数据库版本、需要评估的模式:
在这里插入图片描述

然后选择一直点下一步就好了:
在这里插入图片描述

然后进行评估等待评估结果。
对于不兼容的可以双击查看并筛选:
在这里插入图片描述

上面的内容是oracle在DBMS_JOB创建的定时作业不支持迁移:
在这里插入图片描述

这些定时作业可以在迁移之后通过达梦的语法重新进行创建。

扩展:如果要指定oracle的驱动可以从oracle的安装目录下获取对应的jdbc驱动:

# 查询oracle安装目录
echo $ORACLE_HOME
# 也可以直接搜
find / -name "ojdbc*.jar" 2>/dev/null

2.3目标端创建表空间与用户

确定源端待迁移的用户和表空间大小。
在oracle可以通过以下查询判断表空间大小:

SELECT * FROM (
SELECT D.TABLESPACE_NAME,SPACE || 'M' "SUM_SPACE(M)",SPACE - NVL (FREE_SPACE, 0) || 'M' "USED_SPACE(M)",ROUND ( (1 - NVL (FREE_SPACE, 0) / SPACE) * 100, 2) || '%'"USED_RATE(%)",FREE_SPACE || 'M' "FREE_SPACE(M)"FROM (  SELECT TABLESPACE_NAME,ROUND (SUM (BYTES) / (1024 * 1024), 2) SPACEFROM DBA_DATA_FILESGROUP BY TABLESPACE_NAME) D,(  SELECT TABLESPACE_NAME,ROUND (SUM (BYTES) / (1024 * 1024), 2) FREE_SPACEFROM DBA_FREE_SPACEGROUP BY TABLESPACE_NAME) FWHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+)
UNION ALL                                                           
SELECT D.TABLESPACE_NAME,SPACE || 'M' "SUM_SPACE(M)",USED_SPACE || 'M' "USED_SPACE(M)",ROUND (NVL (USED_SPACE, 0) / SPACE * 100, 2) || '%' "USED_RATE(%)",NVL (FREE_SPACE, 0) || 'M' "FREE_SPACE(M)"FROM (  SELECT TABLESPACE_NAME,ROUND (SUM (BYTES) / (1024 * 1024), 2) SPACEFROM DBA_TEMP_FILESGROUP BY TABLESPACE_NAME) D,(  SELECT TABLESPACE_NAME,ROUND (SUM (BYTES_USED) / (1024 * 1024), 2) USED_SPACE,ROUND (SUM (BYTES_FREE) / (1024 * 1024), 2) FREE_SPACEFROM V$TEMP_SPACE_HEADERGROUP BY TABLESPACE_NAME) FWHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+)
ORDER BY 4 DESC)

在这里插入图片描述

可以看到待迁移的TEST的表空间总大小为500MB,只使用了5MB,所以可以按以下命令创建表空间:

create tablespace test datafile '/dmdata/dmdb/test01.dbf' size 512 autoextend on next 128 maxsize 1024;

创建用户并授权:

create user test identified by "密码" default tablespace test default index tablespace test;
grant resource,public,vti,soi,svi to test;

2.4迁移

DTS工具位于安装目录的tool目录下,Linux启动方式:(服务器需要支持图形化界面)

cd /home/dmdba/dmdbms/tool
./dts

迁移的时候建议分批迁移特别是数量比较大的情况下

2.4.1创建迁移并连接源端和目标端

新建工程后,右击【迁移】新建迁移:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.4.2配置获取对象的方式和迁移策略

可以根据本机cpu设置并行度。如果源端和目标端字符集相同就不需要设置批量放大,字符串长度默认就好了,但是本次迁移源端oracle的字符集是GBK,达梦是UTF-8所以建议还是放大两倍;如果源端有非法的日期格式字符串这里也可以设置统一进行转换;
在这里插入图片描述

点击【更多】还可以设置字符集转换并发读取等设置:
在这里插入图片描述

2.4.3进行表定义和注释迁移

选择需要迁移的模式,再勾选“表”:
在这里插入图片描述

选择要迁移的表,之后点击转换:先不要勾选主键!
在这里插入图片描述

等待迁移完成:
在这里插入图片描述

迁移完成后查看是否有失败任务,处理完成后再进行下一步的迁移。
在这里插入图片描述

2.4.4进行表数据迁移

建议在表定义和注释迁移完成后,在同一个工程下创建一个新的迁移单独处理表数据的迁移,后续有问题也可以溯源和查看历史迁移情况。后续的迁移同样也是创建新的迁移。
迁移对象还是只勾选表:
在这里插入图片描述

迁移策略时只勾选迁移数据:
在这里插入图片描述

等待迁移完成:
在这里插入图片描述

2.4.5进行主键、索引和约束迁移

迁移对象还是只勾选表。
迁移策略时只勾选迁移数据:
在这里插入图片描述

等待迁移完成:
在这里插入图片描述

2.4.6非表对象迁移

迁移对象除了“创建模式”和“表”不勾选,其他都勾选:
在这里插入图片描述

选择转换的时候源库存在的类型不一样的话显示的设置内容也不一样,不要像以前一样设置一次就点下一步了。
在这里插入图片描述

一般不需要单独设置这些内容,所以勾选后点击下一步就好了。
如果是重新迁移的话就需要每类对象设置存在的时候先“先删除”;
等待迁移完成:
在这里插入图片描述

2.5数据对比

2.5.1简单对比

可以直接通过对象个数初步判断是否完成迁移:
源端(oracle)查询:

select owner,object_type,count(*) 
from all_objects 
where OWNER = 'TEST' -- TEST为迁移的用户
group by owner,object_type
order by owner,object_type;

在这里插入图片描述

目标端(DM)查询:

select owner,object_type,count(*) 
from all_objects
where owner = 'TEST'
group by owner,object_type
order by owner,object_type;

在这里插入图片描述
在这里插入图片描述

发现索引对不上,是两倍,更新了统计信息也是。
其实是达梦数据库和Oracle在索引的组织方式上存在差异,Oracle:默认创建堆表。达梦默认是索引组织表,主键本身就是通过一个聚簇索引(DM默认是逻辑ROWID号创建聚集索引)。

SELECT owner, index_name, index_type, table_name, uniqueness 
FROM all_indexes 
WHERE owner = 'TEST' 
ORDER BY table_name,index_name;

查询结果可以看到很多:index_type为CLUSTER的聚集性主键索引:
在这里插入图片描述

这些聚集性索引查dba_ind_columns表是查不到定义的,所以如果要对比迁移过来的索引数量可以剔除这些再查一遍就准确了:

SELECT count(*)
FROM all_indexes 
WHERE owner = 'TEST'
and index_type != 'CLUSTER'
ORDER BY table_name,index_name;

在这里插入图片描述

2.5.2DTS对比

DTS自带数据比对功能,在迁移完成后,可以比对数据。
新建比对:
在这里插入图片描述

输入源端和目标端信息后,选择模式:
在这里插入图片描述

添加原表示是源库作为标准去对比目标库:
在这里插入图片描述

等待比对完成:
在这里插入图片描述

查看对比报告:
在这里插入图片描述

只有表定义不一致一般没有什么问题,因为前面批量放大过或者DM有些类型做了转换:
在这里插入图片描述

2.6更新统计信息

在迁移完成后需要在目标端更新统计信息,统计信息更新完成后数据库才可以使用:

DBMS_STATS.GATHER_SCHEMA_STATS('TEST',100,TRUE,'FOR ALL COLUMNS SIZE AUTO');

2.7编译无效对象
迁移完成后虽然再DTS中没有报错,但是再目标端查看是有无效对象的:
在这里插入图片描述
在这里插入图片描述

然后再处理这些无效对象。

2.8迁移问题处理

2.8.1迁移表定义和注释阶段

2.8.1.1DEFAULT约束表达式无效

迁移报错:
在这里插入图片描述
在这里插入图片描述

双击查看详情:
在这里插入图片描述

因为源端是GBK,一个中文字符占2个字节,本质还是值超过定义的长度了,UTF-8字符集一个中文字符是3个字节导致的报错。
在这里插入图片描述

将这个表结构拿出来直接在目标端执行还是会报错的:
在这里插入图片描述

解决方式:重新迁移表结构,在迁移策略出指定字符放大倍数:
在这里插入图片描述

迁移过去后再目标端查看该表结构可以看到:
在这里插入图片描述

2.8.2迁移主键、索引和约束阶段

2.8.2.1表中已存在这样的唯一关键字或主键

解决:
前面迁移表定义和注释的时候勾选了主键导致的冲突:
在这里插入图片描述

查看一下是不是报错的同类型的问题,如果是的话就不需要处理了。

2.8.3无效的链接名

Oracle数据库有dblink用法,通过dblink就可以查全称数据库(即不是当前数据库中的对象),查询语法如下:

select * from  表名@数据库链接名;

其实和普通的select语句不一样的就是多了一个指定dblink的语法,然后就可以查远程数据库了。
扩展:
在oracle有两种方式创建dblink,方法一:配置tnsnames.ora并在里面编写对应远程数据库的别名等信息,然后使用以下命令创建dblink:

create public database link link_name
connect to username identified by password
using 'connect_string';
-- link_name是连接名字,可以自定义
-- username是登陆数据库的用户名
-- password是登陆数据库的用户密码
-- connect_string是数据库连接字符串,即配置在tnsnames.ora的定义的远程数据库别名

方法二:直接通过语法创建,比如创建一个到IP为192.168.30.18,实例名为orcl并且用户名为test密码为oracle的dblink:

create public database link link_local_orcl
connect to test identified by oracle
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.30.181 )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)';

如果迁移后有以下的无效对象:
在这里插入图片描述

说明是dblink失效了,要查看一下源库这个dblink是怎么定义的,如果那个远程的数据库可以连上则需要在目标端也创建相同的dblink到同一个数据库。
查询数据库的所有dblink:

select * from dba_db_links;

在目标端创建:

CREATE OR REPLACE PUBLIC LINK "LINK_LOCAL_ORCL"
CONNECT 'ORACLE' WITH TEST IDENTIFIED BY "oracle" 
USING '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.30.181 )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)';

注意:用户名要大写且不能带引号,否则报错:“-6033: DBLINK连接丢失”!
验证:
在这里插入图片描述

方法一(推荐):到Oracle官网下载对应架构的instantclient客户端,上传服务器然后把后的解压路径加入到dmdba的LD_LIBRARY_PATH中;
(文件:instantclient-basic-linux.x64-19.28.0.0.0dbru.zip)

[dmdba@localhost.localdomain:/home/dmdba]$ cd /soft/
[dmdba@localhost.localdomain:/soft]$ mkdir /dmdata/oci
[dmdba@localhost.localdomain:/soft]$ unzip instantclient-basic-linux.x64-19.28.0.0.0dbru.zip -d /dmdata/oci[dmdba@localhost.localdomain:/soft]$ vi /home/dmdba/.bash_profile
在原有的LD_LIBRARY_PATH后面加上,注意前面有一个冒号
:/dmdata/oci/instantclient_19_28
[dmdba@localhost.localdomain:/soft]$ source /home/dmdba/.bash_profile
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ cp /dmdata/oci/instantclient_19_28/libclntsh.so.11.1 /home/dmdba/dmdbms/bin/libclntsh.so
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ ll libclntsh.so
-rwxr-xr-x 1 dmdba dinstall 82874352 1026 03:39 libclntsh.so
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ ldd libclntsh.so
# 然后重启数据库

方法二:把ORACLEHOME/lib目录的so文件拷贝到ORACLE_HOME/lib目录的so文件拷贝到ORACLEHOME/lib目录的so文件拷贝到DM_HOME/bin目录后再把需要的版本的libclntsh.so.11.1文件链接到libclntsh.so(Oracle 11g客户端:使用 libclntsh.so.11.1)重启达梦数据库:

[root@localhost ~]# mkdir /soft/oracle_so
[root@localhost ~]# chmod -R 755 /soft/oracle_so/
[root@localhost ~]# chown -R oracle:oinstall /soft/oracle_so/
[root@localhost ~]# su - oracle
[oracle@localhost ~]$ cd $ORACLE_HOME/lib
[oracle@localhost lib]$ pwd
/database/oracle/oracle/product/11g/db_1/lib
[oracle@localhost lib]$ cp *.so /soft/oracle_so/
[oracle@localhost lib]$ du -sh /soft/oracle_so/
270M    /soft/oracle_so/
[oracle@localhost lib]$ scp -P 22 -r /soft/oracle_so/ root@192.168.30.175:/soft/

复制过去后到达梦数据库所在服务器175上执行:

[root@localhost.localdomain:/root]# chown -R dmdba:dinstall /soft/oracle_so/
[root@localhost.localdomain:/root]# chmod -R 755 /soft/oracle_so/
[root@localhost.localdomain:/root]# su - dmdba
[dmdba@localhost.localdomain:/home/dmdba]$ cd /soft/oracle_so/
[dmdba@localhost.localdomain:/soft/oracle_so]$ cp *.so $DM_HOME/bin
[dmdba@localhost.localdomain:/soft/oracle_so]$ cd $DM_HOME/bin/
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ chmod +x *.so
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ ldd libocci.so linux-vdso.so.1 =>  (0x00007ffefb08f000)libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd69f4f8000)libm.so.6 => /usr/lib64/libm.so.6 (0x00007fd69f1f6000)libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd69efe0000)libc.so.6 => /usr/lib64/libc.so.6 (0x00007fd69ec12000)/lib64/ld-linux-x86-64.so.2 (0x00007fd69fafc000)
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ ldd libclntsh.so linux-vdso.so.1 =>  (0x00007ffd067e3000)libnnz11.so (0x00007ff16dae1000)libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007ff16d8dd000)libm.so.6 => /usr/lib64/libm.so.6 (0x00007ff16d5db000)libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007ff16d3bf000)libnsl.so.1 => /usr/lib64/libnsl.so.1 (0x00007ff16d1a5000)libc.so.6 => /usr/lib64/libc.so.6 (0x00007ff16cdd7000)libaio.so.1 => /usr/lib64/libaio.so.1 (0x00007ff16cbd5000)/lib64/ld-linux-x86-64.so.2 (0x00007ff1704d4000)
[dmdba@localhost.localdomain:/home/dmdba/dmdbms/bin]$ ./DmServicedmdb restart

达梦社区地址:https://eco.dameng.com/

http://www.dtcms.com/a/560828.html

相关文章:

  • langchain agent的短期记忆
  • 使用DrissionPage和自动化技术实现得物鞋子信息爬取
  • 做网站的是干嘛的为网站添加统计
  • 网站设计的建设目的做网站推销手表
  • [LitCTF 2023]Vim yyds
  • LNMP环境部署 KodBox私有云盘
  • 解决windows docker开发thinkphp6启动慢的问题
  • Rust编译参数与优化控制
  • springboot后端的接口headers
  • day04(11.2)——leetcode面试经典150
  • mysql常识和jdbc工具类的进化以及连接池思想
  • 七.Docker网络
  • 怎么做免费视频网站吗网站建设哪儿好
  • 推荐优质wordpress外贸网站主题
  • TDengine 数学函数 ASCII 用户手册
  • @Builder注解导致mybatis类型匹配错误 Cannot determine value type from string
  • AI模型开发 | 从零部署Deepseek OCR模型,零门槛开发PDF文档解析工具
  • Linux INPUT 子系统实验
  • 1000套实习报告模板大合集+多行业多专业实习总结实践报告素材
  • 百度网站快速优化国内flask做的网站
  • Spring AI--Prompt、多轮对话实现方案
  • 网页模板免费下载网站广州页面制作公司
  • Java:继承与多态
  • 10. 从0到上线:.NET 8 + ML.NET LTR 智能类目匹配实战--Web API 接口与前端集成:部署与生产运维:稳定性、可观测与成本
  • 网站开发招标网网站免费注册会员怎么做
  • linux系统中网络编程的实现
  • Vue-github 用户搜索案例
  • GD32F407VE天空星开发板的电压电流检测
  • 网站优化文章怎么做蔡甸城乡建设局网站
  • 中小企业网站开发韵茵全屋定制家具品牌排行榜前十名