Leitfaden zur Migration von Microsoft SQL Server nach

Transcription

Leitfaden zur Migration von Microsoft SQL Server nach
Leitfaden zur Migration von
Microsoft SQL Server nach MySQL
Ein technisches MySQL® White Paper
September 2007
Copyright © 2007, MySQL AB
Inhaltsverzeichnis
1
Einleitung .........................................................................................................................4
2
Warum die Migration von SQL Server unternehmerisch sinnvoll ist..........................4
3
4
2.1
Bemessung der Kosten für die Nutzung von SQL Server im Vergleich zu MySQL......4
2.2
Ein kurzer Blick auf MySQL AB ...................................................................................6
Die technische Seite der Migration von SQL Server nach MySQL..............................6
3.1
MySQL unter Windows? Natürlich! ..............................................................................7
3.2
Genau die richtigen Funktionen ...................................................................................7
3.3
Untersuchung der Leistung und Skalierbarkeit von MySQL ........................................9
3.4
MySQL – Immer betriebsbereit, immer funktionsfähig .................................................9
Praktische Vorschläge für die einfache Migration von SQL Server zu MySQL........10
4.1
Alles oder nichts? ......................................................................................................10
4.2
1. Schritt – Dokumentation des SQL Server-Quellcodes ...........................................10
4.3
2. Schritt – Entwurf der MySQL-Zieldatenbanken......................................................12
4.4
3. Schritt - Durchführung der Migration nach MySQL ................................................12
4.5
Validierung der Migration von SQL Server nach MySQL...........................................13
4.6
Ratschläge zur gemeinsamen Handhabung von SQL Server und MySQL................15
5
Fazit ................................................................................................................................16
6
Weitere Informationsquellen.........................................................................................17
7
8
6.1
MySQL Migrationshilfen.............................................................................................17
6.2
Anwenderberichte......................................................................................................17
6.3
White Paper ...............................................................................................................18
Anhang A – MSSQL to MySQL - Datatypes .................................................................19
7.1
Overview....................................................................................................................19
7.2
Comparable Datatypes ..............................................................................................19
7.3
Datatypes Requiring Conversion ...............................................................................19
Anhang B – SQL Server to MySQL – Predicates.........................................................20
8.1
Overview....................................................................................................................20
8.2
Synopsis ....................................................................................................................20
8.3
Boolean conditions ....................................................................................................20
8.4
Comparison conditions ..............................................................................................20
8.5
Exists conditions ........................................................................................................22
8.6
In conditions...............................................................................................................22
Copyright © 2007, MySQL AB
Seite 2 von 49
8.7
Null conditions ...........................................................................................................22
8.8
Pattern matching conditions.......................................................................................23
8.9
Range conditions .......................................................................................................23
9
Anhang C – SQL Server to MySQL – Operators and Date Functions .......................24
9.1
Overview....................................................................................................................24
9.2
Arithmetic operators...................................................................................................24
9.3
Concatenation operators ...........................................................................................24
9.4
Hierarchical query operators......................................................................................25
9.5
Set operators .............................................................................................................25
9.6
Date Functions...........................................................................................................26
10
Anhang D – T-SQL Conversion Suggestions ...........................................................27
10.1
Overview.................................................................................................................27
10.2
Getting T-SQL Code out of SQL Server .................................................................27
10.3
Procedure Formats .................................................................................................27
10.4
Error Handling.........................................................................................................27
10.5
Use LIMIT instead of TOP ......................................................................................28
10.6
LIMIT and Optimization...........................................................................................29
10.7
IF THEN … ELSE … END IF ;................................................................................30
10.8
DATETIME with default values ...............................................................................30
10.9
Index Name Length Differences .............................................................................30
10.10
Support for SQL Server Declared Tables ............................................................31
10.11
Obtaining Row Counts .........................................................................................31
10.12
Default Values for Parameters.............................................................................31
10.13
Use of SELECT INTO ..........................................................................................31
10.14
Uses of IFNULL ...................................................................................................31
10.15
Replace DATEADD with ADDDATE()..................................................................31
10.16
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ....................32
10.17
Replace SET ROWCOUNT = @rows with SQL_SELECT_LIMIT .......................32
10.18
Perl Script to Help with Conversion of T-SQL to MySQL .....................................32
10.18.1
11
Perl Conversion Script ...................................................................................34
Anhang E – Sample Migration ...................................................................................36
11.1
Sample SQL Server Schema..................................................................................36
11.2
Moving the SQL Server Database to MySQL with the Migration Toolkit .................40
11.3
Sample MySQL Schema Generated from SQL Server...........................................45
11.4
Sample Code Migration ..........................................................................................46
Copyright © 2007, MySQL AB
Seite 3 von 49
1 Einleitung
Mit dem raschen Wachstum von MySQL auf dem Datenbankmarkt haben viele Unternehmen,
Regierungsbehörden, Bildungseinrichtungen und andere begonnen, sich von ihren kostspieligen
und proprietären Datenbanken zu verabschieden. Eine Datenbankmigration ist natürlich niemals
auf die leichte Schulter zu nehmen, und deshalb denken zahllose Unternehmen nun über ihre
Optionen für die Migration hin zu MySQL nach.
Viele MySQL-Kunden migrieren von SQL Server, denn Sie haben festgestellt, daß die
Kombination aus Kosteneinsparung, Plattformunabhängigkeit und der Funktionsumfang von
MySQL eine unwiderstehliche Gelegenheit darstellen, einen Teil oder die Gesamtheit ihrer
datenbankgetriebenen Anwendungen auf den MySQL Datenbankserver zu migrieren. Dieses
Dokument liefert einen Einblick in die Überlegungen, die für einen Wechsel von SQL Server zu
MySQL notwendig sind und stellt Ihnen eine Reihe von Möglichkeiten vor, die dabei helfen
werden, den Übergang einfacher zu gestalten. Dieses White Paper betrachtet sowohl die
geschäftliche als auch die technische Seite der Migration zu MySQL, Sie werden also unabhängig
davon, ob Sie Manager oder erfahrener Datenbankadministrator sind, die erforderlichen
Antworten auf die Fragen finden, die sich rund um die Migration hin zur weltweit populärsten
Open-Source-Datenbank MySQL drehen.
2 Warum die Migration von SQL Server unternehmerisch
sinnvoll ist
Moderne Unternehmen, die sich im großen Umfang für eine Technologie engagieren wollen,
müssen zunächst einmal hinter die technischen Versprechen der Lieferanten blicken und die
unternehmerische Seite des Erwerbs einer neuen Technologie betrachten. Jedes Geschäft
verfügt über seine eigene Methode zur Bewilligung einer bestimmten Software, dennoch sind die
wichtigsten Faktoren für die Akzeptanz normalerweise das Ergebnis der Kalkulation der
Gesamtbetriebskosten, die über den kompletten Lebenszyklus hinweg anfallen sowie die
Bewertung der Integrität des Softwarehändlers.
Lassen Sie uns jeden dieser beiden oben erwähnten Faktoren etwas genauer anschauen und
feststellen, wie MySQL bei der Kalkulation der Gesamtbetriebskosten des MySQL
Datenbankservers und der Bewertung des Unternehmens, das hinter der Datenbank steht,
abschneidet.
2.1 Bemessung der Kosten für die Nutzung von SQL Server im Vergleich
zu MySQL
Zu den wichtigsten Faktoren, die für die große Beliebtheit und Akzeptanz von Open-SourceSoftware in den Unternehmen verantwortlich sind, gehören unter anderem auch die hohen
Kosteneinsparungen, die der Einsatz einer solchen Software mit sich bringt. Wenn man bedenkt,
daß viele große Global 2000- Unternehmen jährlich zwischen 500.000 und 10.000.000 € für neue
Lizenzen und die Wartung für proprietäre Datenbanksoftware aufwenden, wird MySQL zu einer
unglaublich attraktiven Alternative, denn durch die Verwendung von MySQL sowohl für neue
Anwendungsprojekte als auch für die Erweiterung bestehender Systeme anstelle kostspieligerer
proprietärer Alternativen können die meisten Unternehmen ihre Kosten um etwa 80 – 90 %
senken.
Da SQL Server im Vergleich zu anderen Datenbanken wie Oracle im Hinblick auf
Kosteneinsparungen im Allgemeinen gut abschneidet, erscheint es möglicherweise überraschend,
daß eine Migration von SQL Server zu MySQL dennoch zu erheblichen Kosteneinsparungen
führen kann. Schauen Sie sich einmal den folgenden Dreijahresvergleich der
Gesamtbetriebskosten zwischen MySQL, SQL Server und Oracle an:
Copyright © 2007, MySQL AB
Seite 4 von 49
Gesamtbetriebskosten über 3 Jahre
$1.400.000
$1.200.000
$1.000.000
$800.000
$600.000
$400.000
$200.000
$0
MySQL
MS SQL Server
Oracle
Beispiel einer Hardware-Konfiguration für einen kleinen Online-Händler:
- Anzahl an Servern: 10 (standardmäßige x86-Maschinen)
- Anzahl an CPUs (pro Maschine): 2 (Dual CPU)
- Anzahl an Kernels (pro CPU): 2 (Dual Core)
- Gesamtzahl der eingesetzten CPUs: 20
- Gesamtzahl der eingesetzten Kernels: 40
Microsoft SQL Server Enterprise:
- Softwarelizenz: $24.995 pro CPU
- Support & Wartung pro Jahr: 22% der Softwarelizenz
Oracle Enterprise:
- Softwarelizenz: $40.000 pro Kernel
- Support & Wartung pro Jahr: 22% der Softwarelizenz
MySQL Enterprise Gold:
- Softwarelizenz: KEINE (bei MySQL fallen keine Datenbank-Lizenzgebühren an)
- Jährliches MySQL Enterprise-Abonnement: 2.399 € pro Server
Gesamtbetriebskosten
über 3 Jahre
Microsoft
Oracle
$0
$499.900
$800.000
3 Jahre Support & Wartung
$89.850
$329.934
$528.000
Gesamtkosten
$89.850
$829.834
$1,328.000
Softwarelizenzen
Einsparung über 3 Jahre: MyQL anstatt MS SQL Server
Einsparung über 3 Jahre: MySQL anstatt Oracle
$ 739.984 (89%)
$ 1.238.150 (93%)
Wie Sie sehen können, ist durch einen Wechsel von SQL Server zu MySQL eine Kostensenkung
von fast 90 % realisierbar. Solch deutliche Vergleichsergebnisse sind der Grund dafür, warum
sich so viele Unternehmen für eine horizontale Skalierung mit MySQL zur Erweiterung ihrer
Geschäfte entscheiden - und zwar unabhängig davon, ob das Unternehmen bei Microsoft
Windows bleiben oder auf ein anderes Betriebssystem wie Linux umsteigen möchte.
Unternehmen wie Weather Channel halten MySQL für das perfekte Instrument bei ihrem Streben
nach hoher Datenbankleistung und geringstmöglichen Betriebskosten:
Copyright © 2007, MySQL AB
Seite 5 von 49
„Weather Channel ist heute die zehntgrößte Webseite der Welt und läuft fast zu 100 Prozent
auf der Open-Source-Datenbank MySQL. Mit dem Wechsel von einer Sun Solaris-Umgebung
zu Linux oder Intel, dem Wegfall der Hardwarewartung, dem Austausch der kommerziellen
Software gegen quelloffene Software sowie dem niedrigeren Preis und der besseren Leistung
einer Intel-Plattform reduzierten wir die Kosten um ein Drittel und konnten die
Prozessorkapazität der Website um 30 Prozent steigern“, berichtet Dan Agronow, CTO von
The Weather Channel Interactive.“1
2.2 Ein kurzer Blick auf MySQL AB
Die Migration zu einer neuen Datenbankplattform bedeutet im Allgemeinen ein langfristiges
Engagement; moderne Unternehmen, die über einen Wechsel zu MySQL nachdenken, möchten
deshalb nicht nur die Geschichte der Datenbank kennen lernen, sondern auch erfahren, wer sie
wie verwendet.
Branchenumfragen zufolge bestehen die wichtigsten Bedenken der Unternehmen, die über den
Einsatz einer quelloffenen Software nachdenken, im möglichen Mangel an Support2. Natürlich
wird kein großes Unternehmen seine kritischen Geschäftssysteme auf Software stützen, die nicht
von einem angesehenen Lieferanten unterstützt wird – einem Lieferanten, der über einen lang
anhaltenden und ausgezeichneten Ruf in der Branche verfügt und erstklassigen Support bietet.
Viele Unternehmen wundern sich bei Ihrer ersten Berührung mit MySQL, daß MySQL AB seit
mehr als 10 Jahren im Geschäft ist. Mit elf Millionen aktiven Installationen expandiert MySQL
immer weiter und entwickelte sich so zur populärsten Open-Source-Datenbanken der Welt. Jeden
Tag laden über 50.000 Nutzer weltweit MySQL-Software für ihre geschäftlichen Anwendungen
herunter.
Forrester Research stellte in einer Studie fest, daß im Jahr 2006 74% der Unternehmen eine
Umstellung auf Open-Source in Betracht zogen und 53% den Einsatz von MySQL als eine der
Datenbankplattformen vorsahen.
Aufgrund des ständig anwachsenden Bestands an Firmenkunden bietet MySQL Kunden, welche
erstklassige Support- und Dienstleistungen auf Unternehmensniveau wünschen, MySQL
Enterprise an. MySQL Enterprise bietet diesem Klientel unter anderem Supportleistungen rund
um die Uhr, Benachrichtigungssysteme, und einen professionellen Monitor- und Advisordienst.
Bekannte Anbieter von IT-Systemen und –Lösungen haben inzwischen die Popularität von
MySQL Enterprise erkannt und sich mit MySQL zusammengeschlossen, um MySQL Enterprise
an ihren großen Kundenstamm weiterzuveräußern. Unter den MySQL-Wiederverkäufern befinden
sich heute Unternehmen wie HP, Novell, Dell und andere.
Unternehmen, die Referenzen wünschen und sich absichern möchten, daß MySQL auch für
kritische Anwendungsbedürfnisse zuverlässig arbeitet, brauchen sich nur den rasch wachsenden
MySQL-Kundenstamm anzuschauen: er liest sich wie das Who’s-Who der Geschäftswelt. Im
MySQL-Kundenstamm sind moderne Unternehmen wie Yahoo, Google, Amazon, Siemens,
neckermann.de, OBI, die HypoVereinsbank und viele andere vertreten. Weitere Informationen
finden Sie auf http://www.mysql.de/customers/.
3 Die technische Seite der Migration von SQL Server
nach MySQL
MySQL hat seine Bewährungsprobe im geschäftlichen Umfeld mit Bravour bestanden. Die
nächste Hürde, ob von SQL Server zu MySQL migriert werden kann ist die Überprüfung der
Datenbank-Funktionalitäten und deren Fähigkeiten. Mit anderen Worten: Wie gut kann eine OpenSource-Datenbank sein?
1
2
http://www.cio.com/archive/090105/forum.html, September 2005
Forrester Research, Februar 2004.
Copyright © 2007, MySQL AB
Seite 6 von 49
3.1 MySQL unter Windows? Natürlich!
MySQL kann auf eine umfangreiche Vergangenheit mit vielen Open-Source-Betriebssystemen
wie Linux zurückblicken, und deshalb überrascht es möglicherweise zu sehen, wie beliebt MySQL
mit seiner Datenbankserver-Plattform bei den Anwendern von Microsoft Windows ist. In einer
Umfrage3 unter MySQL-Anwendern gaben 58% an, daß bei ihnen MySQL unter Windows läuft.
46% sagten, daß sie von einem Microsoft-Datenbankprodukt (SQL Server und Access) zu MySQL
migriert hatten. Warum ist MySQL bei den Windows-Anwendern so beliebt?
Zunächst einmal ist MySQL unter Windows extrem einfach zu installieren und betreiben. Die
Installation
und
Konfiguration
mit
der
grafischen
Benutzerschnittstelle von MySQL dauert unter Windows
weniger als 5 Minuten, und das ist schneller und einfacher als
mit SQL Server. Es ist auch ganz leicht, mehrere Instanzen
von MySQL auf demselben Windowsserver zu installieren,
denn jede Instanz läuft als eigener, separater Dienst und
akzeptiert eingehende Verbindungen über einen eigenen,
separaten Port. Wie bei SQL Server ist es ausgesprochen
einfach, MySQL-Instanzen auf einem Windows-Server
entweder über das Windows Dienstprogramm oder aber über
den von MySQL mitgelieferten systray-System Manager zu
starten/anzuhalten.
Auch die Treiber für MySQL lassen sich auf jeden WindowsServer oder auf der Entwickler-Workstation einfach installieren und konfigurieren, und dabei sind
ODBC- und .NET-Treiber verfügbar. MySQL stellt darüber hinaus kostenlose grafische
Management-, Entwicklungs- und Migrations-Werkzeuge zur Verfügung, so daß die Entwickler
oder DBAs ihre MySQL-Datenbanken, Tabellen, Indizes, die gespeicherten Prozeduren und
andere Objekte ganz einfach per Mausklick erstellen können.
Es ist also ganz einfach, MySQL auf der Microsoft Windows-Plattform zu betreiben. Wir möchten
jedoch auch betonen, daß MySQL anders als SQL Server darüber hinaus auf über 2 Dutzend
weiteren Plattformen verwendet werden kann, so daß bei der Arbeit mit MySQL niemals eine
Abhängigkeit von einer bestimmten Plattform entsteht.
3.2 Genau die richtigen Funktionen
Niemand wird abstreiten, daß SQL Server mehr Funktionalität aufzuweisen hat als der MySQLDatenbankserver. MySQL wurde jedoch auch nicht konzipiert, um SQL Server zu ersetzen,
sondern die Absicht bestand darin, einen Hochleistungs-Datenbankserver zu schaffen, der die
meisten Funktionen enthält, die moderne Unternehmen für ihre Geschäfte benötigen. Viele
MySQL-Kunden (einer kürzlich durchgeführten Umfrage zufolge 44%) setzen sowohl SQL Server
als auch MySQL im selben Rechenzentrum ein und verwenden dann das jeweils passende
Produkt.
Was die Kernfunktionen anbelangt, werden sich sowohl Datenbankadministratoren als auch ITLeiter darüber freuen, daß MySQL über alle notwendigen Funktionen verfügt, um die große
Mehrheit der Anwendungsanforderungen zu erfüllen:
3
MySQL-Anwenderumfrage – Dezember 2005.
Copyright © 2007, MySQL AB
Seite 7 von 49
Leistungsmerkmal
Quelloffen
Verfügbar für zwei Dutzend Plattformen (32- und 64-Bit),
einschließlich Windows: (RedHat, SuSE, Fedora, Solaris, HPUS,
AIX, SCO, FreeBSD, Mac OS, Windows)
Modulare Speicher-Engine-Architektur (MyISAM, InnoDB, Merge,
Memory, Archive, Cluster)
Geclusterte, hochverfügbare Datenbank
ANSI SQL, SubQueries, Joins, Cursors, Prepared Statements
Gespeicherte Prozeduren, Trigger, SQL und benutzerdefinierte
Funktionen
Aktualisierbare Views
ACID-Transaktionen mit Commit, Rollback
Verteilte Transaktionen
Sperren auf Datensatzebene
Snapshots/konsistente, wiederholbare Lesezugriffe (beim Lesen
wird der Schreibzugriff nicht gesperrt und umgekehrt)
Vom Server erzwungene, referenzielle Integrität
Breite Datentypunterstützung (numerisch, VARCHAR, BLOB, etc.)
Hochpräzise numerische Datentypen
Robuste Indizierung (geclustered, b-tree, hash, Volltext)
Dynamische Speichercaches
Zentraler Abfragecache
Kostenbasierter Optimizer
Unicode, UTF-8
XML, XPath
Geographische Datentypen
Replikation (zeilen- und befehlsbasiert)
Partitionierung (Bereich, Liste, Hash, Schlüssel, kombiniert)
VLDB-Unterstützung (Terabytes)
Hochperformantes Dienstprogramm zum parallelen Laden von
Daten
Online-Backup mit Point-in-Time-Wiederherstellung
Automatischer Neustart/Crash-Recovery
Automatisches Speichermanagement (Auto-Expanision, UndoManagement)
Komprimierte Tabellen und Archivtabellen
Informationsschema/Data Dictionary)
Sicherheitsfunktionalitäten (SLL,detailierte Objektprivilegien)
Integrierte Datenver- und entschlüsselung
Integrierter Task Scheduler
Treiber (ODBC, JDBC, .NET, PHP, usw.)
GUI-Werkzeuge (Workbench, Administrator, Query-Browser,
Migration Toolkit)
Tabelle 1 – Die wichtigsten Funktionen des MySQL-Datenbankservers
Verfügbarkeit
in MySQL
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
√
Wie oben dargestellt enthält MySQL sehr leistungsstarke Funktionen und übertrifft SQL Server in
einigen Bereichen. SQL Server 2005 unterstützt zum Beispiel nur die bereichsbasierte
Partitionierung, während MySQL 5.1 Unterstützung für Bereichs-, Hash-, Schlüssel-, Listen- und
gemischte Partitionierung einführte.
Copyright © 2007, MySQL AB
Seite 8 von 49
3.3 Untersuchung der Leistung und Skalierbarkeit von MySQL
Eines der Kennzeichen von MySQL war immer die ausgesprochen hohe Leistung in allen
Bereichen, unabhängig davon, ob es um die Transaktionsverarbeitung, um Data Warehousing
oder um stark frequentierte Websites geht. Wie bereits erwähnt können viele moderne
Unternehmen durch den Einsatz einer horizontalen Skalierungsarchitektur in Verbindung mit
MySQL unglaubliche Leistungsgewinne verzeichnen, bei denen Daten über zahlreiche MySQLStandardserver vervielfältigt und so verteilt werden, so daß auch die größten Belastungen durch
den Endanwender in extrem kurzen Reaktionszeiten verarbeitet werden können.
Kunden wie Friendster verarbeiten mit MySQL täglich über 1,5 Milliarden Abfragen auf einer
Datenbasis von 24 Terabytes. Andere Kunden wie Craigslist und Sabre Holdings bedienen mit
Hilfe von MySQL täglich unzählige Kundenanfragen. Los Alamos Labs verwaltet 7 Terabyte an
Daten mit MySQL, Cox Communications registriert innerhalb von zwei Stunden 4 Millionen neue
Einträge an Kundendaten – beide Unternehmen stellen hinsichtlich des Data Warehouse fest, daß
sich MySQL in punkto Leistungsfähigkeit und Skalierbarkeit mehr als bewährt hat. Alan Walker,
Vizepräsident von Sabre äußerte sich so: „MySQL läuft schneller oder zumindest genauso schnell
wie jede kommerzielle Datenbank, die wir getestet haben.“
3.4 MySQL – Immer betriebsbereit, immer funktionsfähig
Zuverlässigkeit und verfügbare Betriebszeit sind zwei wichtige technische Anforderungen für jede
Software, dies gilt jedoch insbesondere für Datenbanksoftware. MySQL enttäuscht auch in
diesem Bereich nicht und bietet viele Funktionen, die dabei helfen, einen kontinuierlichen
Datenbankbetrieb zu gewährleisten.
Eine eigenständige MySQL-Installation ist extrem zuverlässig, und viele MySQL-Installationen
erleben über mehrere Jahre hinweg nur wenige oder gar keine Ausfälle. Wie bereits weiter oben
besprochen, setzen viele große Unternehmen die MySQL-Replikation zur Implementierung von
horizontalen Skalierungsarchitekturen ein, die eine sehr hohe Redundanz liefert. Das Ergebnis ist
ein vollständig unterbrechungsfreier Betrieb über Dutzende und sogar Hunderte von Servern
hinweg, so daß oft gar kein Bedarf mehr z.B. an SQL Server Clustering oder Log Shipping
besteht.
Für Unternehmen, die höchstmögliche Betriebszeiten benötigen, kann MySQL Cluster verwendet
werden, um Lösungen für eine 99,999%ige Verfügbarkeit einzurichten. Bei Verwendung einer
Shared-Nothing-Architektur wird MySQL Cluster von Kunden eingesetzt, die es sich einfach nicht
leisten können, daß ihre Systeme ausfallen. MySQL Cluster ist besonders für Anwendungen wie
Transaktions- und Katalogsysteme in den Bereichen Telekommunikation und eCommerce
geeignet. MySQL Cluster ist derzeit nur für Linux und Unix verfügbar.
Copyright © 2007, MySQL AB
Seite 9 von 49
4 Praktische Vorschläge für die einfache Migration von
SQL Server zu MySQL
In der folgenden Abbildung werden die drei grundlegenden Schritte für die Migration von SQL
Server nach MySQL dargestellt:
Abbildung 1 – Die drei grundlegenden Schritte bei der Migration von SQL Server zu MySQL
4.1 Alles oder nichts?
Vor der Arbeit an jedem einzelnen Migrationsschritt möchten wir auf eine sehr erfolgreiche
MySQL-Einsatzstrategie der Kunden hinweisen: Wenn kein Bedarf an speziellen SQL ServerFunktionen besteht kommt bei neuen Projekten MySQL zum Einsatz oder es werden bestehende
Anwendungen migriert, während bei ganz besonderen Datenbankanforderungen SQL Server
eingesetzt wird. Wie aus Tabelle 1 in diesem Dokument hervorgeht, bietet MySQL das perfekte
Gleichgewicht aus Anwenderfreundlichkeit und leistungsstarken Funktionalitäten für die
Handhabung der meisten Datenbankanforderungen einer jeden Anwendung.
MySQL kann in jeder IT-Infrastruktur auch in Verbindung mit SQL Server oder jeder anderen
Datenbankplattform eingesetzt werden, denn seine große Anwenderfreundlichkeit verursacht wenn überhaupt - einen nur sehr geringen Verwaltungsaufwand. Ein Beispiel aus der Praxis ist
die Firma Sabre: Hier wird MySQL als Nachschlagewerk für Reservierungen eingesetzt; für
komplexe
Transaktionsverarbeitungen
verwendet
Sabre
HP
Nonstop.
4.2 1. Schritt – Dokumentation des SQL Server-Quellcodes
Die Dokumentation der Datenbankstruktur eines bestehenden SQL Servers über manuelle
Standardverfahren kann schwierig sein. Obwohl SQL Server über ein sehr gutes MetadatenDictionary verfügt, kann der manuelle Auszug aller Metadaten (Tabelle, Spalte, Index usw.) sehr
zeitraubend sein.
Copyright © 2007, MySQL AB
Seite 10 von 49
Der beste Ansatz besteht hier in der Verwendung eines computerisierten Reverse EngineeringVerfahrens, bei dem alle für die Konvertierung maßgeblichen Metadaten automatisch katalogisiert
werden. Dafür kann ein gutes Datenmodellierungs-Werkzeug eines Drittanbieters verwendet
werden. Der Markt bietet hier eine Reihe guter Produkte, wie z.B. PowerDesigner von
Sybase/Quest und ER/Studio von Embarcadero, welche die Rückentwicklung verschiedener
Datenquellen wie z.B. SQL Server unterstützen. MySQL stellt außerdem ein freies
Modellierungswerkzeug mit der Bezeichnung MySQL Workbench, das eine Rückentwicklung der
SQL Server-Tabellen und Indexstrukturen durchführen kann.
Die Verschiebung von Daten und Indexstrukturen nach MySQL ist normalerweise keine
besonders schwierige Aufgabe, denn MySQL unterstützt alle wichtigen Datentypen,
Tabellendesigns und Indexstrukturen. Eine vollständige Beschreibung zum Vergleich von
Datentypen und anderen wichtigen Migrationsmerkmalen für SQL Server und MySQL finden Sie
in den Anhängen A - C dieses Dokuments. In Anhang D finden Sie eine schrittweise
Beispielmigration von einem SQL Serverschema nach MySQL.
Außerhalb codebezogener Objekte wie gespeicherter Prozeduren können einige wenige SQL
Server-Objekte nicht eins-zu-eins migriert werden:
•
•
Synonyme
Sicherheitsrollen
Der schwierigere Teil der Migration ist die Arbeit mit Codeobjekten. Transact-SQL von SQL
Server enthält viele Funktionen, von denen viele nicht dem ANSI-Standard entsprechen. Aus
diesem Grund muß bei der Betrachtung von gespeicherten Prozeduren, Triggern, Views,
benutzerdefinierten Funktionen usw. sehr vorsichtig vorgegangen werden. Neben den
allgemeinen Unterschieden bei Syntaxfunktionen und Funktionalität erfordern folgende Elemente
besondere Aufmerksamkeit, bevor sie vollständig von SQL Server nach MySQL migriert werden
können:
•
•
•
•
•
Assemblies
Typen
DDL und Statement-basierte Trigger (MySQL hat zeilenbasierte Trigger)
Proprietäre SQL Server-Funktionsaufrufe
Bestimmte Fälle von dynamischem T-SQL
Um die Migration von Datenobjekten von SQL Server nach MySQL zu vereinfachen, stellt MySQL
ein
frei
verfügbares
grafisches
MigrationsWerkzeug bereit. Dieses
Werkzeug enthält auch eine
Komponente
zur
Rückentwicklung, wie sie
auch
in
guten
DatenmodellierungsWerkzeugen zu finden ist.
Über
eine
einfach
zu
verwendende Schnittstelle
gibt der Anwender zunächst
die Verbindungsdetails für
das Quelldatenbanksystem
ein und stellt dann eine
Verbindung mit der SQL
Serverdatenbank her, die zu
Migrationszwecken
rückentwickelt wird.
Mit dem MySQL Migration
Toolkit ist es ganz einfach, die notwendigen Metadaten der Quelldatenbank zu erhalten, so daß
die Migration rasch gestartet werden kann.
Copyright © 2007, MySQL AB
Seite 11 von 49
4.3 2. Schritt – Entwurf der MySQL-Zieldatenbanken
Nachdem die Quellmetadaten des SQL Servers erhalten und verarbeitet wurden, besteht der
nächste Schritt im Entwurf der MySQL-Zieldatenbank. Hierzu gehört vor allem die Übersetzung
der Quellobjekte und ihrer Eigenschaften (wie Spaltendatentypen) in MySQL-Gegenstücke.
Dieser Schritt kann extrem zeitraubend und fehlerträchtig ausfallen, wenn er manuell durchgeführt
wird, denn die meisten Datenbanken beinhalten Tausende von Objekteigenschaften, die
konvertiert werden müssen. Eine detaillierte Auflistung der umzuwandelnden Datentypen und
Funktionen von SQL Server nach MySQL finden Sie auch hier in Anhang A dieses Dokuments.
Bitte beachten Sie, daß die meisten Werkzeuge für die Datenmodellierung die Fähigkeit besitzen,
mit nur wenigen Mausklicks ein SQL Server-Schema in ein MySQL-Schema zu konvertieren.
MySQL Workbench erledigt automatisch diese Aufgabe, wenn eine Rückentwicklung der SQL
Server-Datenbank mit diesem Tool durchgeführt wird. Diese Modelle können natürlich bei Bedarf
angepaßt werden. Die automatische Konvertierung von SQL Server in MySQL-Datenobjekte
durch die Modeling-Werkzeuge spart große Mengen an Zeit und kann für das
Datenbankmigrationsteam zu großen Produktivitätsgewinnen führen.
Bei der Konvertierung von Codeobjekten verhält es sich jedoch anders. Eine Reihe von MySQLPartnern arbeitet bereits an Werkzeugen für die automatische Codekonvertierung, mit dem ein
Reverse Engineering der T-SQL-Codeobjekte von SQL Server durchgeführt werden kann und
konstruieren dafür MySQL-Gegenstücke.
Das MySQL Migration
Toolkit
konvertiert
automatisch
jede
Quelldatenbank, an der mit
diesem Tool ein Reverse
Engineering durchgeführt
wurde, in ein MySQLGegenstück, und zwar
vollständig
mit
allen
Datentypübersetzungen
und anderen ähnlichen
Konvertierungen.
Der
Anwender
hat
die
vollständige Kontrolle über
die
exakten,
zu
migrierenden
Objekte
sowie
darüber,
wie
MySQL-spezifische
Angaben – zum Beispiel,
welche Speicher-Engine verwendet werden soll – erfolgen sollen.
Wie bereits erwähnt, kann dieser Schritt extrem kompliziert sein, und wird er nicht korrekt
durchgeführt, so kann das dazu führen, daß der Datenbankadministrator plötzlich Objekte neu
konzipieren oder Datentransferfehler bearbeiten muß, die aufgrund eines ungültigen
Datentypmappings auftreten. Wie dem auch sei, wenn Sie das MySQL Migration Toolkit
verwenden, gehören diese Probleme der Vergangenheit an, denn dieses Werkzeug erledigt die
Arbeit auf Anhieb korrekt.
4.4 3. Schritt - Durchführung der Migration nach MySQL
Nachdem die Quellmetadaten von SQL Server erfaßt und die MySQL-Ziel-Datenbank konzipiert
wurde, ist der nächste Schritt die Durchführung der tatsächlichen Migration. Die Extrahierungs-,
Umwandlungs- und Ladephasen (ETL) können abhängig von den Zielen recht kompliziert sein.
Zusätzlich zum MySQL Migration Toolkit gibt es daher viele leistungsstarke ETL-Werkzuge von
Drittanbietern auf dem Markt, die eine extreme Flexibilität bei Bewegung, Sammlung, Mapping
und Transformation der Daten vom SQL Server zu den MySQL-Datenbanken bieten. Drittanbieter
wie Informatica, Embarcadero DT/Studio, Goldengate und andere bieten Support für die Migration
Copyright © 2007, MySQL AB
Seite 12 von 49
komplexer SQL Server-Datenbanken nach MySQL an. Wenn Sie kontinuierlich
Datenbankmigrationen durchführen müssen (zum Beispiel für die Datenübertragung von
Quellsystemen in Data Warehouses) ist der Erwerb eines solchen Werkzeugs eine gute
Investition.
Für einmalige Migrationen ist der Preis für derartige ETL-Tools jedoch zu hoch. Das MySQL
Migration Toolkit kann hier hilfreich sein, denn es bietet eine Reihe an Optionen für den Transfer
einer Quelldatenbank von SQL Server nach MySQL. Das MySQL Migration Toolkit steht frei zur
Verfügung und ist und unter der Open-Source-GPL-Lizenz veröffentlicht.
Auch Microsoft bietet Data Transformation Services (DTS für SQL Server 2000) und Integration
Services (SQL Server 2005) an, die bei einer Migration von SQL Server nach MySQL hilfreich
sein
können.
Microsofts
integrierte
Migrationswerkzeuge
unterstützen
den
Datenbankadministrator beim mühelosen Transfer von SQL Server-Daten nach MySQL.
Wenn Sie SQL Server verwenden, mit den Integration Services jedoch nicht vertraut sind, können
Sie die Daten mit Hilfe einer Kombination des SQL Server Bulk Copy-Programms (BCP) und dem
MySQL LOAD DATA INFILE-Dienstprogramm von SQL Server nach MySQL transferieren. Wenn
die Daten durch ein geeignetes Zeichen getrennt sind (wie z.B. durch ein Komma, Semikolon
etc.), dann kann der DBA Datenfiles mit SQL Server BCP erstellen und dann mit LOAD DATA
INFILE unter Angabe desselben Trennzeichens nach MySQL laden.
Eine letzte Möglichkeit zum Laden einer SQL Server-Datenbank nach MySQL mit Hilfe von
Microsoft besteht in der Verwendung der Exportmöglichkeiten von Microsoft Access. Der
Datenbankadministrator kann durch Klicken auf eine Access-Tabelle und eine Kombination aus
Exportfunktion und dem ODBC-Treiber von MySQL jeden Datensatz aus Access nach MySQL
exportieren. Bitte achten Sie darauf, daß die Indizes normalerweise nicht mit der Tabellenstruktur
und den Daten exportiert werden.
Eine Strategie für die Datenmigration besteht in der Migration aller bestehenden SQL ServerObjekte und Daten aus der Quelldatenbank in eine MySQL Staging-Datenbank. Nachdem die
Daten sicher im MySQL Datenbankserver angekommen sind, kann der DBA oder Entwickler
gespeicherte Prozeduren oder anderen Migrationscode erzeugen, anhand dessen die Daten dann
selektiv von der Staging-Datenbank in eine andere MySQL-Datenbank zur weiteren Entwicklung
oder Produktion manipuliert oder transferiert werden.
Eine weitere Option besteht in den Scripting-Fähigkeiten des MySQL Migration Toolkits für die
Übermittlung der Daten beim Transfer von der SQL Server-Quelle zur MySQL-Zieldatenbank.
Obwohl die meisten Anwender die grafische Benutzerschnittstelle zur Durchführung von
Datenbankmigrationen mit der Maus verwenden werden, so können fortgeschrittene Anwender
die zugrundeliegende Architektur einsetzen, um – falls erforderlich - komplexere ETL-Prozesse zu
erstellen und zu planen.
Bei umfangreichen Transformationen von SQL Server-Daten bewegt das Migration Toolkit die
Daten als Bulk und stellt sicher, daß alle Datenbank- und Objekteigenschaften, die zu schnellen
Ladezeiten führen, automatisch eingestellt werden. Die Anwender des Migration Toolkits werden
über einfach abzulesende Anzeigen und andere Informationsmeldungen über den Fortschritt des
Migrationsverfahrens auf dem Laufenden gehalten. Nach Beendigung der Migration erhält der
Anwender einen zusammenfassenden Bericht aller durchgeführten Aufgaben.
4.5 Validierung der Migration von SQL Server nach MySQL
Nachdem alle Informatioenn von der SQL Server-Quelldatenbank nach MySQL extrahiert wurden,
empfehlen wir Ihnen, abschließende Tests durchzuführen, um sich zu vergewissern, daß im
Hinblick auf die Übereinstimmung von Objekten und Datensatzanzahl sowie auf ergänzende
Elemente wie Indizes und unterstützende Codeobjekte (Views etc.) alles in Ordnung ist. Auch die
Durchführung einer Reihe von Benchmarktests, anhand derer Sie feststellen können, ob die
Leistung akzeptabel ist, ist eine gute Idee. Dieser Schritt wird von allen Migrationsprozessen
vielleicht am meisten vernachlässigt, da er naturgemäß nicht so einfach auszuführen ist.
Copyright © 2007, MySQL AB
Seite 13 von 49
Gute Leistungstests erfassen die Leistungsprobleme, die von ungeeigneten Anwender- und
Qualitätssicherungstests übersehen werden. Leistungstests simulieren nur das, was beim
tatsächlichen Einsatz erwartet wird. Sie belasten die MySQL-Datenbank auf eine Weise, die sonst
nur durch gleichzeitige Zugriffe aller möglichen Nutzer erreicht werden könnte (Spitzenlast).
Intelligente Leistungstests verwenden folgende Komponenten für eine realistische Simulation
dessen, was in einer produktiven Datenbank geschieht:
•
Erwartete Anwenderpräsenz – Es ist entscheidend, daß der Test die Anzahl der
Anwenderverbindungen simuliert, die zu Spitzenzeiten und zu normalen Arbeitszeiten
erwartet werden. Dies ist der größte Bereich, in dem manuelle Methoden, bei denen nur
ein Teil der Anwender zum Test von Datenbank und Anwendung verwendet werden,
scheitern. Die Datenbank funktioniert eventuell mit 10 Anwendern vollkommen
problemlos, scheitert jedoch, wenn 400 Verbindungen hergestellt werden.
•
Wiederholte Anwenderaktivität – Nachdem die erwartete Anzahl an Anwendern
Verbindungen mit der Datenbank hergestellt hat, müssen die Anwender natürlich „etwas
tun", damit das System belastet wird. Und diese „Etwas“ dürfen sie nicht nur einmal tun.
Entweder alle oder ein Teil der Anwender müssen die Aufgaben wiederholt durchführen,
ganz genau so, wie es an einem normalen Arbeitstag erfolgen würde. Bei einem OLTPSystem kann dies die Eingabe zahlreicher Aufträge bedeuten. Bei einem Date
Warehouse hingegen kann das umfangreiche analytische Abfragen bedeuten. Wichtig ist,
daß die Arbeit wiederholt durchgeführt wird, so daß die Datenbank immer neuen
Belastungsspitzen ausgesetzt ist.
•
Erweiterte Dauer – Nachdem Sie eine Anzahl von Sessions eingestellt haben, in denen
wiederholt Aufgaben durchgeführt werden, besteht Ihr nächster Schritt darin
sicherzustellen, daß die Arbeit über eine bestimmte Dauer fortgesetzt werden kann, damit
der Test überhaupt sinnvoll ist. Sie suchen hier nach Problemen, die sich erst im Laufe
der Zeit entwickeln. Die Fragmentierung einer MySQL-Tabelle erfolgt vielleicht nicht nach
30 Minuten OLTP-Arbeit, jedoch ganz überraschend und auf dramatische Weise nach 2
oder mehr Stunden wiederholter Aktivität.
•
Erwartetes Produktivdatenvolumen – Um ein aussagekräftiges Testergebnis zu erhalten,
müssen Sie Testdaten in Ihre Datenbank laden, die in etwa der Größe Ihrer tatsächlichen
Datenbank entsprechen. Dies ist einfach zu erreichen, wenn eine bestehende produktive
Datenbank nach MySQL migriert wurde.
Die meisten Datenbankadministratoren sind ratlos, wie sie in der Praxis alle oben erwähnten
Punkte umsetzen sollen. Es gibt Open-Source Benchmark-Werkzeuge; die meisten verfügen aber
über Unzulänglichkeiten bei der Durchführung von korrekten Performanz-Tests, sodaß das
eigentliche Ziel verfehlt wird.
Hier kann Software von Drittanbietern Abhilfe schaffen, wobei nicht jede Software gleich gut
geeignet ist. Ein sehr gutes Leistungstestwerkzeug, Benchmark Factory, wird von Quest Software
vertrieben. Benchmark Factory ist extrem einfach zu verwenden und bietet flexible, per Maus
bedienbare Assistenten, die den Anwender durch den vollständigen Einrichtungsprozess führen
und viele der standardmäßigen TPC-Benchmarktests für MySQL als auch andere skalierbare
Leistungstests durchführen. Nach Beendigung der Tests liefert Benchmark Factory Analysen mit
einfachen Vergleichsläufen und kann die Testergebnisse nach Microsoft Excel exportieren.
Mit MySQL 5.1 wurde ein neues Dienstprogramm eingeführt – mysqlslap. Mit diesem Programm
kann über die Befehlszeile ein Leistungsvergleich für MySQL Server durchgeführt werden. Mit
diesem Programm können auf schnelle Weise Testschemata generiert, Testdaten eingepflegt und
eine beliebige Anzahl an virtuellen Nutzern erzeugt werden, die eine Folge von vordefinierten
oder kurzfristig erstellten SQL-Befehlen auf der Testdatenbank ausführen. Im Anschluß werden
die Testergebnisse zurückgemeldet.
Copyright © 2007, MySQL AB
Seite 14 von 49
4.6 Ratschläge zur gemeinsamen Handhabung von SQL Server und
MySQL
Wie sehen die optimalen Verfahren für einen Datenbankadministrator aus, wenn MySQL in einem
Rechenzentrum parallel zu SQL Server betrieben werden soll? Obwohl die nachfolgenden
Empfehlungen keinen Anspruch auf Vollständigkeit haben, sollen sie Datenbankadministratoren
dabei helfen, so produktiv wie möglich zu arbeiten.
•
Datenbankwerkzeuge können bei korrekter Wahl zu großen Produktivitätsgewinnen
führen. Viele Drittanbieter von Datenbankwerkzeugen unterstützen heute MySQL und
gleichzeitig SQL Server. Der DBA sollte also herausfinden, ob die Verwendung dieser
Werkzeuge für ihn sinnvoll ist. Quest TOAD wird zum Beispiel aufgrund der großen
Zeiteinsparungen in vielen SQL Server Shops verwendet. Ein Datenbankverwalter, der
die TOAD-Schnittstelle kennt, kann durch Verwendung von Toad for MySQL von Quest
ganz einfach zu MySQL wechseln. Das Gleiche gilt auch für die Anwender von DBArtisan
von Embarcadero, das SQL Server unterstützt. DBArtisan unterstützt jetzt MySQL, so
daß der DBA nur ein einziges Tool zur Handhabung sowohl der SQL Server- als auch der
MySQL-Plattform verwenden muß. Der DBA kann natürlich auch die Werkzeuge seines
Datenbanklieferanten wie Management Studio für SQL Server (Enterprise Manager für
SQL Server 2000 und darunter) und die Administrator- und Query Browser-Tools von
MySQL (alle frei von MySQL) verwenden.
•
SQL Server-DBAs, die daran gewöhnt sind, daß sich der SQL Server automatisch selbst
verwaltet, sollten die entsprechenden zusätzlichen MySQL-Funktionen verwenden, so
daß zusätzlicher Verwaltungsaufwand vermieden wird. Dazu gehören unter anderem die
Aktivierung der InnoDB Tablespace-Dateien für die automatische Größenanpassung
(entspricht der Aktivierung der Autogrowth-Eigenschaft für SQL Server-Daten und
Logfiles), die Einrichtung des MySQL Binary Loggings für die Point-in-TimeWiederherstellung
(entspricht
der
Verwendung
eines
vollständigen
Wiederherstellungsmodells unter SQL Server mit periodischen Transaktions-Logdumps)
und andere ähnliche Funktionen.
•
Denken Sie daran, daß Sie anders als bei SQL Server in MySQL eine Reihe
unterschiedlicher zugrundeliegender Speicher-Engines zur Verfügung haben, die für
bestimmte Anwendungsszenarien gedacht sind. Vergewissern Sie sich, daß Sie die
richtige Engine für den richtigen Zweck verwenden.
•
Großzügige Speicherzuweisungen führen bei MySQL genau wie bei SQL Server zu
Leistungssteigerungen. Achten Sie also darauf, daß abhängig von der zugrundeliegenden
Engine genügend RAM für den Speicherzugriff auf die Daten (im Gegensatz zum Lesen
von der Festplatte) verfügbar ist, denn die Standardeinstellungen für MySQL sind für fast
alle Geschäftsanwendungen zu niedrig. Seien Sie sich auch bewußt, daß das ständige
Lesen der Daten in den RAM - wie bei SQL Server - nicht bedeutet, daß der aktuelle
SQL-Code wirklich auch effizient ist. Unnötige logische Ein/Ausgabe-Operationen können
die Leistung genau wie physische Ein- und Ausgaben beeinträchtigen.
o Geclusterte Indizes weichen in MySQL leicht von denen in SQL Server ab:
ƒ Geclusterte Indizes sind nur mit der InnoDB-Speicherenginge verfügbar.
ƒ Geclusterte Indizes müssen auf dem Primärschlüssel der Tabelle
angelegt werden.
ƒ Wird ein geclusterter Index nicht explizit auf einer InnoDB-Tabelle
definiert, erstellt MySQL automatisch einen Index auf einem
Primärschlüssel, einem eindeutigen Schlüssel (wenn ein Primärschlüssel
nicht verfügbar ist) oder auf einem internen Row-Identifier, wenn die
Tabelle keine eindeutigen Schlüssel enthält.
•
Die Partitionierung in MySQL erfordert anders als bei SQL Server nicht das Erstellen von
Partitionsfunktionen oder Partitionsschemata. Die Partitionen und die Partitionsmethoden
(Range, Hash, Key, List, Composite) werden statt dessen in der DDL für die
Tabellenerstellung definiert.
Copyright © 2007, MySQL AB
Seite 15 von 49
•
Linked Server und partitionierte Views von SQL Server können mit Hilfe der FederatedSpeicher-Engine von MySQL imitiert werden.
•
Anders als SQL Server 2005 erfolgt die Aktivierung von „Snapshot Read“ (beim
Lesezugriff wird der Schreibzugriff nicht verhindert und umgekehrt) in MySQL
automatisch und erfordert keinerlei Einstellung von Datenbankoptionen oder einleitenden
SQL-Statements mit speziellen Befehlen für Snapshot-Isolation-Lesevorgänge. SnapshotRead ist zurzeit jedoch nur für besondere Speicherengines verfügbar (wie InnoDB,
Archive etc.). Schlagen Sie also im aktuellen MySQL-Handbuch nach, welche
Sperrfunktionen für jede Engine unterstützt werden.
•
Wenn mehrere MySQL-Instanzen parallel betrieben werden (wie viele DBAs dies mit SQL
Server tun), dann sollte der MySQL Instance Manager verwendet werden. Er wurde mit
Version 5.0 eingeführt und erhöht die Produktivität der MySQL DBAs, indem er eine
einfache Möglichkeit bietet, MySQL-Instanzen remote zu starten, anzuhalten, zu
bearbeiten und zu steuern. Darüber hinaus ermöglicht dieses Werkzeug den einfachen
Fernzugriff auf Fehlerprotokolle und andere Vorgänge, die MySQL protokolliert.
•
Da ein ineffizienter SQL-Code negative Auswirkungen auf eine sonst gut laufende
MySQL-Datenbank haben kann, sollten Sie als MySQL-Datenbankadministrator das Slow
Query Log aktivieren, um auf diese Weise schlecht abgestimmten SQL-Code ausfindig zu
machen und die Ergebnisse regelmäßig im Protokoll zu überprüfen. Mit MySQL können
das Slow Query Log oder das General Log so eingerichtet werden, daß die Ergebnisse,
die in den dynamischen Management-Views oder in SQL Profiler von SQL Server zum
Aufspüren von schlechtem Code zu finden sind, automatisch widergespiegelt werden.
Version 5.1 liefert SQL-Leistungstabellen, die über SQL abgerufen werden können, um
Metriken über ineffizienten Code zu erhalten. Für eine weitere Leistungsüberwachung
können die Befehle MySQL SHOW GLOBAL STATUS und SHOW INNODB STATUS zur
Untersuchung der rohen MySQL-Leistungsmetriken verwendet werden. MySQL
Enterprise bietet mit dem MySL Enterprise Monitor erweiterte Überwachungs- und
Beratungsfunktionen und sollte in den meisten produktiven Umgebungen verwendet
werden, in denen MySQL eingesetzt wird.
•
MySQL DBAs sollten für die Überprüfung des MySQL-Fehlerprotokolls auf
ungewöhnliches Verhalten dieselben Pläne wie zur Überprüfung der SQL Server
Error/Notification Logs verwenden.
•
Wenn Sie es gewohnt sind, den SQL Server Agent zur Planung und Ausführung von
SQL/T-SQL-Jobs zu verwenden, dann können Sie in MySQL 5.1 den Event Scheduler für
denselben Zweck verwenden.
•
DBAs mit produktiven Anwendungen, die eine Überwachung rund um die Uhr benötigen,
sollten MySQL Enterprise in Betracht ziehen, denn die zertifizierte Software liefert eine
hohe Zuverlässigkeit, während die Softwareupgrades und Überwachungs/Advisorydienste proaktiv dabei helfen, eine möglichst hohe verfügbare Betriebszeit zu
gewährleisten und bei der Diagnose und Lösung von Leistungsproblemen Unterstützung
bieten.
5 Fazit
Vom geschäftlichen und technischen Standpunkt aus betrachtet ist die Frage, ob eine Migration
von SQL Server nach MySQL sinnvoll ist, schnell beantwortet. Zahreiche Unternehmen kommen
durch den Einsatz von MySQL in den Genuß gewaltiger Kosteneinsparungen. Gleichzeitig
betreiben sie ihre anspruchsvollsten datenbankgetriebenen Systeme mit Hilfe der
benutzerfreundlichen Scale-Out-Architektur von MySQL.
Obwohl die SQL Server-Datenbankmigration normalerweise nicht leicht ist, gewährleisten Sie
durch die Verwendung der in diesem Dokument dargelegten Migrationsschritte einen
problemlosen, erfolgreichen Wechsel zu MySQL. Zur Unterstützung der Migration von SQL
Copyright © 2007, MySQL AB
Seite 16 von 49
Server bietet MySQL das frei verfügbare Migration Toolkit, mit dem bei der Datenbankmigration
erhebliche Zeit eingespart werden kann, während die Fehler, die normalerweise bei der
manuellen Durchführung derart komplexer Operationen entstehen, erheblich gesenkt werden.
Der Wechsel von SQL Server nach MySQL kann – unabhängig davon, ob er vollständig oder
teilweise erfolgt und ob MySQL und SQL Server für entsprechende Anwendungssituationen
verwendet werden – sehr sinnvoll sein, sowohl vom finanziellen als auch vom technologischen
Standpunkt aus betrachtet. Wenn Sie die Vorschläge und Schritte in diesem Dokument folgen,
können Sie sicher sein, daß Ihre Implementierung von MySQL erfolgreich sein wird. Unabhängig
davon, ob Sie lediglich einen Testlauf mit Open Source durchführen möchten oder sich bereits auf
MySQL festlegen und es damit zu Ihrer bevorzugten Datenbankplattform machen.
6 Weitere Informationsquellen
6.1 MySQL Migrationshilfen
MySQL Migration Toolkit
http://www.mysql.de/products/tools/migration-toolkit/
Die graphische Migration einer beliebigen Datenbank auf MySQL, auf die mit Hilfe von Oracle,
SQL Server, Microsoft Access oder JDBC zugegriffen werden kann.
Weitere Infos auf den MySQL-Webseiten
http://www.mysql.de/why-mysql/migration/
Erfahren Sie, wie Sie schnell und leicht Ihre bestehende Datenbank auf MySQL migrieren
können.
Migrationsforen
http://forums.mysql.com/
Arbeiten Sie mit anderen MySQL-Experten zusammen, die mit aktuellen Datenbankmigrationen
beschäftigt
sind.
MySQL Migrationsstarthilfe
http://www.mysql.de/consulting/packaged/migration.html
Wenn Sie einen MySQL-Berater benötigen, der Ihnen bei Ihrem Datenbank-Migrationsprojekt
Starthilfe gibt, dann ist das Beratungspaket MySQL Migrationsstarthilfe genau das richtige für Sie.
Unsere Seniorberater nutzen bewährte Methodiken, um von Oracle, Sybase, Microsoft SQL
Server, DB2, Informix und anderen Datenbanksystem auf MySQL zu migrieren.
6.2 Anwenderberichte
The Phone House Telecom wählt MySQL Enterprise Gold als Datenbank-Standard
http://www.mysql.de/why-mysql/case-studies/de/mysql-phonehouse.php.de
Onlineshop, CMS und Online-Rechnung waren bei The Phone House Telecom GmbH
unabhängige Systeme und verteilt auf Informix- und Oracle-Datenbanken. Vereinzelt wurde
MySQL für eigenentwickelte neue Funktionen eingesetzt. Diese nur schwer zu wartende
Systemlandschaft sollte mit einem grundlegenden Neuaufbau des Systems vereinheitlicht
werden. Heute laufen alle Websysteme (Händler Online-Aktivierungs- und Informationssystem,
CMS, Onlineshop, Kundenselbstadministration einschließlich Online-Rechnung) über einen
einheitlichen Softwarekern auf Basis von PHP mit dem MySQL Enterprise Server als Datenbank.
Cox Communications betreibt große Data Warehouse-Anwendungen mit MySQL, MySQL AB
http://www.mysql.com/it-resources/case-studies/cox.php
Cox Communications ist der viertgrößte Anbieter für Kabelfernsehen in den Vereinigten Staaten
und bedient rund 6,3 Millionen Kunden. Um eine optimale Leistungsfähigkeit und ein hohes
Niveau an Kundenservice sicherzustellen, hat Cox ein riesiges Data Warehouse-System
Copyright © 2007, MySQL AB
Seite 17 von 49
entwickelt. Das Herzstück dieses geschäftskritischen Systems bildet eine MySQL-Datenbank mit
2 Milliarden Datensätzen.
Friendster skaliert horizontal mit MySQL Enterprise, MySQL AB
http://www.mysql.com/it-resources/case-studies/cox.php
Friendster, die größte Webseite zum Social Networking mit über 60 Millionen Seitenansichten
täglich wählte MySQL Enterprise, um die richtige Kombination an erschwinglicher Zuverlässigkeit
und Skalierbarkeit der Datenbank zu erreichen. Ihr horizontal skaliertes LAMP-System verarbeitet
über eine Milliarde Datenbankabfragen am Tag. Zudem konnte das IT-Personal Millionen Dollar
Hardware- und Softwarekosten einsparen.
Citysearch spart über 1 Million Dollar mit MySQL, MySQL AB
http://www.mysql.com/why-mysql/case-studies/mysql-citysearch-casestudy.php
Citysearch ist ein führender regionaler Online-Suchservice, der die aktuellsten Informationen zu
Unternehmen – von Restaurants und Handel bis hin zu Reisen und qualifizierten Dienstleistungen
- zur Verfügung stellt. Diese Webseite verzeichnet monatlich über 10 Millionen einzelne Besucher.
Die Anzahl der Nutzer stieg exponentiell an, sodaß das ursprüngliche Oracle-System dem
Datenverkehr der Webseite nicht mehr gewachsen war. Zur Verarbeitung des Datenverkehrs und
einem Terabyte an Daten wurden replizierte MySQL-Server eingesetzt – damit war Citysearch in
der Lage, eine extrem hochleistungsfähige Lösung zur Verfügung zu stellen und zusätzlich über 1
Million Dollar an Datenbanklizenzen und Hardwarekosten einzusparen.
6.3 White Paper
Leitfaden zur Senkung der Datenbankkosten (TCO), MySQL AB
http://www.mysql.de/tco
Ein Artikel in der Computerworld „MySQL Breaks Into the Data Center“ zeigte auf, wie MySQL zur
populärsten Open-Source-Datenbank der Welt wurde und warum sie von Unternehmen, die
darauf bedacht sind, ihre Betriebskosten zu senken eingesetzt wird, um ihre IT-Infrastruktur zu
vereinheitlichen. In diesem White Paper zeigen wir Ihnen, wie Sie dabei vorgehen können. Sie
erfahren außerdem, wie Organisationen wie Cox Communications, NASA, Sabre Holdings und
Yahoo! Zuverlässigkeit, Leistungsfähigkeit und Datenbankbetriebskosten durch den Einsatz von
MySQL verbessert haben.
Kostengünstiges Datenbank Scale-Out durch den Einsatz von MySQL, MySQL AB
http://www.mysql.de/why-mysql/white-papers/scale-out.php
Zahlreiche moderne Unternehmen setzen MySQL in Verbindung mit handelsüblicher Hardware
ein, um hohe Kosteneinsparungen und nahezu uneingeschränkte Anwendungsskalierbarkeit zu
erreichen. In diesem White Paper werden wir die Techniken behandeln, welche MySQL-Kunden
heute einsetzen, um ihre wichtigsten Unternehmensanwendungen zu betreiben und abzusichern.
Copyright © 2007, MySQL AB
Seite 18 von 49
7 Anhang A – MSSQL to MySQL - Datatypes
7.1 Overview
This section provides a quick listing of the compatibility between SQL Server and MySQL with respect to
datatypes.
7.2 Comparable Datatypes
The following datatypes can be mapped in a one-to-one relationship from SQL Server to 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
Note that the DATETIME datatype in MySQL is a seven byte value that is currently down to the second
precision (although a future release will allow greater granularity), while SQL Server is an eight byte value that
has granularity down to the 3/100 second precision.
In addition, TIMESTAMP is a special datatype that is typically used to store the time a row was last created or
updated (which MySQL handles automatically).
7.3 Datatypes Requiring Conversion
The following map can be used to convert SQL Server datatypes that do not map in 1-to-1 relationship to
MySQL:
SQL Server
IDENTITY
NTEXT, NATIONAL TEXT
SMALLDATETIME
MONEY
SMALL MONEY
UNIQUEIDENTIFIER
SYSNAME
Copyright © 2007, MySQL AB
MySQL
AUTO_INCREMENT
TEXT CHARACTER SET UTF8
DATETIME
DECIMAL(19,4)
DECIMAL(10,4)
BINARY(16)
CHAR(256)
Seite 19 von 49
8 Anhang B – SQL Server to MySQL – Predicates
8.1 Overview
This section provides a list of the SQL predicates supported by SQL Server Database 10g and compares
them to equivalent predicates supported by MySQL version 5.0. The predicates are split into nine categories:
•
•
•
•
•
•
•
Predicates for comparison conditions
Predicates for exists conditions
Predicates for floating-point conditions
Predicates for in conditions
Predicates for null conditions
Predicates for pattern matching conditions
Predicates for range conditions
8.2 Synopsis
SQL Server and MySQL 5.0 both support the use of conditions in the WHERE clause of the SELECT,
DELETE, and UPDATE statements, as well as in the HAVING clause of the SELECT statement.
8.3 Boolean conditions
A Boolean condition combines two other conditions, to return a single result. SQL Server supports three
Boolean conditions.
Summary
Each SQL Server Boolean condition has an exact MySQL equivalent, and therefore no action is necessary
when migrating from SQL Server to MySQL.
SQL Server boolean conditions
expression1 AND expression2
Returns TRUE if both expressions return TRUE, UNKNOWN if either expression is NULL, FALSE otherwise.
MySQL equivalent: AND
NOT expression
Negates the result of expression; returns TRUE if expression is FALSE, UNKNOWN if expression is NULL, and
FALSE if expression is TRUE.
MySQL equivalent: NOT
expression1 OR expression2
Returns TRUE if either expression returns TRUE, UNKNOWN if either expression is NULL, FALSE otherwise.
MySQL equivalent: OR
8.4 Comparison conditions
Comparison conditions compare two expressions. SQL Server supports eight comparison conditions.
Summary
Each SQL Server comparison condition has an exact MySQL equivalent, and therefore no action is necessary
when migrating from SQL Server to MySQL.
Copyright © 2007, MySQL AB
Seite 20 von 49
SQL Server comparaison conditions
expression1 = expression2
Returns TRUE if the expressions are equal, UNKNOWN if either expression is NULL, and FALSE otherwise.
MySQL equivalent: =
expression1 <> expression2
Additional formats accepted (not all forms available on every platform): != ^= ¬=
Returns TRUE if the expressions are not equal, UNKNOWN if either expression is NULL, and FALSE
otherwise.
MySQL equivalent: <> !=
expression1 < expression2
Returns TRUE if expression1 is less than expression2, UNKNOWN if either expression is NULL, and FALSE
otherwise.
MySQL equivalent: <
expression1 <= expression2
Returns TRUE if expression1 is less than or equal to expression2, UNKNOWN if either expression is NULL,
and FALSE otherwise.
MySQL equivalent: <=
expression1 > expression2
Returns TRUE if expression1 is greater than expression2, UNKNOWN if either expression is NULL, and FALSE
otherwise.
MySQL equivalent: >
expression1 >= expression2
Returns TRUE if expression1 is greater than or equal to expression2, UNKNOWN if either expression is NULL,
and FALSE otherwise.
MySQL equivalent: >=
expression1 comparison ANY expression2
expression1 comparison SOME expression2
Synonyms; return TRUE if the comparison condition returns TRUE for at least one value in expression2 and
FALSE if the comparison condition returns either FALSE for every value in expression2 or returns an empty set
(zero rows).
comparison must be one of: = <> < <= > >=.
expression2 is generally a subquery, but may resolve to any expression.
MySQL equivalent: ANY, SOME, provided expression2 is a subquery.
expression1 comparison ALL expression2
Returns FALSE if the comparison condition returns FALSE for at least one value in expression2 and TRUE if
the comparison condition returns either TRUE for every value in expression2 or returns an empty set (zero
rows).
comparison must be one of: = <> < <= > >=.
expression2 is generally a subquery, but may resolve to any expression.
MySQL equivalent: ALL, provided expression2 is a subquery.
Copyright © 2007, MySQL AB
Seite 21 von 49
8.5 Exists conditions
Exists conditions test for rows in a sub query. SQL Server supports two exists conditions.
Summary
Each SQL Server exists condition has an exact MySQL equivalent, and therefore no action is necessary when
migrating from SQL Server to MySQL.
SQL Server exists conditions
EXISTS (subquery)
Returns TRUE if subquery returns at least one row, FALSE otherwise.
MySQL equivalent: EXISTS
NOT EXISTS (subquery)
Returns TRUE if subquery returns zero rows, FALSE otherwise.
MySQL equivalent: NOT EXISTS
8.6 In conditions
In conditions test whether a value is found in a set. SQL Server supports two in conditions.
Summary
Each SQL Server in condition has an exact MySQL equivalent, and therefore no action is necessary when
migrating from SQL Server to MySQL.
SQL Server in conditions
expression IN {value_list | (subquery)}
Returns TRUE if expression equals any value in value_list (or returned by subquery), UNKNOWN if either
argument is NULL, FALSE otherwise.
MySQL equivalent: IN
expression NOT IN {value_list | (subquery)}
Returns TRUE if expression does not equal any value in value_list (or returned by subquery), UNKNOWN if
either argument is NULL, FALSE otherwise.
MySQL equivalent: NOT IN
8.7 Null conditions
Null conditions test for null values. SQL Server supports two null conditions.
Summary
Each SQL Server null condition has an exact MySQL equivalent, and therefore no action is necessary when
migrating from SQL Server to MySQL.
SQL Server null conditions
expression IS NULL
Copyright © 2007, MySQL AB
Seite 22 von 49
Returns TRUE if the result of expression is NULL, FALSE otherwise.
MySQL equivalent: IS NULL
expression IS NOT NULL
Returns TRUE if the result of expression is not NULL, FALSE otherwise.
MySQL equivalent: IS NOT NULL
8.8
Pattern matching conditions
Pattern matching conditions test whether a value matches a specific pattern. SQL Server supports nine pattern
matching conditions.
SQL Server pattern matching conditions
string_expression LIKE pattern [ESCAPE escape_string]
Returns TRUE if string_expression matches pattern, UNKNOWN if any argument is NULL, FALSE otherwise.
Uses the current (input) character set to interpret all arguments.
MySQL equivalent: LIKE
string_expression NOT LIKE pattern [ESCAPE escape_string]
Returns TRUE if string_expression does not match pattern, UNKNOWN if any argument is NULL, FALSE
otherwise.
Uses the current (input) character set to interpret all arguments.
MySQL equivalent: NOT LIKE
8.9
Range conditions
Range conditions test for inclusion in a range of values. SQL Server supports two range conditions.
Summary
Each SQL Server range condition has an exact MySQL equivalent, and therefore no action is necessary when
migrating from SQL Server to MySQL.
SQL Server range conditions
expression1 BETWEEN expression2 AND expression3
Returns TRUE if expression1 falls into the range of values specified by the other expressions (i.e. if
expression1 is greater than or equal to expression2 and less than or equal to expression3), UNKNOWN if any
expression is NULL, FALSE otherwise.
MySQL equivalent: BETWEEN
expression1 NOT BETWEEN expression2 AND expression3
Returns TRUE if expression1 does not fall into the range of values specified by expression2 and expression3,
UNKNOWN if any expression is NULL, FALSE otherwise.
MySQL equivalent: NOT BETWEEN
Copyright © 2007, MySQL AB
Seite 23 von 49
9 Anhang C – SQL Server to MySQL – Operators and
Date Functions
9.1 Overview
This paper provides a list of the built-in SQL operators supported by SQL Server Database 10g and compares
them to equivalent operators supported by MySQL version 5.0. The operators are split into five categories:
•
•
•
•
Arithmetic operators
Concatenation operators
Hierarchical Query operators
Set operators
9.2 Arithmetic operators
Summary
Each SQL Server arithmetic operator has an exact MySQL equivalent, and therefore no action is necessary
when migrating from SQL Server to MySQL.
SQL Server arithmetic operators
+
When used as a unary operator, indicates a positive numeric or temporal expression.
When used as a binary operator, adds two numeric or temporal values.
MySQL equivalent: +
When used as a unary operator, indicates a negative numeric or temporal expression.
When used as a binary operator, subtracts one numeric or temporal value from another.
MySQL equivalent: *
Binary operator; multiplies numeric expressions.
MySQL equivalent: *
/
Binary operator; divides numeric expressions.
MySQL equivalent: /
9.3 Concatenation operators
Summary
When the MySQL server is started with the –ansi option, the SQL Server || (concatenation) operator has an
exact MySQL equivalent, and therefore no action is necessary when migrating from SQL Server to MySQL.
When the MySQL server is started in the default mode, map SQL Server || to MySQL CONCAT('string1',
'string2').
No other concatenation operators are supported by SQL Server, although SQL Server's CONCAT string
function serves the same purpose.
Copyright © 2007, MySQL AB
Seite 24 von 49
SQL Server concatenation operators
+
Concatenates character strings and CLOB values.
MySQL equivalent (--ansi mode): ||
MySQL equivalent (default mode): CONCAT('string1', 'string2')
9.4 Hierarchical query operators
Summary
SQL Server LEVEL has no MySQL equivalent.
9.5 Set operators
Summary
SQL Server INTERSECT and EXCEPT have no MySQL equivalent.
All other SQL Server set operators have an exact MySQL equivalent, and therefore no action is necessary
when migrating from SQL Server to MySQL.
SQL Server set operators
UNION
Combines two SELECT queries.
Returns all distinct (non-duplicate) rows found by either SELECT.
MySQL equivalent: UNION.
UNION ALL
Combines two SELECT queries.
Returns all rows found by either SELECT, including duplicates.
MySQL equivalent: UNION ALL.
Copyright © 2007, MySQL AB
Seite 25 von 49
9.6 Date Functions
Summary
The majority of date functions in SQL Server can be replicated in MySQL.
Date Formats
SQL Server
YYYYMMDD
YYYY MonthName DD
MM/DD/YY[YY]
MM-DD-YY[YY]
MM.DD.YY[YY]
MySQL
YYYYMMDD
YY[YY]-MM-DD
YY[YY]/MM/DD
YY[YY]-MM-DD
YY[YY].MM.DD
Date Functions
SQL Server
DATEADD(day, 1, GETDATE())
DATEDIFF(day, GETDATE(),
GETDATE()-1)
DATENAME(month, GETDATE())
DATENAME(weekday, GETDATE())
DATEPART(month, GETDATE())
DAY(GETDATE())
GETDATE()
GETDATE() + 1
GETUTCDATE()
MONTH(GETDATE())
YEAR(GETDATE())
Copyright © 2007, MySQL AB
MySQL
DATE_ADD(NOW(), INTERVAL 1 DAY)
DATEDIFF(NOW(), NOW() – INTERVAL 1 DAY)
DATE_FORMAT(NOW(), ‘%M’)
MONTHNAME(NOW())
DATE_FORMAT(NOW(), ‘%W’)
DAYNAME(NOW())
DATE_FORMAT(NOW(), ‘%m’)
DATE_FORMAT(NOW(), ‘%d’)
DAY(NOW()) (as of MySQL 4.1.1)
DAYOFMONTH(NOW())
NOW()
SYSDATE()
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP()
NOW() + INTERVAL 1 DAY
CURRENT_TIMESTAMP + INTERVAL 1 DAY
UTC_TIMESTAMP()
MONTH(NOW())
YEAR(NOW())
Seite 26 von 49
10 Anhang D – T-SQL Conversion Suggestions
10.1 Overview
As of March 2006 the MySQL migration tool does not migrate MS SQL Transact SQL code to
MySQL. Because of this stored procedures and other code objects in SQL Server need to be
migrated manually. This appendix provides suggestions in converting Microsoft T-SQL code to
MySQL.
10.2 Getting T-SQL Code out of SQL Server
The stored procedures are extracted from SQL Server using the SQL Server ‘create scripts’
option with all Stored Procedure selected and the generate a file for each stored procedure flag
selected.
10.3 Procedure Formats
While the general format for an MS stored procedure is:
CREATE PROCEDURE name
Param1 type,
Param2 type
AS
Statement1
Statement2
MySQL requires that a format of:
CREATE PROCEDURE name (
Param1 type,
Param2 type
)
BEGIN
Statement1 ;
StateMent2 ;
…
END ;
With the major differences being that MySQL:
1.
2.
3.
4.
5.
Requires that the parameter list be in ‘(‘ ‘)” pairs
Cannot take an AS after the parameter list
Requires a BEGIN END pair if there is more than one statement in the stored procedure
Requires that every statement is terminated by a ‘;’.
In MySQL stored procedures all variable declarations must come before the first non-declare
statement.
10.4 Error Handling
In SQL Server, errors below a certain level are returned in @@ERROR and the Stored Procedure
continues while errors above that level terminate the Stored Procedure immediately and return
and error to the caller. In MySQL most errors terminate the Stored Procedure and return an error
code. To get a MySQL Stored Procedure to behave more like a SQL Server Stored Procedure
you must define an error handler as follows:
DECLARE "@ERROR" INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
Copyright © 2007, MySQL AB
Seite 27 von 49
SET "@ERROR" = 1;
END;
And then modify your Stored Procedure code to use the @ERROR variable instead of @@ERROR, for
example, replace:
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
With:
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;
10.5 Use LIMIT instead of TOP
The MySQL, the LIMIT feature in a SELECT both replaces the SQL Server TOP function and adds
new functionality not available in TOP. In its simplest form:
Replace:
SELECT TOP 100 * FROM TABLE
With:
SELECT * FROM TABLE LIMIT 100 ;
Copyright © 2007, MySQL AB
Seite 28 von 49
If you want to get 10 records starting at position 100, then use:
SELECT * FROM TABLE LIMIT 100,10 ;
Note that the values in the LIMIT clause must be constants, variables are not allowed.
You cannot use:
SELECT * FROM TABLE LIMIT @start,@rows ;
To get around this issue you can use a PREPARE statement as follows. Assuming the query you
want to run is:
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" ;
Use the following code to implement the 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"
;
10.6 LIMIT and Optimization
In some cases, MySQL handles a query differently when you are using LIMIT <row_count>
and not using HAVING:
•
If you are selecting only a few rows with LIMIT, MySQL uses indexes in some cases when
normally it would prefer to do a full table scan.
•
If you use LIMIT row_count with ORDER BY, MySQL ends the sorting as soon as it has
found the first row_count rows of the sorted result, rather than sorting the entire result. If
ordering is done by using an index, this is very fast. If a filesort must be done, all rows that
match the query without the LIMIT clause must be selected, and most or all of them must
be sorted, before it can be ascertained that the first row_count rows have been found. In
either case, after the initial rows have been found, there is no need to sort any remainder of
the result set, and MySQL does not do so.
•
When combining LIMIT row_count with DISTINCT, MySQL stops as soon as it finds
row_count unique rows.
Copyright © 2007, MySQL AB
Seite 29 von 49
•
In some cases, a GROUP BY can be resolved by reading the key in order (or doing a sort
on the key) and then calculating summaries until the key value changes. In this case,
LIMIT row_count does not calculate any unnecessary GROUP BY values.
•
As soon as MySQL has sent the required number of rows to the client, it aborts the query
unless you are using SQL_CALC_FOUND_ROWS.
•
LIMIT 0 quickly returns an empty set. This can be useful for checking the validity of a
query. When using one of the MySQL APIs, it can also be employed for obtaining the types
of the result columns. (This trick does not work in the MySQL Monitor, which merely
displays Empty set in such cases; you should instead use SHOW COLUMNS or DESCRIBE
for this purpose.)
•
When the server uses temporary tables to resolve the query, it uses the LIMIT
row_count clause to calculate how much space is required.
10.7 IF THEN … ELSE … END IF ;
MySQL requires that an IF include a THEN and that a block with more than one statement must
be terminated by an ‘END IF ;’. Note that the ‘;’ after the END IF is required.
IF <expr> THEN
Statement 1;
ELSE
Statement 2 ;
END IF;
10.8 DATETIME with default values
The MySQL migration tool cannot handle migrating DATETIME columns that have a default value
of getdate(). For example:
UPLOADED DATETIME NULL DEFAULT GETDATE(),
Tables with DATETIME columns with the above default will not automatically be converted and
must be manually modified as follows:
UPLOADED TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMTP,
Note that only the TIMESTAMP type can have a default value of CURRENT_TIMESTATMP so if
you want to keep the default you must also change the type from DATETIME to TIMEDSTAMP.
Another difference between MySQL and SQL Server is that MySQL only allows 1 column per
table to have a default value of CURRENT_TIMESTATMP. For tables in SQL Server with two or
more columns with default values set to GETDATE(), one or the other column must have its
default value removed for the table to create successfully. In addition, MySQL implicitly assigns a
default value of CURRENT_TIMESTAMP to the first TIMESTAMP column in a create table
statement unless it is explicitly assigned a default value other than NULL or
CURRENT_TIMESTATMP. This means that if you are converting a table that has two columns
with a default values of getdate() and you choose the second column as the one to have the
default value you will get a error creating the table if you do not explicitly assign a default value,
such as 0 or ‘0000-00-00 00:00:00’ to the first column.
10.9 Index Name Length Differences
MySQL does not support index names longer than 64 bytes. Indexes with names longer than 64
bytes must be renamed.
Copyright © 2007, MySQL AB
Seite 30 von 49
10.10 Support for SQL Server Declared Tables
SQL Server supports a ‘table’ data type in an stored procedure. For example:
DECLARE "@Results" TABLE
(Pos int IDENTITY, ClassifiedID int)
MySQL does not support this. Instead, use a temporary in memory table:
CREATE TEMPORARY TABLE temp1
(ClassifiedID int) ENGINE = MEMORY;
< other code >
DROP TEMPORARY TABLE temp1 ;
10.11 Obtaining Row Counts
In MySQL, the function ROW_COUNT() returns the number of rows effected by the last insert,
update, or delete. Use this instead of the SQL Server @@ROWCOUNT variable.
10.12 Default Values for Parameters
In SQL Server a parameter can have the form:
@Param int default
0
MySQL does not support this. The application must be changed to pass in the appropriate default
values.
10.13 Use of SELECT INTO
In SQL Server, if you want to set a variable based on the results of a SELECT you use:
SELECT INTO A=col1 …
In MySQL, the INTO will cause an error, so you will need to use:
SELECT A=col1 …
10.14 Uses of IFNULL
Use the IFNULL() function to check if a value is NULL and then return either the value or another
value based on the results of the test. The IFNULL() function returns A if A is not NULL, and
returns B otherwise.
10.15 Replace DATEADD with ADDDATE()
The MySQL function ADDDATE() replaces DATEADD(). For example:
Replace:
DATEADD(dd, -14, GETDATE())
With:
ADDDATE(NOW(),INTERVAL -14 DAY) ;
Copyright © 2007, MySQL AB
Seite 31 von 49
10.16 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
This exact syntax works in MySQL and can be placed at the top of each Stored Procedure if
desired. The better solution is to set the value of transaction-isolation in the my.cnf file:
transaction-isolation=READ-UNCOMMITTED
10.17 Replace SET ROWCOUNT = @rows with SQL_SELECT_LIMIT
Use SQL_SELECT_LIMIT instead of ROWCOUNT in MySQL to limit the rows returned in a select.
This method allows the number of rows returned to be set by a variable without using a prepare
statement.
Replace:
SET ROOWCOUNT = @rowcount
With
SET SQL_SELECT_LIMIT=@rowcount;
10.18 Perl Script to Help with Conversion of T-SQL to MySQL
The Perl script below assists in the conversion of SQL Server T-SQL to MySQL. Note that it
performs rudimentary changes only, so many complex SQL Server code objects will still have to
be massaged by hand. Many thanks go to Brian Miezejewski of MySQL Professional Services for
providing the utility.
The method of using the Perl conversion utility is as follows:
1. Extract all desired SQL Server stored procedures into files and place them into a single
directory.
2. Run the below perl script ‘MSProcstoMySql.pl’ as such: perl MSProcstoMySql.pl
*.PRC
3. The procedure will create a subdirectory called ‘converted’ and place the converted
stored procedures in that directory.
The following example shows a stored procedure before and after the above perl script is run:
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
Copyright © 2007, MySQL AB
Seite 32 von 49
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
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 ;$$
The Perl conversion routine performs the following functions:
1. Renames the file from dbo.spName.PRC to spName.sql
2. Wraps the code in:
• DELIMITER $$;
• SET SQL_MODE = ANSI_QUOTES$$
• <Stored procedure code>
• $$
• DELIMITER ;$$
3. Removes all ‘GO’ statements from the code
Copyright © 2007, MySQL AB
Seite 33 von 49
4. Remove all SET statements for QUOTED_IDENTIFIER, ANSI_NULL, NOCOUNT, and
LOCK_TIMEOUT.
5. Comments out both BEGIN TRAN and COMMIT TRAN
6. Replaces all @@IDENTITY references with a call to LAST_INSERT_ID()
7. Wraps every reference to a variable of the format @<name> in double quotes, i.e. @vari
becomes “@vari”
8. Makes all table names lower case
9. Changes NVARCHAR types to VARCHAR
10. Places the parameter list in parentheses
11. Removes the AS after the parameter list
12. Wraps all code after the parameter list in a BEGIN END block
13. Replaces all call to GETDATE() with calls to NOW()
While the script makes many changes to the SQL Server stored procedures, it does not fully
convert them. Each stored procedure will still need to be reviewed and modified before it can be
used. The following list includes some of the more common issues that will still need to be fixed:
•
•
•
10.18.1
Place a ‘;’ after every statement
Add an error handler
Remove any IF @@ERROR<>0 GOTO LABEL and replace them with IF … END
IF blocks using the value set in the error handler.
Perl Conversion Script
#!/usr/bin/perl
if (! -d "converted" ) {
mkdir "converted" ;
}
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 ;
Copyright © 2007, MySQL AB
;
Seite 34 von 49
};
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 ;
}
Copyright © 2007, MySQL AB
Seite 35 von 49
11 Anhang E – Sample Migration
This section provides a simple example of moving an SQL Server 2005 database schema over to
MySQL using the MySQL Migration Toolkit.
11.1 Sample SQL Server Schema
The SQL Server 2005 schema is a small database used for tracking financial investments in a small
brokerage company. The SQL Server schema DDL is as follows:
--- CREATE Tables
-CREATE TABLE BROKER
(
BROKER_ID
numeric(18,0) NOT NULL,
OFFICE_LOCATION_ID
numeric(18,0) NULL,
BROKER_LAST_NAME
varchar(40)
NOT NULL,
BROKER_FIRST_NAME
varchar(20)
NOT NULL,
BROKER_MIDDLE_INITIAL char(1)
NULL,
MANAGER_ID
numeric(18,0) NULL,
YEARS_WITH_FIRM
numeric(3,1) NOT NULL,
CONSTRAINT BROKER_PK
PRIMARY KEY CLUSTERED (BROKER_ID)
)
go
IF OBJECT_ID('BROKER') IS NOT NULL
PRINT '<<< CREATED TABLE BROKER >>>'
ELSE
PRINT '<<< FAILED CREATING TABLE BROKER >>>'
go
CREATE TABLE CLIENT_TRANSACTION
(
CLIENT_TRANSACTION_ID
numeric(18,0) NOT NULL,
CLIENT_ID
numeric(18,0) NOT NULL,
INVESTMENT_ID
numeric(18,0) NOT NULL,
[ACTION]
varchar(10)
NOT NULL,
PRICE
numeric(12,2) NOT NULL,
NUMBER_OF_UNITS
numeric(18,0) NOT NULL,
TRANSACTION_STATUS
varchar(10)
NOT NULL,
TRANSACTION_SUB_TIMESTAMP datetime
NOT NULL,
TRANSACTION_COMP_TIMESTAMP datetime
NOT NULL,
DESCRIPTION
varchar(200) NULL,
BROKER_ID
numeric(18,0) NULL,
BROKER_COMMISSION
numeric(10,2) NULL,
CONSTRAINT CLIENT_TRANSACTION_PK
PRIMARY KEY CLUSTERED (CLIENT_TRANSACTION_ID)
)
go
IF OBJECT_ID('CLIENT_TRANSACTION') IS NOT NULL
PRINT '<<< CREATED TABLE CLIENT_TRANSACTION >>>'
ELSE
PRINT '<<< FAILED CREATING TABLE CLIENT_TRANSACTION >>>'
go
CREATE TABLE CLIENT
(
CLIENT_ID
numeric(18,0) NOT NULL,
CLIENT_FIRST_NAME
varchar(20)
NOT NULL,
CLIENT_LAST_NAME
varchar(40)
NOT NULL,
CLIENT_GENDER
char(1)
NOT NULL,
CLIENT_YEAR_OF_BIRTH
numeric(4,0) NOT NULL,
CLIENT_MARITAL_STATUS
varchar(20)
NULL,
CLIENT_STREET_ADDRESS
varchar(40)
NOT NULL,
CLIENT_POSTAL_CODE
varchar(10)
NOT NULL,
CLIENT_CITY
varchar(30)
NOT NULL,
Copyright © 2007, MySQL AB
Seite 36 von 49
CLIENT_STATE_PROVINCE
varchar(40)
CLIENT_PHONE_NUMBER
varchar(25)
CLIENT_HOUSEHOLD_INCOME numeric(30,0)
CLIENT_COUNTRY
varchar(40)
BROKER_ID
numeric(18,0)
CONSTRAINT CLIENT_PK
PRIMARY KEY CLUSTERED (CLIENT_ID)
NOT NULL,
NOT NULL,
NULL,
NULL,
NOT NULL,
)
go
IF OBJECT_ID('CLIENT') IS NOT NULL
PRINT '<<< CREATED TABLE CLIENT >>>'
ELSE
PRINT '<<< FAILED CREATING TABLE CLIENT >>>'
go
--- Foreign Keys
-ALTER TABLE CLIENT_TRANSACTION
ADD CONSTRAINT CLIENT_TRANSACTION_CLIENT
FOREIGN KEY (CLIENT_ID)
REFERENCES CLIENT (CLIENT_ID)
ON DELETE CASCADE
go
--- CREATE Indexes
-CREATE NONCLUSTERED INDEX CLIENT_BROKER
ON CLIENT(BROKER_ID)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('CLIENT') AND
name='CLIENT_BROKER')
PRINT '<<< CREATED INDEX CLIENT.CLIENT_BROKER >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX CLIENT.CLIENT_BROKER >>>'
go
--- Foreign Keys
-ALTER TABLE CLIENT_TRANSACTION
ADD CONSTRAINT CLIENT_TRANSACTION_BROKER
FOREIGN KEY (BROKER_ID)
REFERENCES BROKER (BROKER_ID)
ON DELETE CASCADE
go
ALTER TABLE CLIENT
ADD CONSTRAINT FK__CLIENT__BROKER_I__0F975522
FOREIGN KEY (BROKER_ID)
REFERENCES BROKER (BROKER_ID)
go
--- CREATE Indexes
-CREATE NONCLUSTERED INDEX CLIENT_TRANSACTION_BROKER
ON CLIENT_TRANSACTION(BROKER_ID)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('CLIENT_TRANSACTION') AND
name='CLIENT_TRANSACTION_BROKER')
PRINT '<<< CREATED INDEX CLIENT_TRANSACTION.CLIENT_TRANSACTION_BROKER >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX CLIENT_TRANSACTION.CLIENT_TRANSACTION_BROKER
>>>'
go
CREATE NONCLUSTERED INDEX CLIENT_TRANSACTION_CLIENT
ON CLIENT_TRANSACTION(CLIENT_ID)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('CLIENT_TRANSACTION') AND
Copyright © 2007, MySQL AB
Seite 37 von 49
name='CLIENT_TRANSACTION_CLIENT')
PRINT '<<< CREATED INDEX CLIENT_TRANSACTION.CLIENT_TRANSACTION_CLIENT >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX CLIENT_TRANSACTION.CLIENT_TRANSACTION_CLIENT
>>>'
go
CREATE NONCLUSTERED INDEX CLIENT_TRANSACTION_INVESTMENT
ON CLIENT_TRANSACTION(INVESTMENT_ID)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('CLIENT_TRANSACTION') AND
name='CLIENT_TRANSACTION_INVESTMENT')
PRINT '<<< CREATED INDEX CLIENT_TRANSACTION.CLIENT_TRANSACTION_INVESTMENT >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX
CLIENT_TRANSACTION.CLIENT_TRANSACTION_INVESTMENT >>>'
go
--- CREATE Tables
-CREATE TABLE INVESTMENT
(
INVESTMENT_ID
numeric(18,0) NOT NULL,
INVESTMENT_TYPE_ID numeric(18,0) NULL,
INVESTMENT_VENDOR
varchar(30)
NULL,
INVESTMENT_NAME
varchar(200) NULL,
INVESTMENT_UNIT
varchar(20)
NULL,
INVESTMENT_DURATION varchar(10)
NULL,
CONSTRAINT INVESTMENT_PK
PRIMARY KEY CLUSTERED (INVESTMENT_ID)
)
go
IF OBJECT_ID('INVESTMENT') IS NOT NULL
PRINT '<<< CREATED TABLE INVESTMENT >>>'
ELSE
PRINT '<<< FAILED CREATING TABLE INVESTMENT >>>'
go
--- CREATE Indexes
-CREATE NONCLUSTERED INDEX INVESTMENT_INVESTMENT_TYPE
ON INVESTMENT(INVESTMENT_TYPE_ID)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('INVESTMENT') AND
name='INVESTMENT_INVESTMENT_TYPE')
PRINT '<<< CREATED INDEX INVESTMENT.INVESTMENT_INVESTMENT_TYPE >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX INVESTMENT.INVESTMENT_INVESTMENT_TYPE >>>'
go
--- CREATE Tables
-CREATE TABLE INVESTMENT_TYPE
(
INVESTMENT_TYPE_ID
numeric(18,0) NOT NULL,
INVESTMENT_TYPE_NAME varchar(30)
NOT NULL,
CONSTRAINT INVESTMENT_TYPE_PK
PRIMARY KEY CLUSTERED (INVESTMENT_TYPE_ID)
)
go
IF OBJECT_ID('INVESTMENT_TYPE') IS NOT NULL
PRINT '<<< CREATED TABLE INVESTMENT_TYPE >>>'
ELSE
PRINT '<<< FAILED CREATING TABLE INVESTMENT_TYPE >>>'
go
--- Foreign Keys
Copyright © 2007, MySQL AB
Seite 38 von 49
-ALTER TABLE INVESTMENT
ADD CONSTRAINT FK__INVESTMEN__INVES__108B795B
FOREIGN KEY (INVESTMENT_TYPE_ID)
REFERENCES INVESTMENT_TYPE (INVESTMENT_TYPE_ID)
go
ALTER TABLE CLIENT_TRANSACTION
ADD CONSTRAINT CLIENT_TRANSACTION_INVESTMENT
FOREIGN KEY (INVESTMENT_ID)
REFERENCES INVESTMENT (INVESTMENT_ID)
ON DELETE CASCADE
go
--- CREATE Tables
-CREATE TABLE OFFICE_LOCATION
(
OFFICE_LOCATION_ID
numeric(18,0) NOT NULL,
OFFICE_NAME
varchar(20)
NOT NULL,
OFFICE_ADDRESS
varchar(50)
NOT NULL,
OFFICE_CITY
varchar(30)
NOT NULL,
OFFICE_STATE_PROVINCE varchar(40)
NOT NULL,
OFFICE_POSTAL_CODE
varchar(10)
NOT NULL,
OFFICE_COUNTRY
varchar(40)
NULL,
CONSTRAINT OFFICE_LOCATION_PK
PRIMARY KEY CLUSTERED (OFFICE_LOCATION_ID)
)
go
IF OBJECT_ID('OFFICE_LOCATION') IS NOT NULL
PRINT '<<< CREATED TABLE OFFICE_LOCATION >>>'
ELSE
PRINT '<<< FAILED CREATING TABLE OFFICE_LOCATION >>>'
go
--- Foreign Keys
-ALTER TABLE BROKER
ADD CONSTRAINT BROKER_OFFICE_LOCATION
FOREIGN KEY (OFFICE_LOCATION_ID)
REFERENCES OFFICE_LOCATION (OFFICE_LOCATION_ID)
ON DELETE CASCADE
go
---- CREATE Indexes
-CREATE NONCLUSTERED INDEX BROKER_LOCATION
ON BROKER(OFFICE_LOCATION_ID)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('BROKER') AND
name='BROKER_LOCATION')
PRINT '<<< CREATED INDEX BROKER.BROKER_LOCATION >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX BROKER.BROKER_LOCATION >>>'
go
Copyright © 2007, MySQL AB
Seite 39 von 49
11.2 Moving the SQL Server Database to MySQL with the Migration
Toolkit
The following steps are used to move the SQL Server 2005 database schema (with data) over to a
MySQL 5.x database.
Step 1 – Connect to SQL Server Source Server and database:
Supply a SQL Server connection string along with an ID, password, and database, and then connect
to SQL Server.
Step 2 – Connect to MySQL Target Server:
Copyright © 2007, MySQL AB
Seite 40 von 49
Enter MySQL connection information for the target server. The Migration Toolkit connects to both the
source and target servers.
Step 3 – Select Target Users/Schema(s) to Migrate:
For this example, SQL Server ‘gim’ database is the source database, with the ‘dbo’ user/schema
being migrated. Note that more than one schema can be selected. The Migration Toolkit will reverse
engineer the source database schema along with all datatypes, etc.
Step 4 (Optional) – Choose Objects to Migrate:
You can optionally select what objects to migrate to MySQL. The default is all data objects in the
schema.
Copyright © 2007, MySQL AB
Seite 41 von 49
Step 5 – Tweak MySQL Defaults:
This step allows you to customize your MySQL settings like target engine, etc. Intelligent defaults are
provided (such as InnoDB storage engine for SQL Server databases, using autoincrement columns,
etc.) The Migration Toolkit will then proceed and inform you if any mapping problems are found and
generate the SQL necessary to create the MySQL target database.
Step 6 – Create MySQL Target Objects:
This step allows you to create the new MySQL database and object schema (with no data) online or
save the SQL statements to a file. If you choose to proceed with the default online option, the
Migration Toolkit will create the MySQL database and schema objects:
Copyright © 2007, MySQL AB
Seite 42 von 49
Step 7 – Migrate Existing SQL Server Data to MySQL:
This step allows you to migrate the existing SQL Server data to the new MySQL database schema.
You can optionally choose to generate INSERT statements into a file for later execution. If you
choose to proceed, the migration toolkit will move the data in bulk from SQL Server to MySQL:
Copyright © 2007, MySQL AB
Seite 43 von 49
Step 8 – Review Migration
The final step is to review the migration process and ensure the desired results were obtained.
Copyright © 2007, MySQL AB
Seite 44 von 49
11.3 Sample MySQL Schema Generated from SQL Server
The following MySQL database was generated from the sample SQL Server10g schema:
DROP TABLE IF EXISTS gim_dbo.BROKER;
CREATE TABLE gim_dbo.BROKER (
BROKER_ID decimal(18,0) NOT NULL,
OFFICE_LOCATION_ID decimal(18,0) default NULL,
BROKER_LAST_NAME varchar(40) NOT NULL,
BROKER_FIRST_NAME varchar(20) NOT NULL,
BROKER_MIDDLE_INITIAL char(1) default NULL,
MANAGER_ID decimal(18,0) default NULL,
YEARS_WITH_FIRM decimal(3,1) NOT NULL,
PRIMARY KEY (BROKER_ID),
KEY BROKER_LOCATION (OFFICE_LOCATION_ID),
CONSTRAINT BROKER_OFFICE_LOCATION FOREIGN KEY (OFFICE_LOCATION_ID) REFERENCES OFFICE_LOCATION
(OFFICE_LOCATION_ID) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS gim_dbo.CLIENT;
CREATE TABLE gim_dbo.CLIENT (
CLIENT_ID decimal(18,0) NOT NULL,
CLIENT_FIRST_NAME varchar(20) NOT NULL,
CLIENT_LAST_NAME varchar(40) NOT NULL,
CLIENT_GENDER char(1) NOT NULL,
CLIENT_YEAR_OF_BIRTH decimal(4,0) NOT NULL,
CLIENT_MARITAL_STATUS varchar(20) default NULL,
CLIENT_STREET_ADDRESS varchar(40) NOT NULL,
CLIENT_POSTAL_CODE varchar(10) NOT NULL,
CLIENT_CITY varchar(30) NOT NULL,
CLIENT_STATE_PROVINCE varchar(40) NOT NULL,
CLIENT_PHONE_NUMBER varchar(25) NOT NULL,
CLIENT_HOUSEHOLD_INCOME decimal(30,0) default NULL,
CLIENT_COUNTRY varchar(40) default NULL,
BROKER_ID decimal(18,0) NOT NULL,
PRIMARY KEY (CLIENT_ID),
KEY CLIENT_BROKER (BROKER_ID),
CONSTRAINT FK__CLIENT__BROKER_I__0F975522 FOREIGN KEY (BROKER_ID) REFERENCES BROKER
(BROKER_ID) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS gim_dbo.CLIENT_TRANSACTION;
CREATE TABLE gim_dbo.CLIENT_TRANSACTION (
CLIENT_TRANSACTION_ID decimal(18,0) NOT NULL,
CLIENT_ID decimal(18,0) NOT NULL,
INVESTMENT_ID decimal(18,0) NOT NULL,
ACTION varchar(10) NOT NULL,
PRICE decimal(12,2) NOT NULL,
NUMBER_OF_UNITS decimal(18,0) NOT NULL,
TRANSACTION_STATUS varchar(10) NOT NULL,
TRANSACTION_SUB_TIMESTAMP datetime NOT NULL,
TRANSACTION_COMP_TIMESTAMP datetime NOT NULL,
DESCRIPTION varchar(200) default NULL,
BROKER_ID decimal(18,0) default NULL,
BROKER_COMMISSION decimal(10,2) default NULL,
PRIMARY KEY (CLIENT_TRANSACTION_ID),
KEY CLIENT_TRANSACTION_BROKER (BROKER_ID),
KEY CLIENT_TRANSACTION_CLIENT (CLIENT_ID),
KEY CLIENT_TRANSACTION_INVESTMENT (INVESTMENT_ID),
CONSTRAINT CLIENT_TRANSACTION_BROKER FOREIGN KEY (BROKER_ID) REFERENCES BROKER (BROKER_ID) ON
DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT CLIENT_TRANSACTION_INVESTMENT FOREIGN KEY (INVESTMENT_ID) REFERENCES INVESTMENT
(INVESTMENT_ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT CLIENT_TRANSACTION_CLIENT FOREIGN KEY (CLIENT_ID) REFERENCES CLIENT (CLIENT_ID) ON
DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS gim_dbo.INVESTMENT;
CREATE TABLE gim_dbo.INVESTMENT (
INVESTMENT_ID decimal(18,0) NOT NULL,
INVESTMENT_TYPE_ID decimal(18,0) default NULL,
INVESTMENT_VENDOR varchar(30) default NULL,
INVESTMENT_NAME varchar(200) default NULL,
INVESTMENT_UNIT varchar(20) default NULL,
INVESTMENT_DURATION varchar(10) default NULL,
PRIMARY KEY (INVESTMENT_ID),
Copyright © 2007, MySQL AB
Seite 45 von 49
KEY INVESTMENT_INVESTMENT_TYPE (INVESTMENT_TYPE_ID),
CONSTRAINT FK__INVESTMEN__INVES__108B795B FOREIGN KEY (INVESTMENT_TYPE_ID) REFERENCES
INVESTMENT_TYPE (INVESTMENT_TYPE_ID) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS gim_dbo.INVESTMENT_TYPE;
CREATE TABLE gim_dbo.INVESTMENT_TYPE (
INVESTMENT_TYPE_ID decimal(18,0) NOT NULL,
INVESTMENT_TYPE_NAME varchar(30) NOT NULL,
PRIMARY KEY (INVESTMENT_TYPE_ID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS gim_dbo.OFFICE_LOCATION;
CREATE TABLE gim_dbo.OFFICE_LOCATION (
OFFICE_LOCATION_ID decimal(18,0) NOT NULL,
OFFICE_NAME varchar(20) NOT NULL,
OFFICE_ADDRESS varchar(50) NOT NULL,
OFFICE_CITY varchar(30) NOT NULL,
OFFICE_STATE_PROVINCE varchar(40) NOT NULL,
OFFICE_POSTAL_CODE varchar(10) NOT NULL,
OFFICE_COUNTRY varchar(40) default NULL,
PRIMARY KEY (OFFICE_LOCATION_ID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
11.4 Sample Code Migration
As was mentioned, no automatic conversion exists in terms of migrating SQL Server T-SQL code
objects to MySQL, although a prior Appendix in this paper does supply some guidance and a simple
Perl conversion utility. MySQL is in discussions with several partners on providing this functionality,
but until a mechanized solution is reached, there are several options open to performing code
migration:
1. Contact MySQL Professional Services group to help with the code migration. Staff at
MySQL have assisted in code conversions from a number of platforms to MySQL.
2. Perform code migrations internally.
The difficulty level of migrating SQL Server T-SQL code to MySQL depends on the actual code itself.
For example, the following SQL Server T-SQL procedure uses the sample schema presented above
to create various business intelligence reports to the staff of the company using the database:
SET QUOTED_IDENTIFIER OFF
go
SET ANSI_NULLS OFF
go
CREATE PROCEDURE CORPORATE_ANALYSIS
@START_DATE DATETIME,
@END_DATE
DATETIME
AS
BEGIN
--- display brokers ordered by highest commissions for time period
-SELECT A.BROKER_ID,
A.BROKER_FIRST_NAME,
A.BROKER_LAST_NAME,
SUM(BROKER_COMMISSION) TOTAL_COMMISSIONS
FROM
BROKER A,
CLIENT_TRANSACTION B
WHERE
B.TRANSACTION_COMP_TIMESTAMP BETWEEN @START_DATE AND @END_DATE AND
A.BROKER_ID = B.BROKER_ID
GROUP BY A.BROKER_ID,
A.BROKER_FIRST_NAME,
A.BROKER_LAST_NAME
ORDER BY 4 DESC
--- display offices ordered by highest commissions for time period
Copyright © 2007, MySQL AB
Seite 46 von 49
-SELECT
C.OFFICE_NAME,
SUM(BROKER_COMMISSION) TOTAL_COMMISSIONS
FROM
BROKER A,
CLIENT_TRANSACTION B,
OFFICE_LOCATION C
WHERE
B.TRANSACTION_COMP_TIMESTAMP BETWEEN @START_DATE AND @END_DATE AND
A.BROKER_ID = B.BROKER_ID AND
A.OFFICE_LOCATION_ID = C.OFFICE_LOCATION_ID
GROUP BY C.OFFICE_NAME
ORDER BY 2 DESC
--- display top 20 invests ordered by highest invested dollars for time
period
-SELECT
TOP 20
B.INVESTMENT_VENDOR,
B.INVESTMENT_NAME,
SUM(PRICE) * SUM(NUMBER_OF_UNITS) TOTAL_INVESTED_DOLLARS
FROM
CLIENT_TRANSACTION A,
INVESTMENT B
WHERE
A.TRANSACTION_COMP_TIMESTAMP BETWEEN @START_DATE AND @END_DATE AND
B.INVESTMENT_ID = A.INVESTMENT_ID AND
A.ACTION = 'BUY'
GROUP BY B.INVESTMENT_VENDOR,
B.INVESTMENT_NAME
ORDER BY 3 DESC
--- display top invest types ordered by highest invested $$ for time period
-SELECT
C.INVESTMENT_TYPE_NAME,
SUM(PRICE) * SUM(NUMBER_OF_UNITS) TOTAL_INVESTED_DOLLARS
FROM
CLIENT_TRANSACTION A,
INVESTMENT B,
INVESTMENT_TYPE C
WHERE
A.TRANSACTION_COMP_TIMESTAMP BETWEEN @START_DATE AND @END_DATE AND
B.INVESTMENT_ID = A.INVESTMENT_ID AND
C.INVESTMENT_TYPE_ID = B.INVESTMENT_TYPE_ID AND
A.ACTION = 'BUY'
GROUP BY C.INVESTMENT_TYPE_NAME
ORDER BY 2 DESC
--- display top 20 clients ordered by highest invested dollars for time
period
-SELECT
TOP 20
B.CLIENT_FIRST_NAME,
B.CLIENT_LAST_NAME,
SUM(PRICE) * SUM(NUMBER_OF_UNITS) TOTAL_INVESTED_DOLLARS
FROM
CLIENT_TRANSACTION A,
CLIENT B
WHERE
A.TRANSACTION_COMP_TIMESTAMP BETWEEN @START_DATE AND @END_DATE AND
B.CLIENT_ID = A.CLIENT_ID AND
A.ACTION = 'BUY'
GROUP BY B.CLIENT_FIRST_NAME,
B.CLIENT_LAST_NAME
ORDER BY 3 DESC
END
go
IF OBJECT_ID('CORPORATE_ANALYSIS') IS NOT NULL
PRINT '<<< CREATED PROCEDURE CORPORATE_ANALYSIS >>>'
ELSE
PRINT '<<< FAILED CREATING PROCEDURE CORPORATE_ANALYSIS >>>'
go
SET ANSI_NULLS OFF
Copyright © 2007, MySQL AB
Seite 47 von 49
go
SET QUOTED_IDENTIFIER OFF
go
The SQL Server T-SQL procedure can be translated to MySQL as follows:
CREATE PROCEDURE CORPORATE_ANALYSIS
(IN START_DATE DATETIME,
IN END_DATE
DATETIME)
BEGIN
/*
display brokers ordered by highest commissions for time period
*/
SELECT A.BROKER_ID,
A.BROKER_FIRST_NAME,
A.BROKER_LAST_NAME,
SUM(BROKER_COMMISSION) TOTAL_COMMISSIONS
FROM
BROKER A,
CLIENT_TRANSACTION B
WHERE
B.TRANSACTION_COMP_TIMESTAMP BETWEEN START_DATE AND END_DATE AND
A.BROKER_ID = B.BROKER_ID
GROUP BY A.BROKER_ID,
A.BROKER_FIRST_NAME,
A.BROKER_LAST_NAME
ORDER BY 4;
/*
-- display offices ordered by highest commissions for time period
*/
SELECT C.OFFICE_NAME,
SUM(BROKER_COMMISSION) TOTAL_COMMISSIONS
FROM
BROKER A,
CLIENT_TRANSACTION B,
OFFICE_LOCATION C
WHERE
B.TRANSACTION_COMP_TIMESTAMP BETWEEN START_DATE AND END_DATE AND
A.BROKER_ID = B.BROKER_ID AND
A.OFFICE_LOCATION_ID = C.OFFICE_LOCATION_ID
GROUP BY C.OFFICE_NAME
ORDER BY 2 DESC;
/*
-- display top 20 invests ordered by highest invested dollars for time
period
*/
SELECT
FROM
WHERE
GROUP
ORDER
LIMIT
B.INVESTMENT_VENDOR,
B.INVESTMENT_NAME,
SUM(PRICE) * SUM(NUMBER_OF_UNITS) TOTAL_INVESTED_DOLLARS
CLIENT_TRANSACTION A,
INVESTMENT B
A.TRANSACTION_COMP_TIMESTAMP BETWEEN START_DATE AND END_DATE AND
B.INVESTMENT_ID = A.INVESTMENT_ID AND
A.ACTION = 'BUY'
BY B.INVESTMENT_VENDOR,
B.INVESTMENT_NAME
BY 3 DESC
20;
/*
-- display top types ordered by highest invested dollars for time period
*/
SELECT
FROM
WHERE
Copyright © 2007, MySQL AB
C.INVESTMENT_TYPE_NAME,
SUM(PRICE) * SUM(NUMBER_OF_UNITS) TOTAL_INVESTED_DOLLARS
CLIENT_TRANSACTION A,
INVESTMENT B,
INVESTMENT_TYPE C
A.TRANSACTION_COMP_TIMESTAMP BETWEEN START_DATE AND END_DATE AND
Seite 48 von 49
B.INVESTMENT_ID = A.INVESTMENT_ID AND
C.INVESTMENT_TYPE_ID = B.INVESTMENT_TYPE_ID AND
A.ACTION = 'BUY'
GROUP BY C.INVESTMENT_TYPE_NAME
ORDER BY 2 DESC;
/*
-- display top 20 clients ordered by highest invested dollars for time
period
*/
SELECT
FROM
WHERE
GROUP
ORDER
LIMIT
B.CLIENT_FIRST_NAME,
B.CLIENT_LAST_NAME,
SUM(PRICE) * SUM(NUMBER_OF_UNITS) TOTAL_INVESTED_DOLLARS
CLIENT_TRANSACTION A,
CLIENT B
A.TRANSACTION_COMP_TIMESTAMP BETWEEN START_DATE AND END_DATE AND
B.CLIENT_ID = A.CLIENT_ID AND
A.ACTION = 'BUY'
BY B.CLIENT_FIRST_NAME,
B.CLIENT_LAST_NAME
BY 3 DESC
20;
END;
Copyright © 2007, MySQL AB
Seite 49 von 49