37
版权所有 © 2014Oracle /或其关联公司。保留所有权利。 1 Microsoft SQL Server 迁移至 MySQL MySQL ® 白皮书

从 Microsoft SQL Server 迁移至 MySQLfiles.cnblogs.com/files/Xiao-Bing/mysql_wp_ent_oem_SQL_Server_to... · 附录 D — T-SQL 转换建议..... 28 版权所有 © 2014,Oracle

  • Upload
    vokien

  • View
    287

  • Download
    0

Embed Size (px)

Citation preview

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 1

- 1 -

从 Microsoft

SQL Server 迁移至 MySQL

MySQL® 白皮书

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 2

- 2 -

目录

执行概要 ......................................................................................................................... 3

从 SQL Server 迁移至 MySQL 的业务优势 ................................................................ 3

从 SQL Server 迁移至 MySQL 的技术优势 ................................................................ 6

从 SQL Server 迁移至 MySQL 基本概述 .................................................................. 13

总结 .............................................................................................................................. 15

其他资源 ....................................................................................................................... 16

附录 A — 从 SQL Server 迁移至 MySQL — 数据类型 ........................................... 17

附录 B — 从 SQL Server 迁移至 MySQL — 语法 .................................................. 19

附录 C — 从 SQL Server 迁移至 MySQL — 运算符和日期函数 ............................. 25

附录 D — T-SQL 转换建议 ......................................................................................... 28

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 3

执行概要

虽然 MySQL 是当前流行的 LAMP 架构(Linux、Apache、MySQL、PHP/Perl/Python)中广为人知的

“M”,但我们调查显示,Microsoft Windows 现在是下载量最大的 MySQL 使用平台,并始终位列开发平台

之首。随着 MySQL 在 Windows 平台上日益普及,越来越多的企业开始从业务和技术的角度探究从

Microsoft SQL Server 迁移至 MySQL 的必要性。

由于 MySQL 将节约成本、自由选择平台、特性丰富等优势于一身,大多数组织选择从 Microsoft SQL

Server 迁移至 MySQL。本文将深入介绍从 SQL Server 迁移至 MySQL 需要考虑的因素,并提供一些

迁移简化方案。本文将从业务和技术角度探讨迁移至 MySQL 的细节,无论您是管理人员、经验丰富的

DBA 还是开发人员,您都可以从这里了找到为什么以及如何迁移至 MySQL 的许多问题的答案。

.

从 SQL Server 迁移至 MySQL 的业务优势

采用某项技术之前,企业通常会考虑其业务优势和技术优势。尽管每个组织都有自己的考量方式,但通常

取决定性的核心因素是总拥有成本 (TCO) 以及软件供应商的能力评估。

MySQL:全球最受欢迎的开源数据库

MySQL 是全球最受欢迎的开源数据库。凭借久经考验的易用性、性能、可靠性和可扩展性,MySQL 成为

Web 应用的首选数据库,部署在众多大型互联网企业(包括 Facebook、Twitter、YouTube、Yahoo! 和

Wikipedia)以及数千家中型企业中。此外,MySQL 还是一款极受欢迎的嵌入式数据库,全球十大软件供

应商中有九家的产品中采用了 MySQL。MySQL 现在已被全球最大的数据库公司 Oracle 纳入旗下。凭借

丰富的资源和深厚的数据库专业技术,Oracle 力求打造一款“超越以往的 MySQL”。为此,Oracle 不断

发布新版本的 MySQL,其数量、范围和品质均是 MySQL 过去发展历程中前所未有的。经验丰富的

MySQL 支持工程师为客户提供 24x7 的全球标准支持服务,而且客户还可直接联系 MySQL 开发人员。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 4

图 1:行业领军企业均依赖 MySQL

SQL Server 与 MySQL 的使用成本对比

在 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% 以上。计算细节如下。

图 2:与 SQL Server 2012 的 3 年总拥有成本对比

硬件配置: Intel x86_64 服务器:4 台,CPU/服务器:4 颗,内核/CPU:8 核

$0

$500,000

$1,000,000

$1,500,000

$2,000,000

MySQL Enterprise Edition

Microsoft SQL Server Enterprise Edition

60000 美元

1539776 美元

MySQL 与 Microsoft SQL Server 2012 的

3 年总拥有成本对比

MySQL 企业版

Microsoft SQL Server

企业版

2000000 美元

1500000 美元

1000000 美元

500000 美元

0 美元

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 5

Microsoft 价格上涨

针对希望利用最新多核硬件的用户,Microsoft 提高了 Microsoft SQL Server 2012 的价格。

Microsoft SQL Server 2012 按内核进行收费。

Microsoft SQL Server 与 MySQL 的对比:数据库 3 年总拥有成本

下表简单比较了 MySQL 企业版和 Microsoft SQL Server 企业版的许可成本。

定价基于公开的标价信息:

Microsoft SQL Server http://www.microsoft.com/sqlserver/en/us/future-editions/sql2012-licensing.aspx

MySQL 企业版: http://www.mysql.com/products/

硬件配置:

- Web 应用(无限用户) - Windows - Intel x86_64 - CPU/服务器:4 - 内核/CPU:8 - 服务器总数:4 - CPU 总数:16 - 内核总数:128

标价 Microsoft SQL Server 企业版

许可 + 3 年支持服务

MySQL 企业版

3 年订阅

许可标价 6874 美元/内核 不适用

支持服务标价 标价的 25% 不适用

订阅标价 不适用 5000 美元/服务器/年

年度节省成本 SQL Server 企业版 MySQL 企业版

年度支持服务 219968 美元 不适用

年度订阅 不适用 20000 美元

年度节省成本(美元) 199968 美元

年度节省成本 (%) 91%

3 年总拥有成本节省 SQL Server 企业版

许可 + 3 年支持服务

MySQL 企业版 3 年订阅

总许可成本: 879872 美元 不适用

总支持服务费用(3 年) 659904 美元 不适用

