XX公司数据库迁移项目可行性研究与风险评估

XX公司数据库迁移项目可行性研究与风险评估

 

 

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

 

 

 

 

当前版本:1.0.0.0

2016  02 21

 

 

 

 

 

文件状态:

[] 草稿

[  ] 正式发布

[  ] 正在修改

文件标识:

HLD_SERVER_IFS

当前版本:

1.0.0.0

    者:

井方南

完成日期:

2016/02/21

版 本 历 史

版本/状态

作者

参与者

日期

备注

1.0.0.0

井方南

 

2016-02-21

正式文档

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第一部分  文档简介

1 文档说明

1.1编写目的

本说明书定义和阐述XX科技有限公司数据库系统迁移流程与工作量以及对迁移过程中全局的风险评估。

目的在于:

定义清晰的迁移流程;

描述基本的迁移步骤。

风险评估

风险成本控制

工作量评估

迁移成本评估

迁移周期评估

本说明书的预期读者包括:

接口开发人员;

技术管理人员;

数据库DBA

系统管理员

测试人员

合作各方有关部门的负责人。

1.2项目背景

XX公司项目环节包括pc客户端、pad开单器、手机客户端、微信服务端以及后期继续开发的其他客户端,项目服务对象为批发行业的生产商、各级代理商以及经销商和个体户经营者,包括一定规模的消费用户。潜在服务对象囊括了具有一定消费能力和经营能力的所有个体以及组织,数据模型呈现多发交叉级联关系。

 

随着近期XX公司的快速发展,现有的数据模型、库表结构已经成为公司高速发展的严重制约因素,现有的数据库系统严重限制了项目开发效率与质量。随着数据规模的快速上升,现有的sql server数据库系统暴露出无法快速向外扩展、无法升级系统版本、无法快速分表分库以及增大数据库大集群复杂度等突出问题。Sqlserver 数据库系统由于其非开源的特性,增加了后期项目微服务化的复杂度。

       综合以上考虑,现讨论将sqlserver 数据库系统更换为mysql.

为大幅度提升服务器后台程序开发效率,更好的维护管理宝贵的数据资源,集中式管理数据冷热备份,为后期扩展提供基础,提高代码质量编写此文档。

 

1.3业务术语

业务术语

解释

  备注

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.4参考资料

资料名称

版本或日期

作者

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第二部分  迁移目标

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

2.1 mysql 简介

      MySQL 是全球最受欢迎的开源数据库。凭借久经考验的易用性、性能、可靠性和可扩展性,MySQL 成为 Web 应用的首选数据库,部署在众多大型互联网企业(包括 FacebookTwitterYouTubeYahoo! Wikipedia)以及数千家中型企业中。此外,MySQL 还是一款极受欢迎的嵌入式数据库,全球十大软件供应商中有九家的产品中采用了 MySQLMySQL 现在已被全球最大的数据库公司 Oracle 纳入旗下。凭借丰富的资源和深厚的数据库专业技术,Oracle 力求打造一款“超越以往的 MySQL”。为此,Oracle 不断发布新版本的 MySQL,其数量、范围和品质均是 MySQL 过去发展历程中前所未有的。经验丰富的 MySQL 支持工程师为客户提供 24x7 的全球标准支持服务,而且客户还可直接联系 MySQL 开发人员。

MySQL是最流行的开放源码SQL数据库管理系统,是一个真正的多用户、多线程SQL数据库服务器。SQL(结构化查询语言)是世界上最流行的、标准化的数据库语言。MySQL是以一个客户机/服务器结构实现,由一个服务器守护程序mysqld和很多不同的客户程序和库组成。

SQL是一种标准化的语言,它使得存储、更新和存取信息更容易。

MySQL的主要目标是快速、健壮和易用。MySQL最初被开发的原因是因为需要一个SQL服务器--它能处理与任何可不昂贵硬件平台上的数据库在一个数量级上的大型数据库,而且它的速度更快。

在这里推荐使用MySQL的主要原因有以下几点。

 

1)便宜(通常是免费)。

2)网络承载比较少。

3)经过高度最佳化(HighlyOptimized)。

4)应用程序通过它做起备份来比较简单。

5)为各种不同的数据格式提供弹性的接口。

