从SQL Server将表和数据迁移到MySQL

 由于一些数据库重构项目的需求,最近遇到很多从SQL Server将表和数据迁移到MySQL的需求。这个需求说简单也简单,说麻烦也麻烦。前不久为了把一张大日志表成功导入到mysql,也折腾了不少时间。现在简单整理下实施方案。

 

首先是表结构的问题:

 

SQL Server中的部分字段类型不能直接沿用到MySQL,需要进行转换,主要有以下几种:



 

 

 然后是数据迁移的问题:

 

数据迁移时,我们采取的是从SQL Server将数据导出为文本文件,然后将文本文件load到MySQL的方式(也尝试过通过etl工具直接迁移,例如SQL Server Integration Service,但是速度实在不理想)。用文本导入的话有几个需要考虑的问题:

  1. 为了保持SQL Server表中的null值,null值需要转化成\N导出;
  2. 由于反斜杠\在load data时是转义符,因此表数据中存有的反斜杠要进行替换变成\\,才能正确导入到MySQL;
  3. 由于源数据的字符类字段中可能本身就含有特殊字符,如换行符回车符等,在导出数据时需要使用特殊分隔符以区分字段和行。

 假设要迁移的表syslog有如下字段:

Column_nameTypeNullable
idintno
Servernamevarcharyes
Dbnamevarcharyes
filenamevarcharyes
Filesizevarcharyes
Backup_start_timedatetimeyes
Backup_end_timedatetimeyes

 

那么在导出数据时可以用如下sql提取数据(有大于8000的数据可以转换成varchar(max)):

select id,
case when Servername is null then '\N' else replace(convert(varchar(8000),Servername),'\','\\') end as Servername,
case when Dbname is null then '\N' else replace(convert(varchar(8000),Dbname),'\','\\') end as Dbname,
case when Filesize is null then '\N' else replace(convert(varchar(8000),Filesize),'\','\\') end as Filesize,
case when Backup_start_time is null then '\N' else convert(varchar(8000),Backup_start_time,121) end as Backup_start_time,
case when Backup_end_time is null then '\N' else convert(varchar(8000),Backup_end_time,121) end as Backup_end_time
from syslog (nolock)

如果表字段很多,提取数据的sql写起来比较麻烦 ,那么可以通过下列语句直接从系统表中拼接语句:

select case is_nullable when 0 then 'replace(convert(varchar(8000),'+name+case system_type_id when 61 then ',121),''\'',''\\'')' else '),''\'',''\\'')' end+name
else 'case when '+name+' is null then ''\N'' else replace(convert(varchar(8000),'+name+case system_type_id when 61 then ',121),''\'',''\\'') end as ' else '),''\'',''\\'') end as ' end+name end +','
From sys.columns (nolock)
where object_id=object_id('syslog')
order by column_id

 上述语句得到的结果是所有字段的转换后输出,加入select和from就可以得到完整的提取sql如下:

select
replace(convert(varchar(8000),id),'\','\\')id,
case when Servername is null then '\N' else replace(convert(varchar(8000),Servername),'\','\\') end as Servername,
case when Dbname is null then '\N' else replace(convert(varchar(8000),Dbname),'\','\\') end as Dbname,
case when Filesize is null then '\N' else replace(convert(varchar(8000),Filesize),'\','\\') end as Filesize,
case when Backup_start_time is null then '\N' else replace(convert(varchar(8000),Backup_start_time,121),'\','\\') end as Backup_start_time,
case when Backup_end_time is null then '\N' else replace(convert(varchar(8000),Backup_end_time,121),'\','\\') end as Backup_end_time
from syslog (nolock)

 这样由于简单的统一化处理,会对非字符类型字段做一些多余的replace,但不会对导出速度有太大影响。

 

 

生成好提取语句后,可以通过SQL Server的数据导入导出工具进行导出。

在源DB上右键,选择导出数据:



 在导出源头输入正确的用户名密码后,导出的目的选择文本文件,并且为了保证中文字符正确迁移,最好采用unicode格式导出:



 
下一步后选择通过查询语句来转换数据:



 

随后在下一窗口填入提取sql的语句,继续下一步到选择分隔符,这里使用特别的自定义分隔符作为行分隔符和列分隔符:



 
 之后完成导出即可生成文件syslog.txt。

 

将导出的文本文件拷贝到mysql所在的linux服务器上后,先将文件进行转码,转为utf8格式:

iconv -f unicode -t utf8 syslog.txt -o syslog.raw

 

然后在mysql中进行load data,按照定义的特殊字符作为分隔(事先应该先把表结构创建好):

load data infile '/tmp/syslog.raw' 
into table syslog FIELDS TERMINATED BY '##$$##' LINES TERMINATED BY '#$#\r\n';

 这样就能把数据完整地导入到MySQL中。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值