总订阅费用(3 年) 不适用 60000 美元

合计(3 年) 1539766 美元 60000 美元

总节省成本(美元) 1479766 美元

总节省成本 (%) 96%

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 6

从 SQL Server 迁移至 MySQL 的技术优势

从 SQL Server 迁移至 MySQL 的另一个考量因素是对数据库的特性集和功能进行技术评估。

与 Microsoft SQL Server 不同,MySQL 支持所有主要的操作系统和平台组合,包括 Linux、Windows、

Mac OS 和 Solaris 等。MySQL 用户不存在单一操作系统或平台依赖性,可以灵活地将 MySQL 部署在

异构计算环境中。

此外,简单易用是 MySQL 最初就确立的一个设计目标。为了让 Windows 用户能够更轻松地使用

MySQL,Oracle 针对 Windows 平台推出了一个统一的点击式 MySQL 安装程序。这个 MySQL 安装程

序从根本上简化了 Windows 平台上所有 MySQL 用户的安装、更新和配置过程。使用 MySQL 安装程序,

从下载 MySQL 数据库到让 MySQL 系统在您的环境中启动、运行和准备使用只需 3 分钟的时间!

安装完成后,丰富的自我管理特性(例如自动空间扩展、自动重启和动态配置变更)帮助数据库管理员摆

脱了超负荷工作状态。此外,MySQL 还提供了一些可视化的数据库设计、开发、管理和监视工具,为

Windows 数据库开发人员和 DBA 提供舒适的用户体验。

MySQL 特性

MySQL 在设计上侧重于高性能、可靠性和易用性,并且将不断完善这些特性。在核心特性方面,DBA 和

CIO 很高兴地发现 MySQL 包含了所有必要的功能,可满足大多数应用需求,尤其是 Web 、企业定制和

嵌入式数据库应用:

数据库特性 MySQL

是否支持

开源许可和商业许可

适用于所有主要平台(32 位和 64 位),包括:Windows Oracle、Linux、

RedHat、Ubuntu、Debian、SuSE、Fedora、Solaris、FreeBSD、MacOS

ANSI SQL、子查询、联接、游标和预处理语句

存储过程、触发器、SQL 和用户定义的函数

可更新视图

支持提交和回滚的 ACID 事务

分布式事务

行级锁定

快照/一致、可重复的读取(读取程序不会阻塞写入程序,反之亦然)

服务器实施的引用完整性

强大的数据类型支持:(数值、VARCHAR 和 BLOB 等。)

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 7

高精度数值数据类型

强健的索引:(簇、B 树、散列、全文本)

动态内存缓存

独有的查询缓存

基于成本的优化器

Unicode、UTF-8

XML、XPath

地理空间支持

复制:(基于行和基于语句)

通过线程池确保高度可扩展性

通过自动故障切换(从服务器升级为主服务器)实现高可用性

分区:(范围、列表、散列、键、组合)

VLDB (TB) 支持

高速数据导入/导出/逻辑备份实用程序

联机备份且支持时间点恢复

自动重启/崩溃恢复

自动存储管理:(自动扩展、撤销管理)

压缩和归档表

信息模式/数据字典

强健的安全性:(SSL、细粒度对象权限)

内置数据加密和解密

可插入身份验证,适用于:Microsoft Active Directory、Linux PAM、LDAP

审计

内置作业/任务调度程序

驱动程序(ODBC、JDBC、.NET 和 PHP 等)

GUI 工具:数据建模、管理、SQL 开发、迁移

图 3:MySQL 特性

如上所示,MySQL 包含一个非常强大的特性集,所提供的功能可支持传统上以 SQL Server 为部署对象

的大多数应用。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 8

MySQL 与 SQL Server Express 对比

Microsoft 于多年前推出了 SQL Server Express。一些行业观察人士认为这项举措旨在与 MySQL 等一些

开源数据库相抗衡。

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

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

决于芯片设计。

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

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

不支持 Microsoft SQL Profiler 工具,该工具可帮助定位有问题的 SQL 查询。MySQL 社区版包括

通用查询日志和慢查询日志,可捕获全部 SQL 查询或仅捕获 ‘慢’SQL 查询;MySQL 企业版包括

MySQL Enterprise Monitor(含 Query Analyzer),可定位所监视的服务器上所有存在问题的 SQL

代码。

不支持 SQL Server Agent。MySQL 从 5.1 版开始提供对事件调度程序的原生支持。

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

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

MySQL 企业版的生产部署

为了满足业务关键型应用对安全性、性能和可靠性的极致要求,Oracle 推出了 MySQL 企业版,并提供

24x7x365 的全球技术支持。MySQL 企业版具有最全面的高级特性、管理工具和技术支持,可帮助您实现

最高水平的 MySQL 可扩展性、可靠性、安全性和无故障运行时间。MySQL 企业版可在开发、部署和管

理业务关键型 MySQL 应用的过程中降低风险、削减成本和减少所需的时间。

除了 MySQL Database 之外,MySQL 企业版还包括:

MySQL Enterprise Monitor MySQL Enterprise Monitor 使您能够了解 MySQL 数据库运行状况的概况。它可以持续监视 MySQL 服

务器并且可提醒您注意可能会对系统产生影响的潜在问题。这样一来,DBA 和系统管理员便可在更短的时

间内管理更多服务器。它还可以在开发环境中用于测试和调优,帮助在产品投入生产环境之前优化查询和

性能,也可供 ISV 和 OEM 用户在发布产品之前使用。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 9

图 4:MySQL Enterprise Monitor

MySQL Enterprise Monitor 提供以下功能:

性能和可用性监视 — 持续监视 MySQL 正常运行时间和可用性,以及与性能相关的服务器指标。

可视化查询分析 — 监视查询性能并定位导致性能下降的 SQL 代码。

InnoDB 监视 — 监视影响 MySQL 性能的主要 InnoDB 指标。