6)较好学且操作简单。

MySql以下的优点足以让我们选择使用她 :

1.避免网络阻塞

针对多个使用者共同存取的支持,MySQL内定最大连接数为100个使用者。但是,即使网络上有大量数据往来,并不会对查询最佳化(Query Optimization)有多大的影响。

 

2.最佳化

数据库结构设计也会影响到MySQL的执行效率,例如MySQL并不支持外来键(Foreign Key),这个缺点会影响到数据库设计以及网站的效率。

 

对于使用MySQL做数据库支持的网站,应该将重点放在如何让硬盘存取减少到最低、如何让一个或多个CPU随时保持在高速作业的状态,以及支持适当的网络频宽,而非实际上的数据库设计以及数据查询状况。

 

3.多线程

MySQL是一个快速、多线程(Multithread)、多使用者且功能强大的关系型数据库管理系统(Relational Database Management SystemRDBMS)。也就是说当客户端与MySQL数据库连接时,服务器会产生一个线程(Thread)或一个行程(Process)来处理这个数据库连接的请求(Request)。

 

4.可延伸性以及数据处理能力

MySQL同时具有高度多样性,能够提供给很多不同的使用者接口,包括命令列、客户端操作、网页浏览器、以及各式各样的程序语言接口,例如C++PerlJavaPHP以及Python

 

MySQL可用于UNIXWindowsOS/2等平台,也就是说它可以用在个人计算机或者是服务器上。

 

5.便于学习

MySQL支持结构化查询语言(Structured Query LanguageSQL),那么精通数据库的人在一天之内,就可以学会MySQL,对于初学者来说也非常容易上手。

 

6.高效升级与维护

MySql 不断被ABOracle公司的数据库团队长期维护,版本不断升级迭代,每一版本总能发布出新特性。全球民间开源组织也不断贡献自己的力量,在数据库引擎和查询优化引擎方面不断推陈出新,使得MySql 发展前景一片大好。

MySql 在分布式、海量数据处理方面有独特优势,其开源特性以及轻量化设计使得她天生适合大规模互联网应用。其不停机升级、优秀的分表分库效率更是锦上添花。

2.2 MySQLSQL Server的使用成本对比

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

MySQL 的年度调查中,低成本是用户选择 MySQL 的首要原因。Microsoft 最近更改了 SQL Server 2012 的定价方式,由以前的按处理器定价改为现在的按内核定价。这样一来,希望采用最新多核硬件的用户需要支付更高的成本。下面的图表对 MySQL 企业版与 Microsoft SQL Server 2012 企业版的数据库 3 年总拥有成本进行了比较。在该配置中,Microsoft SQL Server 2012 的许可成本相比 Microsoft SQL Server 2008 翻了一番。Microsoft SQL Server 3 年总拥有成本比 MySQL 90% 以上。计算细节如下。

 

MySQL Microsoft SQL Server 2012 3 年总拥有成本对比

 



 

 

 

2.3 MySQLSQL Server Express 对比

 

相比于 MySQLMicrosoft SQL Server Express 2012 在特性、支持和性能方面有诸多限制:

1、仅支持 1 CPU 插槽或 4 个内核,而 MySQL 可在 16 路和 64 路系统上实现高效扩展,具体取决于芯片设计。

最多支持 1 GB RAMMySQL 则没有此类限制,而是以操作系统的最大内存容量为上线。

2、每个数据库最多存储 10 GB 用户数据。MySQL 则没有此类限制,可以通过扩展支持数 TB 的配置。

3、不支持 Microsoft SQL Profiler 工具,该工具可帮助定位有问题的 SQL 查询。MySQL 社区版包括通用查询日志和慢查询日志,可捕获全部 SQL 查询或仅捕获’SQL 查询;MySQL 企业版包括 MySQL Enterprise Monitor(含 Query Analyzer),可定位所监视的服务器上所有存在问题的 SQL 代码。

4、不支持 SQL Server AgentMySQL 5.1 版开始提供对事件调度程序的原生支持。

5、仅在用户数据库上提供复制。MySQL 支持现成的主配置和从配置,无需额外付费,也没有任何限制。

6、不支持表和索引分区。MySQL 5.1 版开始支持各种数据分区选项。

 

 