磁盘监视 — 通过趋势分析和预测功能来预测未来的容量需求。

安全监视 — 找到所有 MySQL 服务器中的安全漏洞并进行相应的处理。

操作系统监视 — 监视操作系统级性能指标,包括平均负载、CPU 使用情况、RAM 使用情况和

Swap 使用情况。

MySQL Cluster 监视 — 监视影响性能和可用性的主要 MySQL Cluster 指标。

复制监视 — 了解所有 MySQL 主服务器和从服务器的性能和运行状况。

备份监视 — 确保联机热备份按照预期运行。

MySQL Query Analyzer

MySQL Query Analyzer 通过监视查询和准确查明导致系统变慢的 SQL 代码,帮助开发人员和 DBA 提

高应用性能。借助 MySQL 连接器插件,Java、Microsoft .NET 和 PHP 应用可与 MySQL Query

Analyzer 直接通信,从而获得巨大的性能和效率提升。

MySQL Query Analyzer 可在一个聚合视图中呈现所有 MySQL 服务器的查询,这样 DBA 和开发人员便

可筛选特定的查询问题,分析占用资源最多的代码。借助 MySQL Query Analyzer,DBA 可以在开发过程

中完善 SQL 代码,在生产环境中持续监视和调优查询。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 10

MySQL 顾问程序

MySQL Enterprise Monitor 提供了 250 多项 MySQL 顾问规则和图表,可监视特定于 MySQL 和操作系

统的变量,进而帮助您自动实施 MySQL 建议的数据库最佳实践。MySQL 顾问程序提供的专家意见来自

构建 MySQL 数据库的数据库专家,还提供一些量身定制的分步说明来解决具体的问题或执行性能调优。

MySQL Workbench MySQL Workbench 是一个统一的可视化工具,可帮助开发人员、DBA 和数据架构师设计、开发和管理

MySQL 服务器。MySQL Workbench 提供了高级数据建模功能、一个灵活的 SQL 编辑器和一系列全面

的管理工具。

MySQL Workbench:简化了从 SQL Server 迁移至 MySQL 的过程

MySQL Workbench 还为将 Microsoft SQL Server 数据库表、对象和数据迁移至 MySQL 提供了一个全

面、简单易用的解决方案。开发人员和 DBA 可以轻松、快速地转换现有应用,使其利用 MySQL 可运行

在 Windows 以及 MySQL 支持的任何其他操作系统上。

图 5:MySQL Workbench Migration Tool

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 11

MySQL Workbench Migration Tool 提供了一个易于使用的、可视化、点击式界面,可帮助 DBA 和开发人

员更加快捷地完成配置和管理 SQL Server 至 MySQL 迁移过程的所有阶段:

迁移项目管理 — 配置、复制、编辑、执行和调度迁移。

源和目标选择 — 定义具体的数据源并在迁移之前分析源数据。

对象迁移 — 选择要迁移的对象、根据需要指定从源到目标的映射、编辑迁移脚本以及创建目标模式。

数据迁移 — 映射源数据、目标数据和数据类型,设置数据传输以及根据需要指定数据传输完成之

后的活动。

使用 MySQL Workbench Migration Tool,用户可在数分钟内将现有数据库转换至 MySQL,传统的手动方

式则需要数小时或数天时间。

MySQL 针对 Windows 平台的改进

Oracle 对 MySQL 在 Windows 平台上的性能、开发、管理和易用性进行了显著改进。

性能提升 — 与 MySQL 5.1 相比,MySQL 5.5 在读/写操作方面实现了高达 1500% 的性能提升,

同时在只读操作方面实现了高达 500% 的性能提升。

此外,与 MySQL 5.5 相比,MySQL 5.6 将读/写操作性能提升了 47%,只读操作性能提升了 65%。

MySQL 连接器/.Net — Windows 开发人员可以创建需要与 MySQL 建立安全、高性能数据连接

的 .NET 应用。MySQL 实现了必要的 ADO.NET 接口(包括对 Entity Framework 的支持)并且将

其集成到了可感知 ADO.NET 的工具中。

Windows 版 MySQL 安装程序 — 如前所述,该工具提供了一个简单易用的向导式用户界面,可引

导用户在三分钟内完成整个安装过程。

MySQL for Visual Studio — 支持在 Visual Studio 中访问 MySQL 对象和数据。MySQL for

Visual Studio 作为一个 Visual Studio 程序包进行设计和开发,可直接集成到 Server Explorer 中,

让用户能够无缝地建立新连接以及操作数据库对象,其特性包括:

o 设计时支持

o 查询设计器

o 存储例程调试

MySQL for Excel Application 插件 — 该插件可让用户更加便捷地在 Microsoft Excel 中访问和操

作 MySQL 数据,方便了非技术型业务分析人员使用数据库功能。

MySQL Notifier — 通过 Windows 版 MySQL Notifier 应用,开发人员和 DBA 可以在熟悉的

Microsoft SQL Server 界面中轻松地监视、启动和停止所有 MySQL 数据库实例。该工具集成在

MySQL Workbench 中。

MySQL 企业级备份

MySQL 企业级备份能够执行 MySQL 数据库联机“热”备份。您将获得一致的数据库副本,可将数据恢

复至精确的时间点。此外,MySQL 企业级备份还支持创建压缩的备份文件以及对 MySQL 表的子集进行

备份。与实际数据库文件相比,压缩通常可将备份文件缩小高达 90%,有助于降低存储成本。与 MySQL

二进制日志结合使用时,用户可执行时间点恢复。MySQL 企业级备份可通过 Secure Backup to Tape

(SBT) 接口集成磁带和其他介质管理程序,例如 Oracle Secure Backup、Symantec Net Backup、Tivoli

Storage Manager 和 EMC Networker 等。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 12

MySQL 企业级可扩展性

MySQL 企业级可扩展性选项可帮助您满足不断增长的用户、查询和数据负载对性能和可扩展性的要求。

MySQL 可处理数千个应用连接。MySQL 线程池提供了一个高效的线程处理模型,旨在降低客户端连接和

语句执行线程的管理开销。

MySQL 企业级安全性

MySQL 企业级安全性提供了一些随时可用的外部身份验证模块,可将 MySQL 轻松集成到现有安全基础

架构中,包括 LDAP 和 Windows Active Directory。您可使用可插入身份验证模块( “PAM”)或

Windows OS 原生服务对 MySQL 用户进行身份验证。

MySQL 企业级审计

MySQL 企业级审计提供了一个简单易用、基于策略的审计解决方案,可帮助组织实施更加严格的安全控制

和满足法规要求。它可以帮助用户:

动态启用/禁用审计流

实施策略来记录所有或选定的登录活动或查询活动

根据文件大小自动轮换审计日志文件

将基于 XML 的审计日志流与 MySQL、Oracle 和其他第三方解决方案相集成。

MySQL 企业级高可用性

MySQL 企业级高可用性有助于确保数据库基础架构的高可用性。MySQL 提供了一些经过认证和广受支持

的解决方案,包括 MySQL 复制、适用于 MySQL 的 Oracle VM 模板和适用于 MySQL 的 Windows 故

障转移集群。

Oracle 标准 MySQL 支持服务

MySQL 企业版提供 24x7x365 的技术支持服务,用户可直接联系 Oracle 的 MySQL 支持团队。该团队

由经验丰富的数据库专家组成,可帮助您解决最为复杂的技术问题。Oracle 标准 MySQL 支持服务提供:

24x7x365 电话和在线支持

快速诊断和解决复杂问题

无限制的支持事件

紧急热修复构建,向前兼容未来的 MySQL 版本

访问 Oracle MySQL 知识库

咨询式支持服务

可获得 29 种语言的 MySQL 支持服务

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 13

从 SQL Server 迁移至 MySQL 基本概述

下图概述了从 SQL Server 迁移至 MySQL 的三个基本步骤:

图 6:从 SQL Server 迁移至 MySQL 的三个基本步骤

流程自动化

令人欣喜的是,MySQL Workbench Migration Tool(或 Wizard)可实现上述步骤中许多流程的自动化。市

面上也有许多其他不错的产品支持对多种数据源(包括 SQL Server)进行反向工程。

有关 MySQL Workbench Migration Wizard 的详细技术概述和使用指南,请参阅

《MySQL Workbench Migration Wizard 指南:从 Microsoft SQL Server 迁移至 MySQL》

- http://www.mysql.com/why-mysql/white-papers/guide-to-workbench-migration-wizard/

MySQL 支持所有的核心数据库类型、表设计和索引结构,因此将数据和索引结构移至 MySQL 通常是一

项简单的任务。有关 SQL Server 与 MySQL 之间数据类型和其他要素的全面对比信息,请参阅本文的附

录 A-C。附录 D 提供了将 SQL Server 模式迁移至 MySQL 的详细步骤示例。

有一些 SQL Server 对象并没有完全等效的 MySQL 对象。同义词和安全角色就属于这种情况。迁移过程

中实际代码和代码对象的处理往往更具挑战性。SQL Server 的 Transact-SQL 语言提供了丰富的开发人

员特性,其中许多特性都不符合 ANSI SQL 标准,因此需要检查所有的存储过程、触发器、视图和用户定

义的函数等。除了一般的语法、函数和特性差异外,以下各项还需要进行特别处理才能完全从 SQL Server

迁移至 MySQL:

组合件

专用或自定义数据类型

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 14

DDL 触发器和基于语句的触发器(MySQL 支持基于行的触发器)

专有 SQL Server 函数调用

某些动态 T-SQL

在不需要使用这些特性的情况下,迁移过程会更简单。

非此即彼?

许多 MySQL 客户会选择采用这样一种成功的战略 — 使用 MySQL 支持新应用,将不需要 SQL

Server 高度专业化特性的现有应用迁移至 MySQL,继续使用 SQL Server 支持对专业化数据库有更高

需求的应用。

结合使用 MySQL 与 SQL Server

MySQL 与 SQL Server 结合使用时,负责管理这两个平台的 DBA 应考虑采用哪些最佳实践技巧?虽然

不够详尽,但以下建议可帮助确保 DBA 尽可能高效地开展工作:

如果选择了正确的产品,数据库工具将大幅提升工作效率。除了 MySQL Workbench 外,许多第

三方数据库工具现在都支持同时使用 MySQL 和 SQL Server,因此 DBA 应研究这些工具是否能

够创造切实的收益。例如,Quest TOAD 能够节省时间,因此许多 DBA 选择在 SQL Server 中

使用它。Quest 提供的 TOAD for MySQL 产品可以让习惯于 TOAD 界面的 DBA 轻松上手

MySQL。Embarcadero 的 DBArtisan 产品也是如此,它支持 SQL Server 和 MySQL,可用于

管理这两个平台。当然,DBA 还可以使用数据库供应商提供的工具(例如 SQL Server

Management Studio 产品,当然,Oracle 提供了 MySQL Workbench)。

习惯于让 SQL Server 自动处理任务的 SQL Server DBA 应采用同样的互补性 MySQL 特性,从

而避免额外的管理工作。这包括让 InnoDB 表空间文件自动增长(这对应于启用 SQL Server 数

据和日志文件的自动增长属性)、设置 MySQL 二进制日志以进行时间点恢复(这对应于在 SQL

Server 中使用完全恢复模式),等等。

与 SQL Server 中一样,分配大量内存可帮助 MySQL 提升性能,因此应根据所采用的底层引擎,

确保提供足够的 RAM 来支持从内存中访问数据(而不是从磁盘中读取数据),因为 MySQL 为

大多数企业应用提供的默认值都太低了。与 SQL Server 中一样,应意识到始终从 RAM 中读取

数据并不代表实际的 SQL 代码效率很高。不必要的逻辑 I/O 也会像物理 I/O 那样影响性能。