MySql 有如下诸多优势 :

 

MySQL Windows 平台上广受欢迎且久经考验。此外,MySQL 还可以根据需要部署在其他平台上,而 SQL Server 仅支持 Windows 平台。

SQL Server 相比,MySQL 安装速度更快、占用空间更少、需要调优的配置变量更少。然而,MySQL 能够管理 TB 级的大型数据库。

任何 MySQL 数据库都没有大小限制(CPURAM、数据库大小等),而 Microsoft 对其标准版、Workgroup 版、Compact 版及 Express 版均有不同的限制。 .

 MySQL 的特性集可以支持绝大多数 RDBMS 用例(例如 Web、嵌入式、OLTP、托管、SaaS 和云等),并且其实现模型在某些环节(例如分区和复制)比 SQL Server 更加简单。

在高可用性方面,MySQL 针对不同场景提供了许多久经考验的解决方案,包括复制、SAN MySQL Cluster,且均不亚于 SQL Server

事实证明,MySQL 在性能上足以支持 OLTP Web 级负载,支持高端硬件的纵向扩展和跨多台服务器的横向扩展。

MySQL 支持全局性监视和查询分析,更适合同时监视和调优多台服务器,而 SQL Server 一次只能分析一台服务器的性能。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第三部分  迁移基础

3.1迁移基础知识

   请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

 

3.2数据类型

3.2.1同类数据类型

       SQL Server MySQL 中的以下数据类型可一一对应:

      

BIGINT

 BINARY

 BIT

 CHAR

 CHARACTER

 DATETIME

 DEC, DECIMAL

 FLOAT

 DOUBLE PRECESION

 INT, INTEGER

 NCHAR, NATIONAL CHARACTER

 NVARCHAR, NCHAR VARYING

 NATIONAL CHAR VARYING, NATIONAL CHARACTER VARYING

 NUMERIC

 REAL

 SMALLINT

 TEXT

 TIMESTAMP

 TINYINT

 VARBINARY

 VARCHAR, CHAR VARYING, CHARACTER VARYING

 

此外,TIMESTAMP 是一个特殊的数据类型,通常用于存储最近一次创建或更新某行的时间(MySQL 可自动处理此任务)。

 

 

 

3.2.2需要转换的数据类型

 

SQL Server

MySQL

IDENTITY

AUTO_INCREMENT

NTEXT, NATIONAL TEXT

TEXT CHARACTER SET UTF8

SMALLDATETIME

DATETIME

MONEY

DECIMAL(19,4)

SMALL MONEY

DECIMAL(10,4)

UNIQUEIDENTIFIER

BINARY(16)

SYSNAME

CHAR(256)

 

 

 

3.3语法

3.3.1本节列出 SQL Server 支持的 SQL 语法并与 MySQL 支持的等效语法进行对比。

语法分为九类:

 

比较条件语法

存在条件语法

浮点条件语法

IN 条件语法

NULL 条件语法

模式匹配条件语法

范围条件语法

 

 

 

 

 

 

概要

 

SQL Server MySQL 均支持在 SELECTDELETE UPDATE 语句的 WHERE 子句中以及 SELECT 语句的 HAVING 子句中使用条件。

布尔条件

布尔条件将结合其他两个条件,返回一个结果。SQL Server 支持三种布尔条件。

 

要点

 

每个 SQL Server 布尔条件都有一个完全等效的 MySQL 布尔条件,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server 布尔条件

表达式1 AND 表达式2

如果两个表达式均返回 TRUE,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件:AND

NOT 表达式

对表达式结果取反。如果表达式为 FALSE,则返回 TRUE;如果表达式为 NULL,则返回 UNKNOWN;如果表达式为 TRUE,则返回 FALSE

等效的 MySQL 条件:NOT

表达式1 OR 表达式2

 

 

如果任何一个表达式返回 TRUE,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件:OR

比较条件

比较条件对两个表达式进行比较。SQL Server 支持八种比较条件。

 

要点

 

每个 SQL Server 比较条件都有一个完全等效的 MySQL 比较条件,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server 比较条件

表达式1 = 表达式2

如果两个表达式相等,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件: =

表达式1 <> 表达式2