MySQL 中的簇索引与 SQL Server 中的簇索引略有不同,具体表现在:

o 簇索引仅适用于 InnoDB 存储引擎,因此建议使用 Innodb 处理所有转换后的表。

o 簇索引必须基于表的主键构建。

o 如果 InnoDB 表中未明确定义簇索引,MySQL 将自动基于主键、某个唯一键(如果没有

主键)或某个内部行标识符(如果表中没有唯一性约束)创建一个簇索引。

与 SQL Server 不同,MySQL 中的分区功能不需要创建分区函数或分区方案。而是在表的创建

DDL 中定义分区和分区类型(范围、散列、键、列表、组合)。

与 SQL Server 2005 及更高版本不同,MySQL 自动启用“快照读取”(这样,读取程序不会阻

塞写入程序,反之亦然),无需设置数据库选项或在 SQL 语句前通过特殊的命令来确保快照隔离

读取。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 15

由于效率低下的 SQL 会对 MySQL 数据库造成严重的负面影响,所以 MySQL DBA 应从一开始

就启用慢日志,以便捕获调优效果欠佳的 SQL 代码并定期查看日志结果。此外,用户还可以查看

MySQL Workbench 性能视图,或者通过利用 MySQL Performance Schema 的 MySQL

Enterprise Monitor 获取更详细的信息。在 MySQL 中,用户可以设置慢日志或通用日志对 SQL

Server 动态管理视图或 SQL Profiler 工具中的结果进行镜像,以便找到有问题的 SQL 代码。可

以通过 SQL 查询 MySQL 提供的 SQL 性能表,获取效率低下的代码指标。根据其他性能监视

建议,还可以使用 MySQL SHOW GLOBAL STATUS 和 SHOW INNODB STATUS 命令分析原

始 MySQL 性能指标。包含 Query Analyzer 的 MySQL Enterprise Monitor 提供了一些更高级的

监视和建议功能,DBA 在大多数部署了 MySQL 的生产环境中都应使用该工具。

MySQL DBA 应使用 SQL Server 错误/通知日志检查计划来检查 MySQL 错误日志,从而避免任

何可能的异常行为。

习惯使用 SQL Server Agent 调度和执行 SQL/T-SQL 作业的 DBA 可以利用 MySQL 中的事件

调度器完成同样的任务。

其生产应用需要持续监视的 DBA 应评估 MySQL 企业版,这是因为这个经过认证的软件可提供

高可靠性,而内置的软件升级和监视/咨询工具则有助于主动保证正常运行并协助诊断和解决性能

问题。

总结

无论是从业务角度还是从技术角度,从 SQL Server 迁移至 MySQL 都是一项颇具回报的举措。不计其数

的组织通过使用 MySQL 支持其 Web 应用、定制企业应用和嵌入式应用,节省了大量成本。

从 Microsoft SQL Server 迁移至 MySQL 的理由有很多,除 TCO 可节省 90% 以上外,还包括:

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

台上,而 SQL Server 仅支持 Windows 平台。

与 SQL Server 相比,MySQL 安装速度更快、占用空间更少、需要调优的配置变量更少。然而,

MySQL 能够管理 TB 级的大型数据库。

任何 MySQL 数据库都没有大小限制(CPU、RAM、数据库大小等),而 Microsoft 对其标准版、

Workgroup 版、Compact 版及 Express 版均有不同的限制。 .

MySQL 的特性集可以支持绝大多数 RDBMS 用例(例如 Web、嵌入式、OLTP、托管、SaaS

和云等),并且其实现模型在某些环节(例如分区和复制)比 SQL Server 更加简单。

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

MySQL Cluster,且均不亚于 SQL Server。

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

台服务器的横向扩展。

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

能分析一台服务器的性能。

MySQL 的普遍应用、该产品的开源特性以及成熟的社区将为这个行业带来诸多收益,开发人员和

DBA 将在一个互通的网络中合力确保产品的卓越质量并且实现共赢。

虽然 SQL Server 数据库迁移并不总是轻松的任务(具体工作量取决于依赖关系),按照本文介绍的数据

迁移简易步骤,并利用 MySQL Workbench Migration Tool 等工具,即可确保顺利完成迁移。无论采用完

全、部分还是分阶段迁移方案,从 SQL Server 迁移至 MySQL 都是一项明智的业务和技术决策。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 16

其他资源

Windows 上的 MySQL 资源中心:

http://www.mysql.com/why-mysql/windows/

Windows 上的 MySQL 客户参考

http://www.mysql.com/customers/operatingsystem/?id=109

MySQL 企业版试用

http://www.mysql.com/trials/

MySQL Workbench 和迁移工具包(下载和演示)

http://www.mysql.com/products/workbench/

《MySQL Workbench Migration Wizard 指南:从 SQL Server 迁移至 MySQL》白皮书 (请配合本文使用)

https://www.mysql.com/why-mysql/white-papers/guide-to-workbench-migration-wizard/

“NetMotion Wireless 将产品从 Microsoft SQL Server 迁移至 MySQL”案例研究

https://www.mysql.com/why-mysql/case-studies/netmotion-migrates-from-sqlserver-to-mysql.html

联系 Oracle MySQL 代表:

http://www.mysql.com/about/contact/

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 17

附录 A — 从 SQL Server 迁移至 MySQL — 数据类型

本节提供 SQL Server 与 MySQL 之间在数据类型方面的兼容性信息。

同类数据类型

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 可

自动处理此任务)。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 18

需要转换的数据类型

以下映射可用于转换未与 MySQL 构成一一对应关系的 SQL Server 数据类型:

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)

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 19

附录 B — 从 SQL Server 迁移至 MySQL — 语法

概述

本节列出 SQL Server 支持的 SQL 语法并与 MySQL 支持的等效语法进行对比。语法分为九类:

比较条件语法

存在条件语法

浮点条件语法

IN 条件语法

NULL 条件语法

模式匹配条件语法

范围条件语法

概要

SQL Server 和 MySQL 均支持在 SELECT、DELETE 和 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

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 20

如果任何一个表达式返回 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

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 21

如果表达式 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 条件:ANY、SOME、所提供的表达式 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。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 22

等效的 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 时无需任何操作。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 23

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 大于或等

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 24

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

回 FALSE。

等效的 MySQL 条件:BETWEEN

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

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

UNKNOWN;其他情况返回 FALSE。

等效的 MySQL 条件:NOT BETWEEN

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 25

附录 C — 从 SQL Server 迁移至 MySQL — 运算符和

日期函数

概述

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

算符分为五类:

算术运算符

串联运算符

分层查询运算符

集合运算符

算术运算符

要点

每个 SQL Server 算术运算符都有一个完全等效的 MySQL 算术运算符,因此从 SQL Server 迁移至

MySQL 时无需任何操作。

SQL Server 算术运算符

+

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

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

等效的 MySQL 运算符: +

-

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

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

等效的 MySQL 运算符: -

*

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

等效的 MySQL 运算符: *

/

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

等效的 MySQL 运算符: /

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 26

串联运算符

要点

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 查询。

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 27

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

等效的 MySQL 运算符:UNION ALL。

日期函数

要点

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())

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 28

附录 D — T-SQL 转换建议

概述

MySQL Workbench Migration Tool 不会将 MS SQL Transact SQL 代码转换到 MySQL。因此需要手动

检查 SQL Server 中的存储过程和其他代码对象。本附录提供将 Microsoft T-SQL 代码转换为 MySQL

的相关建议。

从 SQL Server 中获取 T-SQL 代码

使用 SQL Server 的“create scripts”选项从 SQL Server 中提取存储过程,操作时应选择所有存储过程,

并为所选的每个存储过程标志生成一个文件。

过程格式

MS 存储过程的常规格式为:

CREATE PROCEDURE name Param1 type, Param2 type AS Statement1 Statement2

MySQL 的常规格式为:

CREATE PROCEDURE name ( Param1 type, Param2 type ) BEGIN Statement1 ; StateMent2 ; … END;

主要区别在于 MySQL 有以下要求:

1. 要求参数列表以 ‘(‘ ‘)' 对的形式表示

2. 不允许在参数列表后使用 AS

3. 如果存储过程中有多条语句,需要使用 BEGIN END 对

4. 要求每条语句以“;”结束。

5. 在 MySQL 存储过程中,所有变量声明必须位于第一条非声明语句之前。

错误处理

在 SQL Server 中,低于特定级别的错误将由 @@ERROR 返回,存储过程将继续运行,而高于该级别

的错误会立即终止存储过程并将错误返回给调用程序。在 MySQL 中,大多数错误都会终止存储过程并返

回一个错误代码。为了让 MySQL 存储过程的行为更加类似于 SQL Server 存储过程,您需要定义一个错

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 29

误处理程序,如下所示:

DECLARE "@ERROR" INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SET "@ERROR" = 1; END;

然后,修改存储过程代码,用 @ERROR 变量代替 @@ERROR 变量,例如:

IF @@ERROR <>0 GOTO ERROUT UPDATE MessageBoardEntries SET ReplyCount = ReplyCount - 1 WHERE EntryID = @EntryID IF @@ERROR <>0 GOTO ERROUT UPDATE MessageBoardCategories SET PostCount = PostCount -1 WHERE CategoryID = @CategoryID IF @@ERROR <>0 GOTO ERROUT

应替换为:

DECLARE "@ERROR" INT DEFAULT 0 ; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SET "@ERROR" = 1 ; END; INSERT groupmessageboardreplies ( parentid, authorid, body ) VALUES ( "@entryid", "@authorid", "@body" ) ; IF "@ERROR" = 0 THEN UPDATE groupmessageboardentries set replycount = replycount + 1, lastpostdate = NOW(), lastposter = "@authorid" WHERE entryid = "@entryid" ; END IF IF "@ERROR" = 0 THEN UPDATE groupmessageboards set lastpostdate = NOW(), postcount = postcount + 1, lastposterid = "@authorid", lastpostentryid = "@entryid" WHERE groupid = "@groupid" ; END IF;

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 30

用 LIMIT 代替 TOP

在 MySQL 中,SELECT 的 LIMIT 特性取代了 SQL Server 中的 TOP 函数并且增加了 TOP 所不具备

的一些新功能。最简单的形式如下:

以下代码:

SELECT TOP 100 * FROM TABLE

应替换为:

SELECT * FROM TABLE LIMIT 100 ;

如果希望获取从位置 100 开始的 10 条记录,应使用:

SELECT * FROM TABLE LIMIT 100,10 ;

请注意,LIMIT 子语中的值必须是常量,不得使用变量。

您不能使用:

SELECT * FROM TABLE LIMIT @start,@rows ;

可以使用 PREPARE 语句解决此问题,具体示例如下。假设您希望运行以下查询:

select c.classifiedid, c.subject, c.createddate, c.views, c.userid from schoolsclassifieds c where categoryid = "@categoryid" and schoolid = "@schoolid" order by classifiedid desc limit “@startrow","@maxrows" ;

使用以下代码实现 SELECT 功能:

PREPARE STMT FROM 'select c.classifiedid, c.subject, c.createddate, c.views, c.userid from schoolsclassifieds c where categoryid = ? and schoolid = ? order by classifiedid desc limit ?,?' ; EXECUTE STMT USING "@categoryid","@schoolid","@startrow","@maxrows" ;

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 31

LIMIT 和优化

在某些情况下,当您使用 LIMIT <row_count> 而未使用 HAVING 时,MySQL 处理查询的方式会有

所不同:

如果仅通过 LIMIT 选择部分行,MySQL 在某些情况下会使用索引,通常它更愿意执行全表扫描。

如果在 LIMIT row_count 中使用 ORDER BY,MySQL 会在排序结果中找到第一个 row_count