可接受的其他格式(并非每个平台都支持所有形式): != ^= ¬=

如果两个表达式不相等,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件: <> !=

表达式1 < 表达式2

如果表达式1 小于表达式2,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件: <

表达式1 <= 表达式2

如果表达式1 小于或等于表达式2,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件: <=

表达式1 > 表达式2

 

 

如果表达式1 大于表达式2,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件: >

表达式1 >= 表达式2

如果表达式1 大于或等于表达式2,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件: >=

表达式1 比较条件 ANY 表达式2

表达式1 比较条件 SOME 表达式2

同义词。如果比较条件对表达式2 中的至少一个值返回 TRUE,则返回 TRUE;如果比较条件对表达式2 中的每个值均返回 FALSE 或空集(零行),则返回 FALSE

比较条件必须是以下条件之一: = <> < <= > >=.

表达式2 通常是一个子查询,不过也可以解析为任何表达式。

等效的 MySQL 条件:ANYSOME、所提供的表达式2 是一个子查询。

表达式1 比较条件 ALL 表达式2

如果比较条件对表达式2 中的至少一个值返回 FALSE,则返回 FALSE;如果比较条件对表达式2 中的每个值均返回 TRUE 或空集(零行),则返回 TRUE

比较条件必须是以下条件之一: = <> < <= > >=.

表达式2 通常是一个子查询,不过也可以解析为任何表达式。

等效的 MySQL 条件:ANY、所提供的表达式2 是一个子查询。

存在条件

存在条件用于测试子查询中的行。SQL Server 支持两种存在条件。

 

要点

 

每个 SQL Server 存在条件都有一个完全等效的 MySQL 存在条件,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server 存在条件

EXISTS(子查询)

如果子查询 返回至少一行,则返回 TRUE;其他情况返回 FALSE

 

 

等效的 MySQL 条件:EXISTS

NOT EXISTS(子查询)

如果子查询 返回零行,则返回 TRUE,其他情况返回 FALSE

等效的 MySQL 条件:NOT EXISTS

IN 条件

IN 条件测试是否可在某个集中找到某个值。SQL Server 支持两种 IN 条件。

要点

每个 SQL Server IN 条件都有一个完全等效的 MySQL IN 条件,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server IN 条件

表达式 IN {value_list | (子查询)}

如果表达式等于 value_list 中的任意值(或子查询返回的值),则返回 TRUE;如果任何参数为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件:IN

表达式 NOT IN {value_list | (子查询)}

如果表达式不等于 value_list 中的任意值(或子查询返回的值),则返回 TRUE;如果任何参数为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件:NOT IN

NULL 条件

NULL 条件用于测试 NULL 值。SQL Server 支持两种 NULL 条件。

 

要点

 

每个 SQL Server NULL 条件都有一个完全等效的 MySQL NULL 条件,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

 

 

SQL Server NULL 条件

表达式 IS NULL

如果表达式结果为 NULL,则返回 TRUE;其他情况返回 FALSE

等效的 MySQL 条件:IS NULL

表达式 IS NOT NULL

如果表达式结果不是 NULL,则返回 TRUE;其他情况返回 FALSE

等效的 MySQL 条件:IS NOT NULL

模式匹配条件

模式匹配条件用于测试某个值是否与特定模式匹配。SQL Server 支持九种模式匹配条件。

SQL Server 模式匹配条件

string_expression LIKE 模式 [ESCAPE escape_string]

如果 string_expression 与模式匹配,则返回 TRUE;如果任何参数为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

请使用当前(输入)字符集解释所有参数。

等效的 MySQL 条件:LIKE

string_expression NOT LIKE 模式 [ESCAPE escape_string]

如果 string_expression 与模式不匹配,则返回 TRUE;如果任何参数为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

请使用当前(输入)字符集解释所有参数。

等效的 MySQL 条件:NOT LIKE

范围条件

范围条件用于测试特定值是否包含在某个范围内。SQL Server 支持两种范围条件。

要点

每个 SQL Server 范围条件都有一个完全等效的 MySQL 范围条件,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server 范围条件

表达式1 BETWEEN 表达式2 AND 表达式3

如果表达式1 在其他表达式指定的范围内,则返回 TRUE(即表达式1 大于或等

 

 

于表达式2 且小于或等于表达式3);如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件:BETWEEN