行时立即结束排序,而不是对整个结果进行排序。如果使用索引进行排序,速度会非常快。如果必

须进行文件排序,必须选择所有与查询相匹配且没有 LIMIT 子句的行,对大多数的行或所有行进

行排序,然后才能确定找到了第一个 row_count 行。无论在哪种情况下,找到初始行之后都不需

要对其余结果集进行排序,MySQL 也不会这样做。

当 LIMIT row_count 与 DISTINCT 结合使用时,MySQL 会在找到 row_count 唯一行时立

即停止。

在某些情况下,GROUP BY 表示按顺序读取键(或者对键执行排序),然后计算汇总直到键值发

生更改。在这种情况下,LIMIT row_count 不会计算任何不必要的 GROUP BY 值。

MySQL 将所需行数发送给客户端之后,除非您使用 SQL_CALC_FOUND_ROWS,否则它会立

即中止查询。

LIMIT 0 快速返回一个空集。这可用于检查查询的有效性。当使用任何 MySQL API 时,还可以用

它获取结果列的类型。(这一技巧不适用于 MySQL Monitor,后者只显示空集;您应当使用

SHOW COLUMNS 或 DESCRIBE 来完成此任务。)

当服务器使用临时表来解析查询时,它使用 LIMIT row_count 子句计算所需空间。

IF THEN … ELSE … END IF ;

MySQL 要求每个 IF 包括一个 THEN,当代码块有多条语句时,必须以“END IF ;”结束。请注意,END IF

后的“;”是必需的。

IF <expr> THEN Statement 1; ELSE Statement 2 ; END IF;

包含默认值的 DATETIME

MySQL 迁移工具无法迁移默认值为 getdate() 的 DATETIME 列。例如:

UPLOADED DATETIME NULL DEFAULT GETDATE(),

当表中包含使用以上默认值的 DATETIME 列时,该表将不支持自动转换,必须手动修改,如下所示:

UPLOADED TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMTP, 或者

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 32

UPLOADED DATETIME NULL DEFAULT CURRENT_TIMESTAMTP,

请注意,只有 TIMESTAMP 和 DATETIME 类型可以作为 CURRENT_TIMESTATMP 的默认值。

另 外 , MySQL 的 CREATE TABLE 语 句 里 最 初 的 TIMESTAMP 列 只 能 使 用 NULL 或 者

CURRENT_TIMESTAMP 作为声明的默认值,默认的情况下使用 CURRENT_TIMESTAMP (系统变量

explicit_defaults_for_timestamp 设置为 ON 的情况,不分配默认值)

索引名称长度差异

MySQL 不支持超过 64 字节的索引名称。当索引名称超过 64 字节时,必须进行重命名。

对 SQL Server 声明表的支持

SQL Server 支持在存储过程中使用“TABLE”数据类型。例如:

DECLARE "@Results" TABLE (Pos int IDENTITY, ClassifiedID int)

MySQL 不支持此数据类型,而是使用一个临时的内存中表:

CREATE TEMPORARY TABLE temp1 (ClassifiedID int) ENGINE = MEMORY;

< 其他代码 >

DROP TEMPORARY TABLE temp1 ;

获取行数

在 MySQL 中,ROW_COUNT() 函数返回受上次插入、更新或删除操作影响的行数。使用此函数代替

SQL Server 中的 @@ROWCOUNT 变量。

参数的默认值

在 SQL Server 中,参数可以使用以下形式:

@Param int default 0

MySQL 不支持这种形式。必须将应用修改为传入适当的默认值。

SELECT INTO 的使用

在 SQL Server 中,如果希望根据 SELECT 的结果做成表的话,可以使用:

SELECT * INTO tableB FROM tableA;

在 MySQL 中,INTO 会导致错误,因此您需要使用:

CREATE TABLE tableB SELECT * FROM tableA;

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 33

IFNULL 的使用

IFNULL() 函数用于检查某个值是否为 NULL,然后根据测试结果返回该值或其他值。如果 A 为非 NULL,

则 IFNULL() 函数返回 A,否则将返回 B。

将 DATEADD 替换为 ADDDATE()

MySQL 用 ADDDATE() 函数替代了 DATEADD()。例如:

以下代码:

DATEADD(dd, -14, GETDATE())

替换为:

ADDDATE(NOW(),INTERVAL -14 DAY) ;

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

此语法同样适用于 MySQL,可根据需要置于各存储过程的顶部。更好的办法是在 my.cnf 文件中设置

transaction-isolation 的值:

transaction-isolation=READ-UNCOMMITTED

将 SET ROWCOUNT = @rows 替换为 SQL_SELECT_LIMIT

在 MySQL 中,用 ROWCOUNT 代替 SQL_SELECT_LIMIT 限制 Select 返回的行数。该方法允许通过

变量来设定返回的行数,而不必使用 Prepare 语句。

以下代码:

SET ROOWCOUNT = @rowcount

应替换为

SET SQL_SELECT_LIMIT=@rowcount;

使用 Perl 脚本将 T-SQL 转换至 MySQL

以下 Perl 脚本可帮助将 SQL Server T-SQL 转换为 MySQL。请注意,该脚本仅执行基本更改,许多复

杂的 SQL Server 代码对象仍需要手动修改。

Perl 转换工具的使用方法如下:

1. 将所需的所有 SQL Server 存储过程提取到文件中,并将这些文件放在一个目录中。

2. 按如下所示运行下面的 Perl 脚本“MSProcstoMySql.pl”:perl MSProcstoMySql.pl *.PRC

3. 该过程将创建一个名为“converted”子目录,并将转换后的存储过程放在该目录中。

以下示例显示了上述 Perl 脚本运行前和运行后的存储过程:

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 34

SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO CREATE PROCEDURE DeleteMessageBoardReply @ReplyID int, @EntryID int, @CategoryID int AS SET NOCOUNT ON SET LOCK_TIMEOUT 4000 BEGIN TRAN DELETE FROM MessageBoardReplies WHERE ReplyID = @ReplyID IF @@ERROR <>0 GOTO ERROUT UPDATE MessageBoardEntries SET ReplyCount = ReplyCount - 1 WHERE EntryID = @EntryID IF @@ERROR <>0 GOTO ERROUT UPDATE MessageBoardCategories SET PostCount = PostCount -1 WHERE CategoryID = @CategoryID IF @@ERROR <>0 GOTO ERROUT COMMIT TRAN RETURN ERROUT: ROLLBACK TRAN GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO DELIMITER $$; SET SQL_MODE = ANSI_QUOTES$$ DROP PROCEDURE IF EXISTS DeleteMessageBoardReply $$ CREATE PROCEDURE DeleteMessageBoardReply ( "@replyid" int, "@entryid" int, "@categoryid" int ) BEGIN /*BEGIN tran*/ delete from messageboardreplies WHERE replyid ="@replyid" IF @@error <>0 goto errout

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 35

UPDATE messageboardentries set replycount = replycount - 1 WHERE entryid ="@entryid" IF @@error <>0 goto errout UPDATE messageboardcategories set postcount = postcount -1 WHERE categoryid ="@categoryid" IF @@error <>0 goto errout /*commit tran*/ return errout: rollback tran END; $$ DELIMITER ;$$

Perl 转换例程执行以下功能:

1. 将 dbo.spName.PRC 文件重命名为 spName.sql

2. 将代码封装在以下结构中:

DELIMITER $$; SET SQL_MODE = ANSI_QUOTES$$

<存储过程代码>

$$ DELIMITER ;$$

3. 删除代码中的所有“GO”语句

4. 删除 QUOTED_IDENTIFIER、ANSI_NULL、NOCOUNT 和 LOCK_TIMEOUT 的所有 SET 语句。

5. 注释掉 BEGIN TRAN 和 COMMIT TRAN

6. 将所有 @@IDENTITY 引用替换为 LAST_INSERT_ID() 调用

7. 在每个 @<name> 格式的变量引用前后都加上双引号,例如将 @vari 修改为“@vari”

8. 将所有表名都转换为小写

9. 将 NVARCHAR 类型更改为 VARCHAR

10. 将参数列表放入括号中

11. 删除参数列表后的 AS

12. 将参数列表后的所有代码都放入 BEGIN END 块中

13. 将所有 GETDATE() 调用替换为 NOW() 调用

尽管脚本对 SQL Server 存储过程进行了许多修改,但无法进行全面转换。每个存储过程使用前仍需进行

检查和修改。下面列出了一些较为常见的仍需修复的问题:

在每条语句后添加一个“;”

添加一个错误处理程序

删除任何 IF @@ERROR<>0 GOTO LABEL,使用错误处理程序中设定的值将其替换为 IF …

END IF 块。

Perl 转换脚本

#!/usr/bin/perl if (! -d "converted" ) { mkdir "converted" ;

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 36

} foreach my $inFile (@ARGV) { open INFILE, "<$inFile" ; my $outFile = $inFile ; $outFile =~ s/\.[^\.]*$/.sql/ ; $outFile =~ s/^dbo\.// ; open OUTFILE, ">converted/$outFile" ; print OUTFILE "DELIMITER \$\$;\n" ; print OUTFILE "SET SQL_MODE = ANSI_QUOTES\$\$" ; while( <INFILE> ) { s/\@\@identity/LAST_INSERT_ID()/i ; s/\s(\@[^\s\,\)\@]+)/"$1"/g ; /SET QUOTED_IDENTIFIER ON/ && next ; /SET NOCOUNT ON/ && next ; /SET\s*LOCK_TIMEOUT.*/ && next ; /^\s*GO\s*$/ && next ; /SET QUOTED_IDENTIFIER OFF/i && next ; /SET QUOTED_IDENTIFIER ON/ && next ; /SET ANSI_NULLS ON/ && next ; /SET ANSI_NULLS OFF/ && next ; s/nvarchar/varcharg/ ; if (/(CREATE\s+PROCEDURE)\s+([^\n\r]*)/) { print OUTFILE "DROP PROCEDURE IF EXISTS $2 \$\$\n\n" ; print OUTFILE "$1 $2 (\n" ; next ; }; if (/^\s*AS\s*$/) { print OUTFILE ")\n" ; print OUTFILE "BEGIN\n" ; next ; }; s/(BEGIN\s+TRAN[^\n\r]*)/\/*$1*\// ; s/(COMMIT\s+TRAN[^\n\r]*)/\/*$1*\// ; tr/[A-Z]/[a-z]/; s/getdate\(\)/NOW()/i ; s/select\s/SELECT / ; s/update\s/UPDATE / ; s/insert\s/INSERT / ; s/declare\s/DECLARE / ; s/where\s/WHERE / ; s/values/VALUES/ ; s/begin/BEGIN/ ; s/if/IF/ ; /([^\r\n]*)/ && print OUTFILE "$1\n" ; } print OUTFILE "END;\n" ; print OUTFILE "\$\$\n" ; print OUTFILE "DELIMITER ;\$\$\n" ; close OUTFILE ; close INFILE ;

版权所有 © 2014,Oracle 和/或其关联公司。保留所有权利。 37

联系 MySQL:

中国北方地区:800-811-0823

中国南方地区:800-281-2682

香港:800-96-2447

台湾:00801-81-2732

MySQL 网站:http://www.mysql.com

电子邮箱:[email protected]

受理时间 : 平时 9:00-12:00/13:00-18:00 (节假日与年末年初停业日除外)

公司网址:http://www.oracle.com (英文)

中文网址:http://www.oracle.com/cn (简体中文)

销售中心:800-810-0161

售后服务热线:800-810-0366

培训服务热线:800-810-9931

欢迎访问:

http://www.oracle.com (英文)

http://www.oracle.com/cn (简体中文)