表达式1 NOT BETWEEN 表达式2 AND 表达式3

如果表达式1 不在其他表达式指定的范围内,则返回 TRUE;如果任何一个表达式为 NULL,则返回 UNKNOWN;其他情况返回 FALSE

等效的 MySQL 条件:NOT BETWEEN

3.4运算符

    

本文列出 SQL Server Database 支持的内置 SQL 运算符并与 MySQL 支持的等效运算符进行对比。运算符分为五类:

算术运算符

串联运算符

分层查询运算符

集合运算符

 

 

算术运算符

要点

 

每个 SQL Server 算术运算符都有一个完全等效的 MySQL 算术运算符,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server 算术运算符

+

用作一元运算符时,表示正的数值或时间表达式

用作二元运算符时,两个数值或时间值相加。

等效的 MySQL 运算符: +

-

用作一元运算符时,表示负的数值或时间表达式

用作二元运算符时,两个数值或时间值相减。

等效的 MySQL 运算符: -

*

二元运算符;两个数值表达式相乘。

等效的 MySQL 运算符: *

/

二元运算符;两个数值表达式相除。

等效的 MySQL 运算符: /

 

 

 

 

串联运算符

要点

 

SQL Server CONCAT函数对于 MySQL 也同样等效,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

采用默认模式启动 MySQL 服务器时,SQL Server + MySQL CONCAT('string1', 'string2') 相对应。

MySQL 的系统变量 sql_mode 设置为 ANSI 的情况下( PIPES_AS_CONCAT 已设定),SQL Server + 不仅和 MySQL CONCAT('string1', 'string2') 相对应,而且也和 || 相对应。

SQL Server 串联运算符

+

串联字符串和 CLOB 值。

等效的 MySQL 运算符(sql_mode 设置成 PIPE_AS_CONACT ): || 或者 CONCAT('string1', 'string2')

等效的 MySQL 运算符(默认模式):CONCAT('string1', 'string2')

分层查询运算符

要点

 

SQL Server 中的 LEVEL 没有等效的 MySQL 运算符。

 

集合运算符

要点

 

SQL Server 中的 INTERSECT EXCEPT 没有等效的 MySQL 运算符。

所有其他的 SQL Server 集合运算符都有完全等效的 MySQL 集合运算符,因此从 SQL Server 迁移至 MySQL 时无需任何操作。

SQL Server 集合运算符

UNION

合并两个 SELECT 查询。

返回任一 SELECT 找到的所有不同(非重复)行。

等效的 MySQL 运算符:UNION

UNION ALL

合并两个 SELECT 查询。

 

 

 

返回任一 SELECT 找到的所有行,包括重复行。

等效的 MySQL 运算符:UNION ALL

3.5日期函数的转换

日期函数

要点

 

SQL Server 中的大多数日期函数都与 MySQL 相同。

 

日期格式

 

SQL Server

MySQL

YYYYMMDD

YYYYMMDD

YYYY MonthName DD

YY[YY]-MM-DD

MM/DD/YY[YY]

YY[YY]/MM/DD

MM-DD-YY[YY]

YY[YY]-MM-DD

MM.DD.YY[YY]

YY[YY].MM.DD

 

 

 

日期函数

 

SQL Server

MySQL

DATEADD(day, 1, GETDATE())

DATE_ADD(NOW(), INTERVAL 1 DAY)

DATEDIFF(day, GETDATE(), GETDATE()-1)

DATEDIFF(NOW(), NOW() – INTERVAL 1 DAY)

DATENAME(month, GETDATE())

DATE_FORMAT(NOW(), ‘%M’) MONTHNAME(NOW())

DATENAME(weekday, GETDATE())

DATE_FORMAT(NOW(), ‘%W’) DAYNAME(NOW())

DATEPART(month, GETDATE())

DATE_FORMAT(NOW(), ‘%m’)

DAY(GETDATE())

DATE_FORMAT(NOW(), ‘%d’) DAY(NOW()) DAYOFMONTH(NOW())

GETDATE()

NOW() SYSDATE() CURRENT_TIMESTAMP CURRENT_TIMESTAMP()

GETDATE() + 1

NOW() + INTERVAL 1 DAY CURRENT_TIMESTAMP + INTERVAL 1 DAY

GETUTCDATE()

UTC_TIMESTAMP()

MONTH(GETDATE())

MONTH(NOW())

YEAR(GETDATE())

YEAR(NOW())

 

3.6 T-SQL转换建议

由于本迁移项目不含有触发器、过程等内置代码,所以这里对T-SQL的转换不做讨论。

第四部分  迁移风险

由于原数据库结构和数据存在诸多问题与错误,以及与target 数据库差异性比较大,数据迁移过程中需要承担一定的风险以及由此引发的一系列连带工作量。

 

4.1 元数据库结构本身的错误

4.1.1索引问题   

     元数据库的库表结构设计存在对主键这一宝贵资源的严重误解。

            

<!--[if !supportLists]-->1)      <!--[endif]-->主键的设计

元数据库中把基本表的所有主键设计为字符类型的UUID,存在以下风险

         ()  UUID生成策略效率较低,容易引发并发插入异常。

         ()  UUID占用存储空间较大,造成磁盘的严重浪费。

         ()  UUID 需要更多的存储空间,导致索引庞大,致使索引是真实数据的数倍大小。

              例如测试库中 BizGoodsPrice 表存在记录 1066864,数据大小 396.92 MB,索引大小 713.81 MB,接近2倍,表BizGoodsStock 中索引接近真实数据的3倍大小,表 BizGoodsStockDetail 存在记录 3852009,数据大小 1.93 GB,索引竟然高达 4.05 GB

 

              这样的设计属于严重失误,必须更正,当数据规模增长更快更大的时候,极容易造成生产事故。

         ()  UUID作为主键,网络数据传输量的增大,使得接口调用和查询成本飙升,给网络带宽造成极大压力。

         ()  UUID作为主键不够友好,使得程序代码可读性降低。后期维护成本增大。

         (没有认识到聚簇索引的高效性。

 

        重构之后的代码结构摒弃了UUID作为主键的策略,取而代之的是int类型,主键由主键生成器完成,高效的生成效率和计算效率可大幅度提升更新、查询效率。

<!--[if !supportLists]-->2)      <!--[endif]-->非主键索引

库表结构中索引使用泛滥,造成查询效率较低。

4.1.2 字段问题

            元库表结构中存在较多的字段相关问题与错误,导致测试库在转储的过程中多次中断,给生产库的正式转储过程增加了不确定性以及工作量。

            元库表结构存在以下问题与错误 :

 

<!--[if !supportLists]-->(一)<!--[endif]--> 字段中含有空格

元库表在设计阶段由于存在不严谨性,导致库表结构的列属性存在较多的空格,直接致使数据转储失败。

<!--[if !supportLists]-->(二)<!--[endif]--> 字段类型宽泛,没有结合具体业务实际设计,致使查询效率较低,浪费存储空间。 字段多数没有注释,增加后期维护成本。

            

4.1.3乱码问题

        元库表中存在多处插入乱码,直接导致转储中断,增加了生产库转储的不确定性和工作量。

 

 

4.2 数据一致性风险

      生产库在正式的转储过程中,客户端仍在不断地读写, 使用阿里云服务可实现增量操作,但是无法彻底避免数据一致性的问题。需要精确操作, 在转储过程中需要暂停服务,增加服务终止风险。

4.3 原代码结构重构引发的风险

4.3.1数据风险

      代码结构重构之后,由于两种数据库系统存在的差异性,单元测试的局限性、片面性会导致生产库数据出现计划外的错误。

      包括数据不一致、查询结果错误、客户端处理异常等问题。

4.3.2代码风险         

           由于原系统结构没有一定的说明文档 相关的接口文档,接口范围无法得到十分精确的测量,存在接口遗漏或者接口混淆的风险。

 

           原代码结构没有接口测试单元, 容易由此引发一系列的测试风险。

 

 

 

 

 

 

 

 

 

 

 

 

第五部分  迁移成本

5.1  人力成本

    请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

        由于本次数据库转储和代码重构关系到XX公司全部开发项目,所以需要XX公司所有的开发部门参与。

5.2  时间成本

             测试库的转储需要1.5小时,计算错误处理时间 预估在 3小时。

生产库数据规模预估为测试库2.5倍,计算错误处理时间 11.25小时。

        代码重构时间 预计为 15人月,测试周期 2人月,文档编写 2人月。

5.3  营销(机会)成本

        数据库系统的转储以及代码重构会导致项目服务中断,在中断期间销售人员无法正常开展营销活动,同时会给在使用的客户带来中断服务的体验,增大其他服务商机会介入,增加XX运营团队的营销成本。

5.4  其他成本

        由于项目重构和数据转储的不确定性带来的其他连带成本。

 

 

 

 

 

 

 

 

 

 

第六部分  迁移流程

6.1  迁移方案

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

        为尽可能的减少后期数据维护的不确定性,数据的迁移必须和项目代码的重构同步进行,重构之后的项目系统必须运行在转储数据库MySql 上。

        迁移流程图如下。

 

 

 


<!--[endif]-->

 

                                 6.1  XX公司数据转储流程图

 

 

6.1.1 方案一  使用官方迁移工具 MySQLWorkbench

 

   步骤一  配置ODBC数据源

 



 
<!--[endif]-->

 

 


<!--[endif]-->

 

 

 



 

 

 

 

步骤二  配置 MySQLWorkbench 源数据库

 



 

 

 

 

配置目标数据库

 


<!--[endif]-->

 

 

 



 
<!--[endif]-->

 

 

 



 

 



 

 

 

 

 

 

 

 

 



 

 

 

 

等待进度条进行完毕,即可完成数据转储,进入校验阶段。

 

 

6.1.2 方案二  使用程序代码进行转移

        使用程序代码进行转移 :  通过配置一定数量的连接池,使用多线程读取SqlServer 数据源,将读取结果异步提交到多通道队列中,写入多线程从队列中读取数据,写入MySql数据库。

 

        以上方案同样能实现数据转储。

 

 

6.1.3 方案三  使用第三方工具 Navicat Premium

        步骤一 配置原数据库与目标数据库

 

       

 

 

 

步骤二  设置转储参数

 



 

 

 

点击确定开始即可。

 

再配以适当的存储过程进行数据结构的调整,即可完成全部数据的成功迁移。

 

 

 

 

6.1.4 方案小结

        以上提供参考的三种转储方案都进行了部分或者全部实现,通过对测试数据库的转储测试,有以下结论

转储效率排行   :

 方案三 > 方案二 > 方案一

        转储复杂度排行 :

                     方案二 > 方案三 > 方案一

 

 

6.1.5 确定方案

        综合以上三种迁移方案,结合现有数据规模和实际业务需要,以及营销活动需要,考虑成本问题,现采取第三种数据迁移方案。

 

现数据迁移方案详情如下:

 

第一步 数据结构准备

        1 新建数据库,kp_sql_db,设置其字符类型为utf8,



 

 

修改ini文件 ,设置其字符类型都为utf8,并重启mysql服务。

       

        2 拷贝表结构

 

          


 

 

 

 



 

在拷贝表结构的过程中 会出现如下错误

Incorrect column name 'name '

 

这是因为原表结构字段存在 空格,需要提前修正。

目前已知的错误包括表 `WechatChatRoom` `WechatMoChatInfo` 中的name字段。

 



 

 

表结构拷贝结果



 

 

3 检查表数量正确与否

4 抽查表结构

5 抽查表结构状态 basecustomer为例,导出其表结构sql,查看状态。

  验证其 字符编码 CHARSET 是否为utf8 ,字段编码是否为COLLATE utf8_bin

 

第二步 存储引擎修改

 

6 批量修改表引擎

 

SET @DATABASE_NAME = 'kp_sql_db';

 

SELECT  CONCAT('ALTER TABLE `', table_name, '` ENGINE=MyISAM;') AS sql_statements

FROM    information_schema.tables AS tb

WHERE   table_schema = @DATABASE_NAME

AND     `ENGINE` = 'InnoDB'

AND     `TABLE_TYPE` = 'BASE TABLE';

 

 

 

7 查看日志有没有错误信息

 

8 查看表引擎



 

 

第三步 开始传输数据

 

9 开始传输数据

 



 

 

在这一步 需要选取传输的库表,去除不需要的库表,目前暂时有表LemapImages不需要传输,去掉勾选。

 

 

 

 

 

 



 

 

第四步 数据校验

 

10 传输完成之后,简单校验数据。

   校验方法可采取 获取总记录数等方式,具体参照第七部分。

 

11 逐表修改主键

1)      检查当前表中是否存在字段id,如果存在 查看其是否被正常使用。

如果里面存在值,将该表提交审核处。表中存在id字段且没有被使用,

执行脚本 alter table basegoodsimages drop column id; 删除该字段。

然后 去除KID主键策略,之后执行脚本:

alter table basegoodsimages add column id bigint(20) unsigned not null auto_increment,add primary key (id);

 

2)    如果表中不存在id字段,直接去除KID主键策略,执行脚本:

alter table basegoodsimages add column id bigint(20) unsigned not null auto_increment,add primary key (id);

 

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

 

第五步 存储引擎还原

 

12 还原kp_sql_db 存储引擎 InnoDB.

   SET @DATABASE_NAME = 'kp_sql_db';

 

SELECT  CONCAT('ALTER TABLE `', table_name, '` ENGINE=InnoDB;') AS sql_statements

FROM    information_schema.tables AS tb

WHERE   table_schema = @DATABASE_NAME

AND     `ENGINE` = 'MyISAM'

AND     `TABLE_TYPE` = 'BASE TABLE';

 

检查修改之后表的存储引擎。注:一定是一条一条执行。并观察其过程及期间日志。

 

 

 

 

 

项目代码重构方案:

          项目重构之前,必须对涉及到的所有原有接口编写测试用例,用例范式请参照接口文档要求。入参出参务必标明清楚,以供后期代码重构进行数据校对。

          项目重构必须建立在对业务的详细分析的基础上,业务分析模块化,整理成详细的文档作为参考,基于模块化业务文档的基础之上,做以下操作。

           为统一工作任务,制定如下规则步骤。

 

 项目重构之前,务必编写旧版本访问控制接口的测试用例,测试用例编写必须备份入档。

 旧有接口的测试用例编写格式参照接口文档,出参入参必须标明清楚。

 

 1、配置本地maven环境

 

 2、配置本地git环境

 

 3clone 服务器代码

 

 4、使用代码生成器

   

    代码生成器 为项目 kp-builder

    使用步骤为

    (1) 修改项目下 文件db-config.properties 

        根据具体表的实际参数 配置

        TableName=BaseDimValue

         Entityname=BaseDimValue

 

    (2) 使用存储过程 修改原表结构,步骤如下

       1 为表新增 列,名称为 id,添加注释 主键ID

       2 修改存储过程中 三处对应的表明名称。

       3 执行该存储过程。

       4 执行完毕之后,检查id列值是否为数值递增,正确则取消原表主键,修改id列为主键。

       5 运行 kp-builder 项目 GeneralMech 函数,生成 文件 kp_CodeGen3 C盘符根目录。

       6 复制对应的文件到重构项目,编写测试用例 测试。

       7 提交代码。

 

 5、关于git 提交代码

 

    原则上不允许各模块单元直接将代码提交到git主干。

 

    各个模块单元需要在本地新建分支,将模块开发的结果提交到各自的本地和远程分支。

    再切换回master分支,meger分支代码到主干(master)

 

 

 6、关于稳定版本

   

项目开发到一定阶段,需要备份稳定版本,由审核处新建分支,将主干代码备份到稳定分支。

          所有新建索引、sql查询、新建表结构必须提交审核处审核。

第七部分  数据校验

7.1  数据校验

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

7.1.1数据校验方案

(1)   严格检查每张表的记录数

严格对比转储之前元数据库表与转储之后的MySql数据库表的表记录数是否相同,每张表必须执行此步骤。

 

(2)    可通过计算某一列或多列的累加结果集判断数据转储是否成功

       

(3) 查找某一特定范围内的数据完整性来判断转储是否成功。

7.2  系统校验

(1)    使用重构代码进行模块测试

(2)    使用测试单元进行数据完整性测试

(3)    通过一定规模的有效用户检验数据的正确性

 

猜你喜欢

转载自annan211.iteye.com/blog/2308978