MySQL lernen - Anfangen, anwenden, verstehen <Probekapitel 5

Werbung
5
Zugriffsm&ouml;glichkeiten
el r
n
e
n
Man kann auf vielerlei Wegen auf die Daten eines MySQL-Servers zugreifen. Bisher haben wir immer das Client-Programm mysql genutzt.
Nat&uuml;rlich ist das aber kein sinnvoller Weg f&uuml;r Endbenutzer. F&uuml;r diese
Gruppe schreibt man im Allgemeinen ein eigenes Programm, welches
&uuml;ber eine der angebotenen Schnittstellen mit dem MySQL-Server kommuniziert.
Zudem gibt es einige Programme, die einen Administrator bei seiner Arbeit mit dem MySQL-Server unterst&uuml;tzen, sei es grafisch oder textuell
ausgerichtet. Um die Daten „am St&uuml;ck“ aus dem Server heraus- und in
einen anderen wieder hineinzubekommen, kann man auch verschiedene Wege beschreiten.
5.1
Was Sie in diesem Kapitel lernen
Zun&auml;chst wollen wir uns mit den verschiedenen Tools auseinandersetzen, die Zugriff auf den MySQL-Server bzw. die von ihm verwalteten Daten gew&auml;hren. Das wichtigste ist dabei nat&uuml;rlich mysql, es gibt aber noch
einige weitere, die eher der Administration dienen.
Danach werden wir phpMyAdmin vorstellen, ein von Dritten programmiertes Tool, das dem Benutzer eine grafische Oberfl&auml;che pr&auml;sentieren
kann, welche den Dialog mit dem Server h&uuml;bscher verpackt als dies
Textprogramme erm&ouml;glichen (welche daf&uuml;r nat&uuml;rlich andere Vorteile
haben). Zudem l&auml;uft es unter einer Web-Oberfl&auml;che und kann somit mit
jedem Browser bedient werden.
Zum Dritten wollen wir uns mit dem Im- und Export von Daten k&uuml;mmern. Damit kann man Datenbanken von einem zum anderen Rechner
verschieben, aber auch Daten aus anderen Quellen in MySQL importieren.
:DV 6LH LQ GLHVHP .DSLWHO OHUQHQ Schlie&szlig;lich befassen wir uns mit den Programmierschnittstellen von
MySQL. Man kann aus den verschiedensten Programmiersprachen heraus auf den Server zugreifen, aber auch sprachunabh&auml;ngige Schnittstellen wie ODBC nutzen.
5.2
Admin-Tools zu MySQL
Mit MySQL werden schon viele Tools direkt mitgeliefert. Diese sollen
dem Administrator die Arbeit mit dem MySQL-Server erleichtern. Das
am h&auml;ufigsten verwendete d&uuml;rfte nat&uuml;rlich mysql sein. Wir haben die
ganze Zeit damit gearbeitet und werden hier noch ein paar erg&auml;nzende
M&ouml;glichkeiten erw&auml;hnen.
Weiterhin stehen f&uuml;r den Zugriff auf den MySQL-Server weitere Tools
bereit. Im Folgenden werden wir mysqladmin und mysqlshow besprechen.
Die Tools mysqldump und mysqlimport werden wir detaillierter in Kapitel
5.4 behandeln, da sie zum Im- und Exportieren von Daten genutzt werden. mysqlhotcopy dient zum Sichern von Daten und wird im n&auml;chsten
Kapitel besprochen, ebenso wie myisamchk und mysqlcheck, welche zum
Pr&uuml;fen und Reparieren von Tabellen und Datenbanken dienen.
5.2.1 mysql
mysql ist das Tool, mit dem man vermutlich au&szlig;erhalb des eigentlichen
Programms f&uuml;r die Endbenutzer am h&auml;ufigsten arbeiten wird. Wir haben schon sehr viel damit gemacht und werden hier nur noch auf einige
weitere Punkte eingehen, die das Leben einfacher machen k&ouml;nnen.
TEE / NOTEE
TEE
Mit dem Befehl TEE kann man daf&uuml;r sorgen, dass die Ausgabe neben dem
Bildschirm gleichzeitig auch in eine Datei geschrieben wird. Als Parameter gibt man den Pfad und Namen einer Datei an. Diese Datei wird als
Ziel genommen, um die Ein- und Ausgaben, die man auch auf dem Bildschirm sieht, abzuspeichern. Dabei wird immer an das Ende der Datei
angeh&auml;ngt, so dass auch nach einem Neustart die alten Daten nicht verloren sind. Mit NOTEE beendet man das Protokollieren. Ein Beispiel f&uuml;r
eine solche Log-Datei w&auml;re:
Logging to file 'd:/temp/test.txt'
mysql&gt; SELECT * FROM raum;
=XJULIIVP|JOLFKNHLWHQ
+---------+-----------+-------+----------+
| raum_id | raum_name | etage | personen |
+---------+-----------+-------+----------+
|
1 | A5.33
| 5
|
4 |
|
2 | B2.02
| 2
|
20 |
|
3 | C4.16
| 4
|
11 |
|
4 | A5.21
| 5
|
6 |
|
5 | A5.23
| 5
|
6 |
+---------+-----------+-------+----------+
5 rows in set (0.00 sec)
mysql&gt; UPDATE schueler SET nachname = 'Meier' WHERE schueler_id = 11;
Query OK, 0 rows affected (0.02 sec)
Rows matched: 0 Changed: 0 Warnings: 0
mysql&gt; NOTEE
Direkt vor dem „Logging to file…“ wurde der Befehl TEE d:/temp/test.txt
aufgerufen (&uuml;brigens wieder ohne Semikolon). Ruft man nach einem
NOTEE den Befehl TEE erneut auf, ohne aber einen Dateinamen angegeben
zu haben, wird in die letzte Datei protokolliert, die verwendet wurde.
STATUS
Mit diesem Befehl kann man sich Statusinformationen &uuml;ber den Server,
den Client und die Verbindung anzeigen lassen. Auch er wird ohne Semikolon aufgerufen:
STATUS
mysql&gt; STATUS
-------------D:\mysql\bin\mysql.exe Ver 11.18 Distrib 3.23.51, for Win95/Win98 (i32)
Connection id:
Current database:
Current user:
Server version:
Protocol version:
Connection:
Client characterset:
Server characterset:
TCP port:
Uptime:
1
musikschule
ODBC@localhost
3.23.51-nt
10
localhost via TCP/IP
german1
german1
3306
12 hours 37 min 35 sec
Threads: 1 Questions: 66 Slow queries: 0 Opens: 24 Flush tables: 1 Open
tables: 2 Queries per second avg: 0.001
--------------
Zun&auml;chst folgt eine Angabe des aktuellen Programms mit seinem Stand
und der Distribution.
Die Connection id gibt dann die Kennung an, &uuml;ber die das Client-Programm aktuell mit dem Server verbunden ist. Sie kann genutzt werden,
um unter anderem mit mysqladmin Clients „abzuschie&szlig;en“, die sich
aufgeh&auml;ngt haben oder anderen &Auml;rger bereiten.
Die Current database gibt nat&uuml;rlich an, welche Datenbank gerade ausgew&auml;hlt ist, und der Current user zeigt, wer man gerade ist.
Server version und Protocol version geben Informationen &uuml;ber den Stand
des Servers und die Protokollversion. Connection sagt, wie man mit dem
Server verbunden ist, Client characterset und Server characterset informieren &uuml;ber den genutzten Zeichensatz, der TCP port steht f&uuml;r den Port,
&uuml;ber den der MySQL-Server kommuniziert und die Uptime steht f&uuml;r die
Laufzeit, die der Server schon ohne Unterbrechung l&auml;uft. Am Ende finden sich noch ein paar Informationen zur Statistik.
Umleiten der Ein- und Ausgabe
Redirection
Hat man mehrere Befehle in einer festen Reihenfolge zu verarbeiten,
kann man diese in einer Textdatei speichern (gerne mit der Endung .sql)
und entweder in mysql mit dem Befehl SOURCE ausf&uuml;hren lassen (wie
schon weiter oben behandelt), oder direkt beim Aufruf per Umleitung
der Eingabe mitgeben. Speichern wir zum Beispiel die folgenden Befehle
in einer Datei namens mycommand.sql:
SHOW DATABASES;
USE musikschule;
SELECT * FROM raum;
SELECT * FROM instrument;
Wenn man nun mysql diese Datei als Eingabe mitgibt, erh&auml;lt man folgende Ausgabe:
prompt&gt;mysql &lt; mycommands.sql
Database
musikschule
mysql
test
raum_id raum_name
etage
1
A5.33 5
4
2
B2.02 2
20
3
C4.16 4
11
4
A5.21 5
6
5
A5.23 5
6
=XJULIIVP|JOLFKNHLWHQ
personen
instrument_id instr_name
instr_gruppe
1
Querfl&ouml;te
Holzbl&auml;ser
2
Klarinette
Holzbl&auml;ser
3
Violine Streicher
4
Viola Streicher
5
Posaune Blechbl&auml;ser
6
Trompete
Blechbl&auml;ser
7
Klavier Tasten
8
Keyboard
Tasten
Wie man sieht, werden keine weiteren Informationen neben den Daten
selber und den Spalten&uuml;berschriften mitgegeben. Getrennt werden die
Daten mit dem Tabulatorzeichen. Dieses Ausgabeformat wird dann verwendet, wenn MySQL im sogenannten Batch-Modus l&auml;uft. Das Verhalten l&auml;sst sich auch erzwingen oder verhindern, dazu ben&ouml;tigt man die
im n&auml;chsten Abschnitt beschriebenen Kommandozeilen-Parameter.
Die Ausgabe l&auml;sst sich nat&uuml;rlich auch direkt in eine Datei umleiten. Das
erreicht man mit folgendem Aufruf:
prompt&gt;mysql &lt; mycommands.sql &gt; myresult.txt
Kommandozeilen-Parameter
Es gibt (neben -h, -u und -p) einige Parameter, die man beim Starten von
mysql angeben kann und die in manchen Situationen helfen k&ouml;nnen.
F&uuml;nf m&ouml;chte ich hier auff&uuml;hren, es gibt aber noch diverse mehr.
• -? oder --help
Dieser Parameter d&uuml;rfte der wichtigste sein… Er gibt die m&ouml;glichen
Kommandozeilen-Parameter aus und beendet das Programm dann
wieder. Das Ergebnis sehen Sie hier:
prompt&gt;mysql -?
mysql Ver 11.18 Distrib 3.23.51, for Win95/Win98 (i32)
Copyright (C) 2000 MySQL AB &amp; MySQL Finland AB &amp; TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license
Usage: mysql [OPTIONS] [database]
-?, --help
Display this help and exit.
-A, --no-auto-rehash No automatic rehashing. One has to use 'rehash'
to get table and field completion. This gives a
quicker start of mysql and disables rehashing on
reconnect.
-B, --batch
Print results with a tab as separator, each row
on a new line. Doesn't use history file.
--character-sets-dir=...
Directory where character sets are located.
-C, --compress
Use compression in server/client protocol.
-D, --database=..
Database to use.
--default-character-set=...
Set the default character set.
-e, --execute=...
Execute command and quit. (Output like with
--batch)
-E, --vertical
Print the output of a query (rows) vertically.
-f, --force
Continue even if we get an sql error.
-g, --no-named-commands
Named commands are disabled. Use \* form only,
or use named commands only in the beginning of a
line ending with a semicolon (;) Since version
10.9 the client now starts with this option
ENABLED by default! Disable with '-G'. Long
format commands still work from the first line.
-G, --enable-named-commands
Named commands are enabled. Opposite to -g.
-i, --ignore-spaces Ignore spaces after function names.
-h, --host=...
Connect to host.
-H, --html
Produce HTML output.
--local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE
-L, --skip-line-numbers
Don't write line number for errors.
--no-tee
Disable outfile. See interactive help (\h) also.
-n, --unbuffered
Flush buffer after each query.
-N, --skip-column-names
Don't write column names in results.
-O, --set-variable var=option
Give a variable an value. --help lists
variables.
-o, --one-database
Only update the default database. This is useful
for skipping updates to other database in the
update log.
-p[password], --password[=...]
Password to use when connecting to server
If password is not given it's asked from the
tty.
-W, --pipe
Use named pipes to connect to server
-P, --port=...
-q, --quick
-r, --raw
Port number to use for connection.
Don't cache result, print it row by row. This
may slow down the server if the output is
suspended. Doesn't use history file.
Write fields without conversion. Used with
--batch
=XJULIIVP|JOLFKNHLWHQ
-s, --silent
-S --socket=...
-t, --table
-T, --debug-info
--tee=...
-u,
-U,
-v,
-V,
-w,
Be more silent.
Socket file to use for connection.
Output in table format.
Print some debug info at exit.
Append everything into outfile. See interactive
help (\h) also. Does not work in batch mode.
--user=#
User for login if not current user.
--safe-updates[=#], --i-am-a-dummy[=#]
Only allow UPDATE and DELETE that uses keys.
--verbose
Write more. (-v -v -v gives the table output
format)
--version
Output version information and exit.
--wait
Wait and retry if connection is down.
Default options are read from the following files in the given order:
D:\WINNT\my.ini C:\my.cnf
The following groups are read: mysql client
The following options may be given as the first argument:
--print-defaults
Print the program argument list and exit
--no-defaults
Don't read default options from any options file
--defaults-file=#
Only read default options from the given file #
--defaults-extra-file=# Read this file after the global files are read
Possible variables for option
connect_timeout
current
max_allowed_packet
current
net_buffer_length
current
select_limit
current
max_join_size
current
--set-variable (-O) are:
value: 0
value: 16777216
value: 16384
value: 1000
value: 1000000
• -e oder --execute
Mit diesem Parameter kann man einzelne Befehle ausf&uuml;hren lassen.
Das Programm wird dann direkt danach beendet. Der Befehl muss in
Anf&uuml;hrungszeichen stehen. Damit kann man sich einzelne Tabelleninhalte oder andere Informationen ausgeben lassen, ohne erst aufw&auml;ndiger eine Befehlsdatei zu erstellen. Ein Beispiel daf&uuml;r ist:
prompt&gt;mysql -e &quot;SELECT * FROM raum;&quot; musikschule
+---------+-----------+-------+----------+
| raum_id | raum_name | etage | personen |
+---------+-----------+-------+----------+
|
1 | A5.33
| 5
|
4 |
|
2 | B2.02
| 2
|
20 |
|
3 | C4.16
| 4
|
11 |
|
4 | A5.21
| 5
|
6 |
|
5 | A5.23
| 5
|
6 |
+---------+-----------+-------+----------+
Nutzt man die lange Version des Parameters, sieht das Ganze so aus:
prompt&gt;mysql --execute=&quot;SHOW TABLES;&quot; musikschule
+-----------------------+
| Tables_in_musikschule |
+-----------------------+
| ausleihe
|
| fulltexttest
|
| instrument
|
| lehrer
|
| leihinstrument
|
| orchester
|
| orchester_tn
|
| raum
|
| schueler
|
| unterricht
|
| unterricht_tn
|
| warteliste
|
+-----------------------+
• -B oder --batch
Mit dieser Option kann man daf&uuml;r sorgen, dass die Ausgabe wie bei
umgeleiteter Eingabe geschieht: nur mit Tabulatoren getrennte Werte und keine Rahmen um die Tabellen herum. Das kann n&uuml;tzlich
sein, wenn man mysql mit dem Parameter -e aufruft (was ansonsten
zu einer „normalen“ Anzeige f&uuml;hrt):
prompt&gt;mysql -B -e &quot;SELECT * FROM instrument;&quot; musikschule
instrument_id instr_name
instr_gruppe
1
Querfl&ouml;te
Holzbl&auml;ser
2
Klarinette
Holzbl&auml;ser
3
Violine Streicher
4
Viola Streicher
5
Posaune Blechbl&auml;ser
6
Trompete
Blechbl&auml;ser
7
Klavier Tasten
8
Keyboard
Tasten
Nat&uuml;rlich kann man mysql mit diesem Parameter auch im interaktiven Modus starten, nur hat man dann keinerlei Anzeige und Strukturierung neben den eigentlichen Daten. Im folgenden Beispiel sind
zur Verdeutlichung die eingegebenen Zeichen kursiv gedruckt:
=XJULIIVP|JOLFKNHLWHQ
prompt&gt;mysql -B musikschule
SELECT * FROM raum;
raum_id raum_name
etage personen
1
A5.33 5
4
2
B2.02 2
20
3
C4.16 4
11
4
A5.21 5
6
5
A5.23 5
6
SHOW FIELDS FROM raum;
Field Type
Null
Key
Default Extra
raum_id smallint(5) unsigned
PRI
raum_name
varchar(10)
etage char(3) YES
MUL
NULL
personen
mediumint(8) unsigned YES
EXIT
NULL
auto_increment
1
prompt&gt;
Wie man sieht, ist dies in den meisten F&auml;llen nicht wirklich sinnvoll.
Das Gegenst&uuml;ck dazu ist der Parameter -t.
• -H oder --html
Diese Option sorgt daf&uuml;r, dass die Daten anstatt mit |, + und - als
HTML-Tabellen formatiert ausgegeben werden. Es wird eine Tabelle
mit einer Rahmenst&auml;rke von 1 erzeugt, die Spaltennamen sind als
&lt;TH&gt;...&lt;/TH&gt; formatiert, die Werte selber mit &lt;TD&gt;...&lt;/TD&gt; umschlossen. Diese Option kann man dann verwenden, wenn man die Tabelleninhalte schnell und einfach in einer HTML-Datei ausgeben
m&ouml;chte. Allerdings ist zu beachten, dass Umlaute und andere Sonderzeichen nicht gesondert behandelt werden. M&ouml;chte man also auf
Nummer sicher gehen, sollte man in der HTML-Datei, die drumherum noch entstehen muss, den entsprechenden Zeichensatz angeben.
Ein Beispiel f&uuml;r die Ausgabe zusammen mit -e w&auml;re das folgende:
D:\TEMP&gt;mysql -H -e &quot;SELECT * FROM instrument;&quot; musikschule
&lt;TABLE BORDER=1&gt;&lt;TR&gt;&lt;TH&gt;instrument_id&lt;/TH&gt;&lt;TH&gt;instr_name&lt;/
TH&gt;&lt;TH&gt;instr_gruppe&lt;/TH&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;Querfl&ouml;te&lt;/
TD&gt;&lt;TD&gt;Holzbl&auml;ser&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;2&lt;/TD&gt;&lt;TD&gt;Klarinette&lt;/
TD&gt;&lt;TD&gt;Holzbl&auml;ser&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;Violine&lt;/TD&gt;&lt;TD&gt;Streicher&lt;/
TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;4&lt;/TD&gt;&lt;TD&gt;Viola&lt;/TD&gt;&lt;TD&gt;Streicher&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;5&lt;/
TD&gt;&lt;TD&gt;Posaune&lt;/TD&gt;&lt;TD&gt;Blechbl&auml;ser&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;6&lt;/TD&gt;&lt;TD&gt;Trompete&lt;/
TD&gt;&lt;TD&gt;Blechbl&auml;ser&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;7&lt;/TD&gt;&lt;TD&gt;Klavier&lt;/TD&gt;&lt;TD&gt;Tasten&lt;/
TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;8&lt;/TD&gt;&lt;TD&gt;Keyboard&lt;/TD&gt;&lt;TD&gt;Tasten&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
Sehr gut lesbar, oder? Aber f&uuml;r eine Web-Seite genau das Richtige
(vielleicht abgesehen von den fehlenden Zeilenumbr&uuml;chen, die aber
auch nur den Quelltext lesbarer machen). Ein etwas komplexeres Bei-
spiel w&auml;re das folgende, wobei wir die folgende SQL-Anfrage in einer
Datei namens unterricht.sql speichern:
SELECT CONCAT(LEFT(vorname, 1), '. ', nachname) AS Lehrer,
instr_name AS &quot;Instr.&quot;, raum_name AS Raum,
CASE wochentag WHEN 0 THEN 'Mo' WHEN 1 THEN 'Di'
WHEN 2 THEN 'Mi' WHEN 3 THEN 'Do' WHEN 4 THEN 'Fr'
WHEN 5 THEN 'Sa' WHEN 6 THEN 'So' END AS Tag,
CONCAT(TIME_FORMAT(uhrzeit_von, '%H:%i'), '-',
TIME_FORMAT(uhrzeit_bis, '%H:%i')) AS Zeit,
kosten AS Preis, IF(einzel, 'X', ' ') AS Einzel
FROM unterricht AS u, lehrer AS l, instrument AS i, raum AS r
WHERE u.lehrer_id = l.lehrer_id
AND u.instrument_id = i.instrument_id
AND u.raum_id = r.raum_id;
Sie finden die Datei unterricht.sql auch auf der beiliegenden CD-ROM
im Verzeichnis Beispiel.
Mit diesem Aufruf erzeugt man nun eine HTML-Tabelle in unterricht_
tab.html:
prompt&gt;mysql -H musikschule &lt; unterricht.sql &gt; unterricht_tab.html
Diese Datei kann man nun als Grundlage f&uuml;r eine vollst&auml;ndige
HTML-Datei nutzen. Klemmt man noch die notwendigsten Codes
drumherum (&lt;HTML&gt;&lt;BODY&gt; am Anfang und &lt;/BODY&gt;&lt;/HTML&gt; am Ende), erh&auml;lt man eine Ausgabe wie in Abbildung 5.1.
Abbildung 5.1: Ausgabe einer Tabelle im HTML-Format
Die erg&auml;nzte Ergebnisdatei unterricht_tab.html ist ebenfalls auf der CDROM im Verzeichnis Beispiel zu finden.
=XJULIIVP|JOLFKNHLWHQ
Diese Ausgabe kann man also als Grundlage f&uuml;r die Anzeige von Daten
auf Web-Seiten nutzen, allerdings sind andere Wege (zum Beispiel
&uuml;ber PHP, siehe weiter unten) deutlich flexibler. Man kann &uuml;brigens
auch diesen Parameter im interaktiven Modus nutzen, allerdings sind
die Ausgaben dann nicht sehr leserlich (wie man oben gesehen hat)…
• -N oder --skip-column-names
Mit -N kann man die Ausgabe der Spaltennamen unterdr&uuml;cken. Dies
kann dann n&uuml;tzlich sein, wenn man die Daten in Dateien speichern
m&ouml;chte und die Spaltennamen dabei eher hinderlich sind (man sollte dann ja sowieso wissen, wie die Spaltenanordnung ist). Ein Beispiel daf&uuml;r ist:
prompt&gt;mysql -N
1
A5.33
2
B2.02
3
C4.16
4
A5.21
5
A5.23
-B -e &quot;SELECT * FROM raum;&quot; musikschule
5
4
2
20
4
11
5
6
5
6
• -t oder --table
Mit dieser Option kann man sich auch dann die Daten in der &uuml;blichen Tabellenform (mit Rahmen) ausgeben lassen, wenn man sich
eigentlich im Batch-Modus befindet (zum Beispiel bei Verwendung
der Ein- und Ausgabeumleitung):
prompt&gt;mysql musikschule &lt; unterricht.sql
Lehrer Instr. Raum
Tag
Zeit
Preis Einzel
G. Mosler
Posaune A5.23 Mi
19:15-20:00
25.00
H. Knarer
Querfl&ouml;te
C4.16 Fr
17:00-17:45
K. Hansen
Violine B2.02 Do
15:35-16:20
20.00
K. Hansen
Viola B2.02 Do
16:30-17:15
20.00
P. Ottbein
Klavier A5.33 Sa
10:00-11:00
35.00
30.00
X
X
prompt&gt;mysql -t musikschule &lt; unterricht.sql
+------------+-----------+-------+------+-------------+-------+--------+
| Lehrer
| Instr.
| Raum | Tag | Zeit
| Preis | Einzel |
+------------+-----------+-------+------+-------------+-------+--------+
| G. Mosler | Posaune | A5.23 | Mi | 19:15-20:00 | 25.00 |
|
| H. Knarer | Querfl&ouml;te | C4.16 | Fr | 17:00-17:45 | 30.00 | X
|
| K. Hansen | Violine | B2.02 | Do | 15:35-16:20 | 20.00 |
|
| K. Hansen | Viola
| B2.02 | Do | 16:30-17:15 | 20.00 |
|
| P. Ottbein | Klavier | A5.33 | Sa | 10:00-11:00 | 35.00 | X
|
+------------+-----------+-------+------+-------------+-------+--------+
5.2.2 mysqladmin
mysqladmin
Mit mysqladmin kann man viele Verwaltungsaufgaben einfacher erledigen als mit mysql. Dabei nutzt man die folgende Syntax:
mysqladmin [options] command command ...
Die m&ouml;glichen Optionen &auml;hneln denen von mysql, in Tabelle 5.1 gibt es
zu jeder eine kurze Beschreibung.
Kurze Version
Lange Version
Beschreibung
-#
--debug=...
Ausgabe von Debug-Informationen
-f
--force
Beim L&ouml;schen von Datenbanken nicht nachfragen. Werden mehrere Befehle angegeben,
werden die folgenden auch bei einem Fehler
des aktuellen Befehls abgearbeitet.
-?
--help
Ausgabe der Hilfe
--charactersets-dir=...
Angabe des Verzeichnisses mit den Zeichensatzinformationen
-C
--compress
Komprimierung bei der Kommunikation zwischen Client und Server nutzen
-h
--host=...
Angabe des Hosts
-p
--password[=...]
Angabe des Kennworts oder Nachfragen, falls
nicht angegeben
-W
--pipe
Verwendung von Named Pipes bei der Verbindung zum Server
-P
--port=...
Angabe des Ports f&uuml;r die Verbindung
-i
--sleep=...
wiederholtes Ausf&uuml;hren der Befehle mit einer
Pause der angegebenen Zeit (in Sekunden)
-r
--relative
zeigt bei Nutzung von -i nur den Unterschied zur vorigen Ausf&uuml;hrung (funktioniert
nur mit extended-status, siehe unten).
-E
--vertical
Ausgabe wie bei -r, allerdings in vertikaler
Richtung
-s
--silent
Keine Fehlermeldung, wenn es Verbindungsprobleme zum Server gibt.
-S
--socket=...
Angabe der Socket-Datei f&uuml;r die Verbindung
-u
--user=...
Angabe des Benutzers, mit dem sich das
Programm anmelden soll
-v
--verbose
Ausgabe von mehr Informationen
-V
--version
Nur Ausgabe der Versionsnummer und
Beenden des Programms.
-w
--wait=...
Falls die Verbindung nicht m&ouml;glich ist, die
angegebene Anzahl an Versuchen wiederholen, anstatt direkt abzubrechen.
Tabelle 5.1: Optionen f&uuml;r mysqladmin
=XJULIIVP|JOLFKNHLWHQ
Bei den Befehlen gibt es insgesamt 21 M&ouml;glichkeiten. Allen ist gemein,
dass man sie soweit abk&uuml;rzen kann, wie sie noch eindeutig sind. create
db_name zum Beispiel kann man mit c db_name abk&uuml;rzen, status hingegen
muss mindestens stat hei&szlig;en.
• create db_name
Dieser Befehl legt eine Datenbank mit dem Namen db_name an. Er entspricht dem Befehl CREATE DATABASE db_name in mysql.
• drop db_name
Mit diesem Befehl wird eine Datenbank wieder gel&ouml;scht. Dabei gibt
es eine Kontrollabfrage (sofern man nicht die Option -f nutzt), da danach unwiderruflich auch alle Tabellen und Daten dieser Datenbank
gel&ouml;scht sind:
prompt&gt;mysqladmin create mytest
prompt&gt;mysqladmin drop mytest
Dropping the database is potentially a very bad thing to do.
Any data stored in the database will be destroyed.
Do you really want to drop the 'mytest' database [y/N] y
Database &quot;mytest&quot; dropped
• extended-status
Dieser Befehl gibt eine Status&uuml;bersicht aus, die man unter mysql mit
SHOW STATUS erhalten w&uuml;rde. Nutzt man den Parameter -r zusammen
mit -i werden beim ersten Mal die „normalen“ Werte ausgegeben,
danach aber nur noch die Differenzen zur Vorversion. Dies kann
man nutzen, wenn man nur die Ver&auml;nderungen der Werte beobachten m&ouml;chte. Der folgende Befehl gibt die Statusliste alle 60 Sekunden
aus, zeigt dabei aber (nach dem ersten Mal) nur die Differenzen an:
prompt&gt;mysqladmin -i 60 -r extended-status
• flush-hosts
leert den Host-Cache. Dies kann n&uuml;tzlich sein, wenn sich die IPAdresse eines Hosts ge&auml;ndert hat oder wenn ein Host geblockt ist.
Unter mysql kann man daf&uuml;r den Befehl FLUSH HOSTS nutzen.
• flush-logs
schlie&szlig;t alle Log-Dateien und &ouml;ffnet sie neu. Damit ist sichergestellt,
dass alle &Auml;nderungen auch auf Festplatte abgelegt sind. Dies entspricht dem Befehl FLUSH LOGS unter mysql.
• flush-tables
schlie&szlig;t alle offenen Tabellen und sorgt daf&uuml;r, dass alle Tabellen, die
gerade in Benutzung sind, m&ouml;glichst bald geschlossen werden. Dies
entspricht dem Befehl FLUSH TABLES unter mysql.
• flush-privileges
l&auml;dt die Berechtigungen erneut aus den entsprechenden Tabellen.
Dies entspricht dem Befehl FLUSH PRIVILEGES unter mysql.
• kill id, id, ...
Mit diesem Befehl kann man Threads im MySQL-Server beenden, die
einen Client bedienen. Die entsprechende ID wird beim Anmelden
mit mysql ausgegeben, kann aber auch mit SHOW PROCESSLIST ermittelt
werden. Ein Thread wird normalerweise nicht sofort beendet, sondern erh&auml;lt nur eine Markierung. Diese wird erst in bestimmten
Situationen ber&uuml;cksichtigt.
• password new_pwd
&auml;ndert das bestehende Kennwort ab und setzt es auf new_pwd.
• ping
pr&uuml;ft, ob der MySQL-Server erreichbar ist und reagiert:
prompt&gt;mysqladmin ping
mysqld is alive
• processlist
gibt die aktuelle Prozessliste aus. Dies kann auch mit SHOW PROCESSLIST
in mysql erreicht werden. Wie in Abbildung 5.2 zu sehen, erh&auml;lt man
neben den angemeldeten Benutzern auch die gerade verwendete Datenbank und eine Information &uuml;ber die aktuelle T&auml;tigkeit. Auch der
Aufruf von mysqladmin ist hier (indirekt) vermerkt, er wird auf ein
SHOW PROCESSLIST abgebildet.
Prompt&gt;mysqladmin processlist
+----+------+-----------+-------------+---------+------+-------+------------------+
| Id | User | Host
| db
| Command | Time | State | Info
|
+----+------+-----------+-------------+---------+------+-------+------------------+
| 8 | ODBC | localhost | musikschule | Sleep
| 1
|
|
|
| 10 | ODBC | localhost |
| Query
| 0
|
| show processlist |
+----+------+-----------+-------------+---------+------+-------+------------------+
Abbildung 5.2: Ausgabe von mysqladmin processlist
• reload
l&auml;dt die Berechtigungstabellen erneut. Dies ist identisch zu flushprivileges.
=XJULIIVP|JOLFKNHLWHQ
• refresh
schlie&szlig;t alle Tabellen und Log-Dateien und &ouml;ffnet diese erneut.
• shutdown
Dieser Befehl f&auml;hrt den Server herunter. Somit l&auml;sst sich der Server
auch „aus der Ferne“ beenden, ohne, dass man sich direkt auf dem
Rechner anmelden muss.
• status
Mit diesem Befehl kann man sich eine kurze Status-Information ausgeben lassen:
prompt&gt;mysqladmin status
Uptime: 35750 Threads: 2 Questions: 19 Slow queries: 0 Opens: 7 Flush
tables: 1 Open tables: 0 Queries per second avg: 0.001
• start-slave
startet einen Slave in einer verteilten Umgebung
• stop-slave
beendet einen Slave in einer verteilten Umgebung
• variables
Dieser Befehl gibt die aktuellen Variablen des MySQL-Servers aus und
entspricht einem SHOW VARIABLES unter mysql.
• version
Mit diesem Befehl kann man sich – anders als bei der Option -V –
nicht nur die Version von mysqladmin ausgeben lassen, sondern auch
die Versionsinfo des MySQL-Servers auslesen. Zudem werden auch
die Informationen angezeigt, die man mit status erh&auml;lt:
prompt&gt;mysqladmin version
mysqladmin Ver 8.23 Distrib 3.23.51, for Win95/Win98 on i32
Copyright (C) 2000 MySQL AB &amp; MySQL Finland AB &amp; TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license
Server version
Protocol version
Connection
TCP port
Uptime:
3.23.51-nt
10
localhost via TCP/IP
3306
9 hours 59 min 36 sec
Threads: 2 Questions: 26 Slow queries: 0 Opens: 7 Flush tables: 1 Open
tables: 0 Queries per second avg: 0.001
5.2.3 mysqlshow
mysqlshow
Das Programm mysqlshow dient als einfaches Interface zum Anzeigen
von Strukturdaten. Es lassen sich Datenbanken, Tabellen und Spalten
ausgeben. Alle Informationen erh&auml;lt man auch &uuml;ber den SHOW-Befehl in
mysql. Der Aufruf sieht wie folgt aus:
mysqlshow [OPTIONS] [database [table [column]]]
Als Optionen stehen die (zum Teil bekannten) Varianten aus Tabelle 5.2
zur Verf&uuml;gung.
Kurze Version
Lange Version
Beschreibung
-#
--debug=...
Ausgabe von Debug-Informationen
-?
--help
Ausgabe der Hilfe
-c
--charactersets-dir=...
Angabe des Verzeichnisses mit den Zeichensatzinformationen
-C
--compress
Komprimierung bei der Kommunikation
zwischen Client und Server nutzen
-h
--host=...
Angabe des Hosts
-i
–status
Ausgabe von zus&auml;tzlichen Tabelleninformationen
-k
--keys
Angabe der Schl&uuml;ssel f&uuml;r die Tabelle
-p
--password[=...]
Angabe des Kennworts oder Nachfragen, falls
nicht angegeben
-W
--pipe
Verwendung von Named Pipes bei der Verbindung zum Server
-P
--port=...
Angabe des Ports f&uuml;r die Verbindung
-S
--socket=...
Angabe der Socket-Datei f&uuml;r die Verbindung
-u
--user=...
Angabe des Benutzers, mit dem sich das
Programm anmelden soll
-v
--verbose
Ausgabe von mehr Informationen
-V
--version
nur Ausgabe der Versionsnummer und Beenden
des Programms
Tabelle 5.2: Optionen f&uuml;r mysqlshow
Wird keine Datenbank angegeben, werden alle verf&uuml;gbaren Datenbanken angezeigt:
prompt&gt;mysqlshow
+-------------+
| Databases |
+-------------+
| musikschule |
| mysql
|
| test
|
+-------------+
=XJULIIVP|JOLFKNHLWHQ
Mit Angabe einer Datenbank werden die dort enthaltenen Tabellen angegeben:
prompt&gt;mysqlshow musikschule
Database: musikschule
+----------------+
|
Tables
|
+----------------+
| ausleihe
|
| fulltexttest |
| instrument
|
| lehrer
|
| leihinstrument |
| orchester
|
| orchester_tn |
| raum
|
| schueler
|
| unterricht
|
| unterricht_tn |
| warteliste
|
+----------------+
Mit dem zus&auml;tzlichen Parameter -i erh&auml;lt man eine sehr umfangreiche
Ausgabe wie bei SHOW TABLE STATUS, siehe auch Abbildung 5.3.
prompt&gt;mysqlshow -i musikschule
Database: musikschule
+----------------+--------+------------+------+----------------+-------------+-----------------+--------------+-----------+| Type
| Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free |
| Name
+----------------+--------+------------+------+----------------+-------------+-----------------+--------------+-----------+|
| 0
| 1024
| 81604378623
| 0
| 0
| 0
| MyISAM | Fixed
| ausleihe
|
| 0
| 11264
| 4294967295
| 3632
| 16
| 227
| fulltexttest
| MyISAM | Dynamic
|
| 0
| 2048
| 4294967295
| 236
| 29
| 8
| MyISAM | Dynamic
| instrument
|
| 0
| 2048
| 4294967295
| 496
| 124
| 4
| MyISAM | Dynamic
| lehrer
|
| 0
| 2048
| 4294967295
| 136
| 34
| 4
| leihinstrument | MyISAM | Dynamic
|
| 0
| 1024
| 4294967295
| 0
| 0
| 0
| MyISAM | Dynamic
| orchester
|
| 0
| 1024
| 73014444031
| 0
| 0
| 0
| orchester_tn
| MyISAM | Fixed
|
| 0
| 3072
| 4294967295
| 100
| 5
| 20
| MyISAM | Dynamic
| raum
|
| 0
| 4096
| 4294967295
| 468
| 117
| 4
| MyISAM | Dynamic
| schueler
|
| 0
| 2048
| 133143986175
| 155
| 31
| 5
| MyISAM | Fixed
| unterricht
|
| 0
| 2048
| 55834574847
| 52
| 13
| 4
| unterricht_tn | MyISAM | Fixed
|
| 0
| 1024
| 68719476735
| 0
| 0
| 0
| MyISAM | Fixed
| warteliste
+----------------+--------+------------+------+----------------+-------------+-----------------+--------------+-----------+-
Fortsetzung
+----------------+---------------------+---------------------+---------------------+----------------+---------+
| Create_options | Comment |
| Check_time
| Update_time
| Auto_increment | Create_time
+----------------+---------------------+---------------------+---------------------+----------------+---------+
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 21:49:54 |
| 1
|
|
|
| 2002-10-03 14:53:01 | 2002-10-03 15:04:05 |
|
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 22:13:37 |
| 9
|
|
|
| 2002-09-19 21:49:54 | 2002-09-21 17:00:18 |
| 5
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 22:13:37 |
| 5
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 21:49:54 |
| 1
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 21:49:54 |
| 1
|
|
| 2002-09-24 21:38:22 | 2002-09-24 21:38:22 | 2002-09-24 21:38:22 |
| 6
|
|
| 2002-09-28 21:50:55 | 2002-09-28 21:50:55 | 2002-10-03 13:57:10 |
| 5
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 22:13:37 |
| 6
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 22:13:37 |
| 5
|
|
|
| 2002-09-19 21:49:54 | 2002-09-19 21:49:54 |
| 1
+----------------+---------------------+---------------------+---------------------+----------------+---------+
Abbildung 5.3: Ausgabe von mysqlshow -i musikschule
Gibt man Datenbank und Tabelle an, werden Informationen &uuml;ber die
Spalten der Tabelle ausgegeben (siehe Abbildung 5.4). Diese Ausgabe erreicht man auch mit SHOW FULL COLUMNS FROM ...
prompt&gt;mysqlshow musikschule raum
Database: musikschule Table: raum Rows: 5
+-----------+-----------------------+------+-----+---------+----------------+---------------------------------+
| Field
| Type
| Null | Key | Default | Extra
| Privileges
|
+-----------+-----------------------+------+-----+---------+----------------+---------------------------------+
| raum_id
| smallint(5) unsigned |
| PRI |
| auto_increment | select,insert,update,references |
| raum_name | varchar(10)
|
|
|
|
| select,insert,update,references |
| etage
| char(3)
| YES | MUL |
|
| select,insert,update,references |
| personen | mediumint(8) unsigned | YES |
| 1
|
| select,insert,update,references |
+-----------+-----------------------+------+-----+---------+----------------+---------------------------------+
Abbildung 5.4: Ausgabe von mysqlshow musikschule raum
Nutzt man zus&auml;tzlich den Parameter -k, werden auch noch Informationen &uuml;ber die Schl&uuml;ssel der Tabelle ausgegeben, wie in Abbildung 5.5 zu
sehen. Dies ist eine Kombination von SHOW FULL COLUMNS FROM ... mit SHOW
INDEX FROM ...
prompt&gt;mysqlshow -k musikschule raum
Database: musikschule Table: raum Rows: 5
+-----------+-----------------------+------+-----+---------+----------------+---------------------------------+
| Field
| Type
| Null | Key | Default | Extra
| Privileges
|
+-----------+-----------------------+------+-----+---------+----------------+---------------------------------+
| raum_id
| smallint(5) unsigned |
| PRI |
| auto_increment | select,insert,update,references |
| raum_name | varchar(10)
|
|
|
|
| select,insert,update,references |
| etage
| char(3)
| YES | MUL |
|
| select,insert,update,references |
| personen | mediumint(8) unsigned | YES |
| 1
|
| select,insert,update,references |
+-----------+-----------------------+------+-----+---------+----------------+---------------------------------+
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Comment |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+---------+
| raum | 0
| PRIMARY
| 1
| raum_id
| A
| 5
|
|
|
|
| raum | 1
| idx_etage | 1
| etage
| A
| 2
|
|
|
|
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+---------+
Abbildung 5.5: Ausgabe von mysqlshow -k musikschule raum
Gibt man auf einer der beschriebenen Ebenen einen Platzhalter an (wobei hier auch die Betriebssystem-Platzhalter * und ? zugelassen sind),
werden diese wie ein LIKE ... umgesetzt:
prompt&gt;mysqlshow musikschule u*
Database: musikschule Wildcard: u%
+---------------+
|
Tables
|
+---------------+
| unterricht
|
| unterricht_tn |
+---------------+
Dies kann allerdings zu Problemen f&uuml;hren, wenn man zum Beispiel die
Spalten der Tabelle unterricht_tn angezeigt bekommen m&ouml;chte:
prompt&gt;mysqlshow musikschule unterricht_tn
Database: musikschule Wildcard: unterricht_tn
+---------------+
|
Tables
|
+---------------+
| unterricht_tn |
+---------------+
=XJULIIVP|JOLFKNHLWHQ
Leider interpretiert mysqlshow die letzte Angabe als Angabe eines Filters
mit Platzhaltern (wegen des Unterstrichs) und gibt nur alle Tabellen aus,
die diesem Filter entsprechen. Umgehen kann man das Problem, indem
man in solch einem Fall als zus&auml;tzlichen Wert noch ein einzelnes Prozentzeichen anf&uuml;gt:
prompt&gt;mysqlshow musikschule unterricht_tn %
Database: musikschule Table: unterricht_tn Rows: 4 Wildcard: %
+------------------+------------------+------+-----+---------+-------...
| Field
| Type
| Null | Key | Default | Extra ...
+------------------+------------------+------+-----+---------+-------...
| unterricht_tn_id | int(10) unsigned |
| PRI |
|
| unterricht_id
| int(10) unsigned |
|
| 0
|
| schueler_id
| int(10) unsigned |
|
| 0
|
+------------------+------------------+------+-----+---------+-------...
Damit wird die Angabe der Tabelle nicht mehr als Filter interpretiert,
sondern nur die Angabe f&uuml;r die Spalten. Bei denen bewirkt das % aber nat&uuml;rlich, dass alle Spalten ausgegeben werden – also unser gew&uuml;nschtes
Ergebnis.
5.3
phpMyAdmin
phpMyAdmin ist kein direktes Programm. Es handelt sich vielmehr um
eine Sammlung von PHP-Seiten f&uuml;r einen Web-Server, mit denen sich
MySQL-Server (auch aus der Ferne) administrieren und die Daten anzeigen lassen. Er bietet unter einer &uuml;bersichtlichen Oberfl&auml;che viele Funktionen, die bei der Verwaltung von MySQL n&uuml;tzlich sind.
phpMyAdmin
Um phpMyAdmin nutzen zu k&ouml;nnen, ben&ouml;tigt man einen laufenden
Web-Server mit PHP-Unterst&uuml;tzung. Dabei kann es sich um den Apache
oder auch andere Server handeln. Der Server muss nicht mit dem
MySQL-Server identisch sein, solange er Zugriff auf ihn bietet. Zum Einrichten eines Apache-Servers mit PHP-Unterst&uuml;tzung sei auf das sp&auml;tere
Kapitel &uuml;ber LAMP/WAMP verwiesen.
Zur Installation l&auml;dt man sich am besten von http://www.phpmyadmin.net
die entsprechenden Dateien herunter.
Die Installationsdateien sind auch auf der beiliegenden CD-ROM enthalten. Im Unterverzeichnis phpMyAdmin finden Sie die Dateien
phpMyAdmin-2.3.3pl1-php.zip f&uuml;r Windows und phpMyAdmin-2.3.3pl1php.tar.gz.
SKS0\$GPLQ
Es reicht, die Daten auszupacken (wobei auf die Verzeichnisstruktur
R&uuml;cksicht genommen werden sollte) und an eine Stelle zu kopieren, auf
die der Web-Server zugreifen kann. Unter Apache kann man die Daten
zum Beispiel in das entsprechende Verzeichnis htdocs in ein Unterverzeichnis phpMyAdmin kopieren. In der dort vorhandenen Datei config.inc.php m&uuml;ssen nun noch einige wenige Eintragungen zum MySQLServer und den Anmeldeparametern vorgenommen werden.
• $cfg['Servers'][$i]['host'] = 'hostname';
Hier wird der Name oder die IP-Adresse des MySQL-Servers eingetragen.
• $cfg['Servers'][$i]['port'] = 'portnumber';
Falls sich der Port, unter dem der MySQL-Server l&auml;uft, von der Standardvorgabe 3306 unterscheidet, kann man hier die korrekte Portnummer angeben. Ansonsten kann man den Eintrag leer lassen.
• $cfg['Servers'][$i]['user'] = 'username';
Angabe des Benutzernamens, mit dem sich phpMyAdmin am MySQL-Server anmelden soll.
• $cfg['Servers'][$i]['password'] = 'password';
Angabe des Kennworts f&uuml;r den angegebenen Benutzer.
• $cfg['PmaAbsoluteUri'] = 'url_string';
Dies ist die absolute Angabe der URL f&uuml;r das phpMyAdmin-Verzeichnis, zum Beispiel http://localhost/phpMyAdmin/. Dies ist nicht unbedingt erforderlich, da phpMyAdmin diesen Wert in den meisten
F&auml;llen auch automatisch ermitteln kann. L&auml;sst man diesen Eintrag
leer, gibt es auf der Startseite eine Warnung, die ausgeschaltet werden
kann, wenn es auch automatisch funktioniert.
Hat man die notwendigen Einstellungen vorgenommen, kann man die
Startseite aufrufen. Befindet man sich direkt auf dem Web-Server und
hat phpMyAdmin unter htdocs im Verzeichnis phpMyAdmin installiert,
kann man es mit der URL http://localhost/phpMyAdmin/index.php aufrufen und erh&auml;lt eine Webseite wie in Abbildung 5.6 zu sehen.
=XJULIIVP|JOLFKNHLWHQ
Abbildung 5.6: Startseite von phpMyAdmin
Auf der Startseite kann man verschiedene Dinge erreichen: Im linken
Rahmen l&auml;sst sich eine Datenbank ausw&auml;hlen. In der linken Spalte des
rechten Rahmens gibt es einige Links auf Verwaltungstasks, die unabh&auml;ngig von einer ausgew&auml;hlten Datenbank sind (Erstellen einer neuen
Datenbank, Informationen &uuml;ber den MySQL-Server oder die Benutzer
anzeigen, MySQL-Server neu starten). Rechts l&auml;sst sich die Sprache von
phpMyAdmin ausw&auml;hlen und man erreicht die Dokumentation. Der in
eckigen Klammern angegebene Link auf Dokumentation f&uuml;hrt direkt auf
die entsprechenden Webseiten von http://www.mysql.com.
Klickt man zum Beispiel auf Statistiken &uuml;ber alle Datenbanken, erreicht
man die in Abbildung 5.7 dargestellte Seite. Hier lassen sich (wie an fast
allen anderen Stellen auch, wo eine tabellarische &Uuml;bersicht gezeigt
wird) die Spaltentitel anklicken. Dadurch wird die Anzeige nach der entsprechenden Spalte sortiert. Klickt man die &Uuml;berschrift ein zweites Mal
an, wird die Tabelle nach dieser Spalte absteigend sortiert.
SKS0\$GPLQ
Abbildung 5.7: Statistiken &uuml;ber alle Datenbanken in phpMyAdmin
&Uuml;ber die Auswahlbox im linken Rahmen gelangt man zu den einzelnen
Datenbanken des Servers. W&auml;hlt man dort musikschule aus, gelangt man
in eine &Uuml;bersicht &uuml;ber diese Datenbank (siehe Abbildung 5.8). Mit einem Klick auf eine der angezeigten Tabellennamen erh&auml;lt man eine
&Uuml;bersicht &uuml;ber die Struktur der Tabelle und einige statistische Daten
(Abbildung 5.9). Von hier aus kann man eigentlich alles machen, was
mit einer Tabelle sinnvoll ist: &Auml;ndern der Struktur, Eintragen von Daten,
Analysieren der Inhalte, Exportieren, Importieren, Umbenennen und
vieles mehr. Klickt man auf den Reiter Anzeigen, erh&auml;lt man den Inhalt
der Tabelle (siehe Abbildung 5.10). Dabei sind ein paar Dinge, die auch
an vielen anderen Stellen vorkommen, erw&auml;hnenswert:
• Es wird der zugrunde liegende SQL-Befehl mit Syntaxhighlighting
angezeigt. Dieser Befehl l&auml;sst sich &uuml;ber &Auml;ndern anpassen. So kann
man nebenbei etwas SQL lernen …
• Man kann angeben, wie viele Datens&auml;tze angezeigt werden sollen.
Zudem l&auml;sst sich festlegen, ob die Datens&auml;tze untereinander oder nebeneinander zu sehen sein sollen.
• F&uuml;r die einzelnen Spalten lassen sich Aktionen durchf&uuml;hren (hier:
&Auml;ndern, L&ouml;schen).
• Es gibt eine Druckansicht, die alle „Befehlslinks“ entfernt und eine
sinnvoll druckbare &Uuml;bersicht darstellt (siehe Abbildung 5.11).
=XJULIIVP|JOLFKNHLWHQ
Abbildung 5.8: &Uuml;bersicht &uuml;ber die Datenbank musikschule in phpMyAdmin
Abbildung 5.9: &Uuml;bersicht &uuml;ber die Tabelle raum in phpMyAdmin
SKS0\$GPLQ
Abbildung 5.10: Inhalt der Tabelle raum in phpMyAdmin
Abbildung 5.11: Druckansicht der Tabelle raum in phpMyAdmin
All diese Optionen sind auch an vielen anderen Stellen vorhanden, so
dass man sich schnell zurechtfindet.
=XJULIIVP|JOLFKNHLWHQ
phpMyAdmin ist ein sehr bequemes Hilfsmittel, um MySQL-Server und
-Datenbanken zu administrieren. Fast alles, was man mit einem MySQLServer machen kann, l&auml;sst sich auch &uuml;ber diese grafische Oberfl&auml;che erreichen, zudem l&auml;uft es in (fast) jedem Browser und unter jedem Betriebssystem und ist zudem wunderbar f&uuml;r die Fernwartung nutzbar.
5.4
Import und Export
Manchmal ist es notwendig, Daten aus der Datenbank auszulesen, um
sie f&uuml;r andere Programme zu verwenden. Oder man m&ouml;chte Daten aus
einer anderen Quelle einlesen, um sie in seinen eigenen Applikationen
zu nutzen. Nat&uuml;rlich kann man daf&uuml;r eigene Programme schreiben, die
Satz f&uuml;r Satz aus- bzw. einlesen und wegschreiben bzw. in die Datenbank
eintragen. Es gibt allerdings einfachere und schnellere Methoden daf&uuml;r.
Um Daten im Text-Format zu speichern, kann man SELECT ... INTO ...
nutzen. Umgekehrt lassen sich mit LOAD DATA INFILE Daten mit hoher Geschwindigkeit aus einer Text-Datei in die Datenbank einlesen.
Das Programm mysqldump erzeugt SQL-Befehle, mit denen eine Datenbank oder Tabelle in einem anderen Datenbank-Server wieder angelegt
werden kann. In die andere Richtung ist mysqlimport ein Tool, welches
das Importieren von Text-Dateien wie mit LOAD DATA INFILE unterst&uuml;tzt.
5.4.1 SELECT ... INTO
Um Daten in Textdateien zu exportieren, bietet sich der SELECT-Befehl
an, dem als Erweiterung ein Ziel und verschiedene Format-Optionen
mitgegeben werden. Die daraus erstellten Daten lassen sich auf ziemlich
weitreichende Art anpassen, allerdings haben sie nie eine feste Breite
(was man im Notfall allerdings mit einigen Tricks erreichen kann), sondern sind immer durch Trennzeichen unterteilt.
SELECT INTO
Die Syntax wurde schon weiter oben im Kapitel &uuml;ber SELECT beschrieben,
hier nochmals ein &Uuml;berblick &uuml;ber die Optionen. Prinzipiell geht es um
einen normalen SELECT-Befehl, der beliebig kompliziert sein kann. Zus&auml;tzlich folgt nach Angabe der Spalten der Abschnitt INTO ... mit seinen
Optionen:
SELECT ...
INTO {OUTFILE | DUMPFILE} 'file_name'
[FIELDS [TERMINATED BY 'fielddiv']
[[OPTIONALLY] ENCLOSED BY 'enc_char']
[ESCAPED BY 'esc_char']]
[LINES TERMINATED BY 'linedev']
FROM ...
Normalerweise wird man SELECT ... INTO OUTFILE ... nutzen. Dies ist die
„normale“ Version und sorgt f&uuml;r das Speichern aller selektierten Daten
mit den entsprechenden Formatierungsoptionen in der gew&uuml;nschten
Datei. Verwendet man stattdessen SELECT ... INTO DUMPFILE ..., wird nur
ein Datensatz in die Datei geschrieben, und zwar ohne Feldbegrenzer,
Spalten&uuml;berschriften oder &Auml;hnliches. Man kann dies zum Beispiel dazu
nutzen, den Inhalt eines Blob-Feldes direkt in einer Datei zu verewigen.
Zu beachten ist, dass die Ergebnismenge auf jeden Fall nur einen Datensatz enthalten darf, ansonsten funktioniert das Ganze nicht. Sichergehen
kann man, indem man die Option LIMIT 1 am Ende des SELECT-Befehls
nutzt.
Als Dateiname wird file_name verwendet. Diese Datei darf aus Sicherheitsgr&uuml;nden noch nicht existieren, sie wird auf jeden Fall neu angelegt.
Ist sie schon vorhanden, schl&auml;gt der Aufruf fehl. Die Datei wird auf dem
Server erstellt. M&ouml;chte man die Daten auf dem Client speichern, muss
man einen anderen Weg gehen: entweder &uuml;ber mysql -e &quot;SELECT ...&quot; &gt;
file_name mit den entsprechend formatierten Spalten (siehe auch Kapitel 5.2.1) oder &uuml;ber das Programm mysqldump (siehe Kapitel 5.4.3).
Gibt man nur den Dateinamen an, ohne weitere Formatierungsoptionen festzulegen, werden die Daten durch Tabulatorzeichen getrennt,
ohne Anf&uuml;hrungszeichen und mit dem Backslash (\) als Fluchtzeichen
abgespeichert. Dabei wird pro Zeile ein Datensatz angelegt. Mit folgendem Befehl wird die Datei raum.txt auf dem Server erzeugt (sofern nicht
schon vorhanden) und die Raum-Daten dort eingetragen:
SELECT * INTO OUTFILE 'raum.txt' FROM raum;
Die Datei raum.txt hat dann folgenden Inhalt (wobei zwischen den einzelnen Werten ein Tabulatorzeichen steht):
1
2
3
4
5
A5.33
B2.02
C4.16
A5.21
A5.23
5
2
4
5
5
4
20
11
6
6
Mit den folgenden Formatierungsoptionen l&auml;sst sich der Inhalt der Datei in einigen Dingen anpassen. FIELDS &auml;ndert das Ausgabeformat bez&uuml;glich der Feldwerte, w&auml;hrend LINES das Verhalten beim Wechsel von einem Datensatz auf den n&auml;chsten festlegt.
FIELDS
TERMINATED
• FIELDS TERMINATED BY 'fielddiv'
Hiermit kann man festlegen, wie die Feldwerte untereinander getrennt werden sollen. &Uuml;blich sind das Tabulatorzeichen (Standardeinstellung, auch erreichbar durch '\t'), das Komma oder das
=XJULIIVP|JOLFKNHLWHQ
Semikolon. Man kann durchaus auch mehr als ein Zeichen angeben,
es wird dann der gesamte String als Trenner genutzt. Dies ist zum Beispiel dann n&uuml;tzlich, wenn die Ausgabe „leserlicher“ sein soll: Man
gibt nicht nur ein Komma an, sondern auch noch ein Leerzeichen
danach:
SELECT * INTO OUTFILE 'raum2.txt' FIELDS TERMINATED BY ', ' FROM raum;
Das Ergebnis sieht dann so aus:
1,
2,
3,
4,
5,
A5.33,
B2.02,
C4.16,
A5.21,
A5.23,
5,
2,
4,
5,
5,
4
20
11
6
6
• FIELDS [OPTIONALLY] ENCLOSED BY 'enc_char'
FIELDS ENCLOSED
Alle Feldwerte werden durch den enc_char umschlossen. &Uuml;blicherweise wird man hier das einfache oder doppelte Anf&uuml;hrungszeichen nutzen, es sind aber auch andere denkbar, durchaus auch mehrere
Zeichen (zum Beispiel '#*#').
Was f&uuml;r einen Vorteil hat es, Feldwerte zum Beispiel mit Anf&uuml;hrungszeichen zu umschlie&szlig;en? Nun, ein Stringfeld kann alle m&ouml;glichen
Zeichen enthalten, unter anderem auch das Feldtrennzeichen. Ein
Tabulatorzeichen ist vielleicht selten, aber wenn man das Komma als
Feldtrenner nutzt, kann man schon bei Adressen Probleme bekommen. Das glauben Sie nicht? Dann kommen Sie mal nach Mannheim, dort gibt es in der Innenstadt keine Stra&szlig;ennamen (bis auf
Ausnahmen), sondern nur Bl&ouml;cke: A1, A2, ... A7, B1 usw. bis U7.
Noch kein Problem, allerdings wird die Hausnummer meist durch
ein Komma getrennt: P3, 6.
Was macht das jetzt f&uuml;r Kummer? Geben wir doch einfach mal ein
Beispiel aus. Zun&auml;chst f&uuml;gen wir einen Satz mit entsprechender
Adresse ein:
INSERT INTO schueler
(nachname, vorname, geburtsdatum, strasse, plz, ort, geschlecht)
VALUES
('Herms', 'Georg', '1960-09-16', 'P3, 6', '68161', 'Mannheim', 0);
Nun lassen wir uns eine Liste mit Namen und Adressen der Sch&uuml;ler
ausgeben:
SELECT nachname, vorname, strasse, plz, ort INTO OUTFILE 'komma.txt' FIELDS
TERMINATED BY ',' FROM schueler;
Das Ergebnis sieht so aus:
Schmidt,Thomas,Hauptstr. 16,28219,Bremen
Mayer,Anke,Leher Heerstr. 342,68219,Mannheim
Meier,Frank,Waldweg 30,69190,Walldorf
Schulze,Friederike,Relaisstr. 432,41564,Kaarst
Herms,Georg,P3\, 6,68161,Mannheim
Wie man sieht, ist das Komma nun mit einem Fluchtzeichen versehen. Dies ist beim anschlie&szlig;enden Weiterverarbeiten meist recht
umst&auml;ndlich, manche Programme k&ouml;nnen gar nichts damit anfangen. Es kann auch sein, dass man das Fluchtzeichen aus anderen
Gr&uuml;nden bewusst wegl&auml;sst (siehe dazu weiter unten). Und dann wird
es schwierig. In diesem Fall wird das verarbeitende Programm n&auml;mlich 6 als Postleitzahl und 68161 als Ort ansehen. Dumm, oder?
Die L&ouml;sung liegt eben in ENCLOSED BY. Das Beispiel von eben, jetzt aber
mit Anf&uuml;hrungszeichen:
SELECT nachname, vorname, strasse, plz, ort INTO OUTFILE 'komma2.txt'
FIELDS TERMINATED BY ',' ENCLOSED BY '&quot;' FROM schueler;
Als Ergebnis erh&auml;lt man jetzt:
&quot;Schmidt&quot;,&quot;Thomas&quot;,&quot;Hauptstr. 16&quot;,&quot;28219&quot;,&quot;Bremen&quot;
&quot;Mayer&quot;,&quot;Anke&quot;,&quot;Leher Heerstr. 342&quot;,&quot;68219&quot;,&quot;Mannheim&quot;
&quot;Meier&quot;,&quot;Frank&quot;,&quot;Waldweg 30&quot;,&quot;69190&quot;,&quot;Walldorf&quot;
&quot;Schulze&quot;,&quot;Friederike&quot;,&quot;Relaisstr. 432&quot;,&quot;41564&quot;,&quot;Kaarst&quot;
&quot;Herms&quot;,&quot;Georg&quot;,&quot;P3, 6&quot;,&quot;68161&quot;,&quot;Mannheim&quot;
Jeder Wert ist jetzt mit Anf&uuml;hrungszeichen umschlossen, das Komma
in P3, 6 nicht mehr mit einem Fluchtzeichen versehen. Damit k&ouml;nnen die meisten Programme etwas anfangen…
Nun kann man einwenden, dass bei Zahlen nun wirklich kein Anf&uuml;hrungszeichen notwendig ist. Es gibt keine besonders gef&auml;hrlichen
Zeichen, da kostet das nur Platz und macht auch etwas un&uuml;bersichtlicher. Dazu kann man die Option OPTIONALLY nutzen: Sie sorgt daf&uuml;r,
dass nur String-Felder umschlossen werden:
SELECT * INTO OUTFILE 'raum3.txt' FIELDS TERMINATED BY ', ' OPTIONALLY
ENCLOSED BY '&quot;' FROM raum;
f&uuml;hrt zu:
1,
2,
3,
4,
5,
&quot;A5.33&quot;,
&quot;B2.02&quot;,
&quot;C4.16&quot;,
&quot;A5.21&quot;,
&quot;A5.23&quot;,
&quot;5&quot;,
&quot;2&quot;,
&quot;4&quot;,
&quot;5&quot;,
&quot;5&quot;,
4
20
11
6
6
=XJULIIVP|JOLFKNHLWHQ
Die Etage (als jeweils vorletzter Wert) ist hier mit Anf&uuml;hrungszeichen
umschlossen, da sie als String in der Datenbank abgespeichert ist.
Wie man an den letzten Beispielen sieht, kann man bei FIELDS auch
mehrere Optionen kombinieren. Es muss nur mindestens eine angegeben sein, sonst muss man auch FIELDS weglassen.
• FIELDS ESCAPED BY 'esc_char'
FIELDS ESCAPED
Mit dieser Option kann man das Fluchtzeichen angeben. Standardm&auml;&szlig;ig handelt es sich um den Backslash (\), der dann vor allen besonders zu behandelnden Zeichen angegeben wird. Bei diesen
Zeichen handelt es sich um den Backslash selber (daher muss er bei
eigener Angabe auch als '\\' definiert werden), das Tabulatorzeichen, den Zeilenumbruch und der Feldtrenner innerhalb von Werten (sofern sie nicht durch Anf&uuml;hrungszeichen umschlossen sind).
Es lassen sich auch mehrere Zeichen angeben, von denen wird aber
nur das erste verwendet. Will man das Fluchtzeichen unterdr&uuml;cken,
muss ein leerer String ('') angegeben werden. Dies funktioniert &uuml;brigens auch bei den anderen Optionen.
• LINES TERMINATED BY 'linedev'
LINES
Durch diese Option ist es m&ouml;glich, die einzelnen Datens&auml;tze durch
besondere Zeichen zu trennen. &Uuml;blich ist der Zeilenumbruch ('\n'),
man kann aber auch beliebige andere Werte angeben. So w&uuml;rde die
Anweisung f&uuml;r einen Datensatztrenner #*# aussehen:
TERMINATED
SELECT raum_name INTO OUTFILE 'raum4.txt' LINES TERMINATED BY '#*#' FROM
raum;
Das Ergebnis w&auml;re dann:
A5.33#*#B2.02#*#C4.16#*#A5.21#*#A5.23#*#
Es handelt sich hier nur um eine Zeile, da die Datens&auml;tze nur noch
durch #*# getrennt sind, aber nicht mehr durch den Zeilenumbruch.
Die Standardeinstellung lautet zusammengefasst wie folgt:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n'
Zum Abschluss m&ouml;chte ich noch ein Beispiel aus dem „richtigen“ Leben
pr&auml;sentieren, bei dem es um die geschickte Kombination von Funktionen, Formatoptionen und der Ausgabe geht: Es hat nichts mit der Musikschule zu tun, sondern basiert auf einer Frage in der Newsgroup
de.comp.datenbanken.mysql von Andr&eacute; Schleife. Er hatte in einer Tabelle
Literaturverweise auf Artikel gespeichert, die er so in einer Datei spei-
chern wollte, dass sich aus dieser mittels BibTeX (einem Tool f&uuml;r das
Satzsystem LaTeX) ein Literaturverzeichnis erstellen lie&szlig;.
Gegeben war eine Tabelle article mit dem Schl&uuml;ssel ikey sowie den Feldern author, title, journal, year, pages, volume, number, URL und keywords.
Diese sollten dann als Datei pro Datensatz wie folgt aussehen:
@Article{ikey,
author = {author},
title = {title},
journal = {journal},
year = {year},
pages = {pages},
volume = {volume},
number = {number},
URL = {URL},
keywords = {keywords}
}
@Article{ikey,
...
Dabei entsprechen die kursiv geschriebenen Worte den Spaltennamen
in der Tabelle. Erschwerend kam noch hinzu, dass Felder, die keinen Inhalt haben, nicht auftauchen sollen.
Gel&ouml;st wurde das Ganze durch den folgenden Befehl:
SELECT CONCAT('@Article{',ikey,
IFNULL(CONCAT(',\n author = {',author),''),
IFNULL(CONCAT('},\n title = {',title),''),
IFNULL(CONCAT('},\n journal = {',journal),''),
IFNULL(CONCAT('},\n year = {',year),''),
IFNULL(CONCAT('},\n pages = {',page),''),
IFNULL(CONCAT('},\n volume = {',volume),''),
IFNULL(CONCAT('},\n number = {',number),''),
IFNULL(CONCAT('},\n URL = {',URL),''),
IFNULL(CONCAT('},\n keywords = {',keywords),''),'}\n}\n\n')
INTO OUTFILE '/sqltest/literatur.td.bib' FIELDS ESCAPED BY ''
FROM article ORDER BY ikey;
Mittels CONCAT werden die einzelnen Strings und Felder zusammengesetzt. IFNULL sorgt daf&uuml;r, dass nur dann eine Zeile entsteht, wenn das Feld
auch Inhalt besitzt. Dabei wurde die Eigenschaft ausgenutzt, dass CONCAT
immer dann NULL zur&uuml;ckliefert, wenn auch nur ein einzelner Wert der
Parameterliste NULL ist. So ist CONCAT(',\n author = {', author) dann
komplett NULL, wenn author alleine schon NULL ist. In diesem Fall
wird der zweite Parameter von IFNULL zur&uuml;ckgeliefert, der hier ein Leer-
=XJULIIVP|JOLFKNHLWHQ
string ist. Auf diesem Weg werden &uuml;berfl&uuml;ssige Leerzeilen vermieden,
zugleich wird aber f&uuml;r die einzelnen Elemente nicht NULL, sondern ein
leerer String zur&uuml;ckgeliefert. Dies ist deshalb n&ouml;tig, weil sonst das
oberste CONCAT auch NULL zur&uuml;ckgeben w&uuml;rde.
FIELDS ESCAPED BY '' sorgt wiederum daf&uuml;r, dass die per Hand eingef&uuml;gten
Zeilenumbr&uuml;che (\n) nicht wieder mit einem Backslash maskiert werden.
Als Ergebnis erh&auml;lt man jetzt folgenden Text, der wunderbar mit BibTeX
weiterverarbeitet werden kann:
@Article{eppler:92,
author = {D. T. Eppler et al.},
title = {Passive Microwave Signatures of Sea Ice},
journal = {Geophysical Monograph},
year = {1992},
pages = {300--302},
volume = {68},
keywords = {microwave signatures}
}
@Article{fuhrhop:96,
author = {R. Fuhrhop and C. Simmer},
title = {SSM/I Brightness Temperature Corrections for Incidence Angle
Variantions},
journal = {Journal of Atmospheric and Oceanic Technology},
year = {1996},
pages = {230--235},
volume = {13},
number = {1},
keywords = {temperature corrections}
}
@Article{hartmann:96,
author = {J. Hartmann et al.},
title = {Radiation and Eddy Flux Experiment 1995 (REFLEX III)},
journal = {Berichte zur Polarforschung},
year = {1996},
pages = {147--155},
volume = {218},
URL = {www.awi-bremerhaven.de},
keywords = {REFLEX III}
}
Setzt man das Ergebnis schlie&szlig;lich in LaTeX um, erh&auml;lt man die gew&uuml;nschte Ausgabe in Abbildung 5.12:
So konnten Daten aus den verschiedenen jahreszeitlichen Situationen gewonnen werden [2].
Dabei ist zu bedenken, da&szlig; alleine dem SSM/I-Sensor schon ein Fehler
von etwa 2 K zuzuordnen ist [3].
Aus [1] wurden dann für diesen Eistyp die entsprechenden Emissivitäten
ermittelt und in (für MWMOD notwendige) Reflektivitäten umgerechnet.
Literatur
[1] D. T. Eppler et al. Passive Microwave Signatures of Sea Ice. Geophysical
Monograph, 68:300–302, 1992.
[2] J. Hartmann et al. Radiation and Eddy Flux Experiment 1995 (REFLEX
III). Berichte zur Polarforschung, 218:147–155, 1996.
[3] R. Fuhrhop and C. Simmer. SSM/I Brightness Temperature Corrections for Incidence Angle Variantions. Journal of Atmospheric and Oceanic
Technology, 13(1):230–235, 1996.
Abbildung 5.12: Ausgabe der LaTeX-Datei mit dem Literaturverzeichnis
5.4.2 LOAD DATA INFILE
LOAD DATA
F&uuml;r den umgekehrten Weg, das Einlesen von Textdaten in eine MySQLTabelle, gibt es den Befehl LOAD DATA INFILE. Mit ihm kann man Dateien
des Typs einlesen, die sich auch mit SELECT ... INTO erzeugen lassen, auch
die Parameter sind zum Teil identisch. Seine Syntax lautet:
LOAD DATA [LOW_PRIORITY | CONCURRENT]
[LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[FIELDS
[TERMINATED BY 'fielddiv']
[[OPTIONALLY] ENCLOSED BY 'enc_char']
[ESCAPED BY 'esc_char' ]
]
[LINES TERMINATED BY 'linediv']
[IGNORE number LINES]
[(col_name,...)]
Die k&uuml;rzeste g&uuml;ltige Variante ist hier
LOAD DATA INFILE 'file_name' INTO TABLE tbl_name;
Dabei werden die Daten aus der Textdatei file_name in die Tabelle
tbl_name eingelesen. Die Feldwerte m&uuml;ssen durch Tabulatoren getrennt
=XJULIIVP|JOLFKNHLWHQ
werden, d&uuml;rfen nicht mit Anf&uuml;hrungszeichen umschlossen sein und
das Fluchtzeichen ist der Backslash (\). Die einzelnen Datens&auml;tze sind
durch Zeilenumbr&uuml;che getrennt.
Die solcherma&szlig;en eingelesenen Daten wandern dann in die Tabelle
tbl_name, wobei alle Felder in der richtigen Reihenfolge schon in der Datei
vorhanden sein m&uuml;ssen und auch keine &uuml;berfl&uuml;ssigen Zeilen am Anfang
der Datei existieren d&uuml;rfen. Die schon existierenden Schl&uuml;sselwerte in der
Tabelle d&uuml;rfen in der Datei nicht nochmals vorkommen, da es ansonsten
eine Fehlermeldung gibt.
Nat&uuml;rlich kann man sehr viele &Auml;nderungen am Standardverhalten vornehmen:
• LOW_PRIORITY | CONCURRENT
Gibt man als Option LOW_PRIORITY an, werden nur dann Daten in die
Zieltabelle geschrieben, wenn sonst niemand mehr auf sie zugreift.
Umgekehrt kann man mit CONCURRENT daf&uuml;r sorgen, dass auch w&auml;hrend des Einf&uuml;gens von Daten mittels LOAD DATA INFILE andere Clients
auf die Tabelle zugreifen k&ouml;nnen, was allerdings nur mit MyISAMTabellen m&ouml;glich ist.
• LOCAL
Normalerweise sucht MySQL die Datei auf dem Server. Mit der Angabe von LOCAL wird der Client-Rechner als Grundlage genommen. Allerdings muss man sich dar&uuml;ber im Klaren sein, dass das Laden der
Daten dann l&auml;nger dauert, weil schlie&szlig;lich die Textdatei erst an den
Server &uuml;bertragen werden muss.
• REPLACE | IGNORE
Standardverhalten von LOAD DATA INFILE ist, dass es keine Konflikte
zwischen den Schl&uuml;sselwerten der neu einzulesenden Daten und denen der schon vorhandenen Daten in der Tabelle geben darf. Passiert
dies doch (d.h., ein neu einzutragender Datensatz aus der Datei besitzt einen Schl&uuml;ssel, der schon in der Tabelle existiert), bricht die
Verarbeitung mit einer Fehlermeldung ab. Dies entspricht dem Verhalten von INSERT INTO ...
Mittels REPLACE kann man nun daf&uuml;r sorgen, dass die Daten trotzdem
eingetragen werden; bestehende Datens&auml;tze mit dem entsprechenden Schl&uuml;ssel werden dadurch &uuml;berschrieben. Durch diese Option
wird also das Verhalten des Befehls REPLACE INTO ... nachgebildet.
Nutzt man stattdessen IGNORE, werden vorhandene Daten nicht &uuml;berschrieben, es wird aber auch keine Fehlermeldung ausgegeben. Damit bleiben alte Daten bestehen, noch nicht vorhandene werden
aber trotzdem eingetragen – wie bei INSERT IGNORE INTO...
• FIELDS TERMINATED BY 'fielddiv' [OPTIONALLY] ENCLOSED BY 'enc_char'
ESCAPED BY 'esc_char'
LINES TERMINATED BY 'linediv'
Diese Optionen entsprechen exakt denen bei SELECT ... INTO, bis auf
die Ausnahme, dass enc_char und esc_char nur aus jeweils einem einzelnen Zeichen bestehen d&uuml;rfen (wenn man sie nicht leer l&auml;sst). Zudem ist es nicht zul&auml;ssig, fielddiv und enc_char gleichzeitig leer zu
lassen. Dies entspr&auml;che einer Textdatei mit festen Spaltenbreiten, was
nicht unterst&uuml;tzt wird.
• IGNORE number LINES
Mit dieser Angabe werden die ersten number Zeilen am Anfang der Datei ignoriert. Damit kann man Zeilen &uuml;berspringen, die Spalten&uuml;berschriften oder andere Angaben zu den Daten enthalten.
• (col_name, ...)
Auf diesem Weg kann man die zu bef&uuml;llenden Spalten der Tabelle in
der entsprechenden Reihenfolge angeben, in der sie in der Datei auftauchen. Dies kann dann n&uuml;tzlich sein, wenn man nicht alle Spalten
der Tabelle bef&uuml;llen will oder die Daten in der Datei in der falschen
Reihenfolge stehen.
Felder, die nicht gef&uuml;llt werden – entweder, weil sie in der Spaltenliste nicht mit aufgef&uuml;hrt wurden, oder weil einfach nicht genug Werte
pro Datensatz vorhanden sind – erhalten ihren Standardwert. Gibt es
hingegen zu viele Werte pro Datensatz in der Datei, werden diese
ignoriert und die Anzahl der Warnungen dementsprechend erh&ouml;ht.
Als Beispiel wollen wir unsere Musikschul-Datenbank mit den g&uuml;ltigen
Bankleitzahlen erg&auml;nzen. Die Daten m&ouml;gen zwar nicht unbedingt zwingend wichtig sein, sie sind aber ein sch&ouml;nes Beispiel f&uuml;r das Einlesen externer Daten nach MySQL. Zudem kann man die Daten kostenlos im Internet erhalten. Leider handelt es sich dabei um eine Datei mit fester
Feldl&auml;nge und ohne Feldtrenner. Aber auch dies l&auml;sst sich mit Hilfe einer
Zwischentabelle l&ouml;sen.
Auf den Web-Seiten der Bundesbank gibt es unter http://www.bundesbank.de/zv/zv_bankleitzahlen.htm einen Link „Download der Bankleitzahlen-Dateien“ zum Herunterladen der Bankleitzahlen. Es gibt verschiedene Varianten, uns interessiert hier aber die PC/Text-Version. Die hier
genutzte Datei hat den Namen blz0209pc.exe. Dabei steht 0209 f&uuml;r die
G&uuml;ltigkeit ab September 2002, eventuell gibt es bereits neuere Versionen.
Die Datei ist eine selbstentpackende Zip-Datei. Sie kann auch unter Linux mittels unzip ausgepackt werden. Als Ergebnis erh&auml;lt man eine Text-
=XJULIIVP|JOLFKNHLWHQ
datei (hier blz0209pc.txt) und ein Word-Dokument mit der Beschreibung &uuml;ber den Aufbau der Daten (satzaufbaupc188.doc). Auch diese
Datei l&auml;sst sich notfalls unter Linux &ouml;ffnen, entweder, indem man
OpenOffice oder StarOffice nutzt oder sie sich ganz rudiment&auml;r mit
strings satzaufbaupc188.doc ausgeben l&auml;sst.
Aus dieser Beschreibung kann man nun den Aufbau der Daten entnehmen. Da es sich allerdings um Felder fester L&auml;nge handelt, bleibt uns zun&auml;chst nichts anderes &uuml;brig, als die Daten „am St&uuml;ck“ in eine Zwischentabelle zu importieren. Aus dieser Tabelle kann man dann mit den SQLFunktionen die „richtige“ BLZ-Tabelle mit den „richtigen“ Feldern bef&uuml;llen. Der Dokumentation entnehmen wir, dass die Daten pro Satz insgesamt 188 Zeichen lang sind. Also erzeugen wir eine Tabelle mit einem
Feld dieser L&auml;nge:
CREATE TABLE blz_import (satz CHAR(188));
Nun k&ouml;nnen wir f&uuml;r den ersten Schritt die Daten importieren.
mysql&gt; LOAD DATA INFILE 'blz0209pc.txt'
-&gt; INTO TABLE blz_import;
Query OK, 21104 rows affected (0.39 sec)
Records: 21104 Deleted: 0 Skipped: 0 Warnings: 0
Wie man sieht, geht das Einlesen der Datei wirklich schnell – gerade mal
0,39 Sekunden haben die 21.104 S&auml;tze ben&ouml;tigt. Allerdings sind wir
noch nicht fertig, schlie&szlig;lich m&uuml;ssen die Daten noch in die richtige Tabelle kopiert werden. Diese legen wir erst einmal an, wobei als Vorlage
f&uuml;r die Felder die Beschreibung der Datenstruktur dient. Dabei nutzen
wir nur die Felder, die wir sp&auml;ter auch nutzen wollen: die Bankleitzahl
selber und der l&auml;ngere Name der Bank.
CREATE TABLE bankleitzahl
(blz CHAR(8),
bank_name VARCHAR(58),
INDEX (blz),
INDEX (bank_name));
Es wurde kein Prim&auml;rschl&uuml;ssel angelegt, da es durchaus mehrfache
Kombinationen von BLZ und Name gibt. Nun k&ouml;nnen wir die Daten aus
der Import-Tabelle &uuml;bertragen:
mysql&gt; INSERT INTO bankleitzahl
-&gt;
(blz, bank_name)
-&gt;
SELECT DISTINCT LEFT(satz, 8), MID(satz, 28, 58)
-&gt;
FROM blz_import
-&gt;
WHERE LEFT(satz, 8) &gt; '00000000';
Query OK, 6401 rows affected (0.56 sec)
Records: 6401 Duplicates: 0 Warnings: 0
Durch den Einsatz der Zwischentabelle und den Funktionen LEFT() und
MID() haben wir trotz fester Feldl&auml;nge die Daten sinnvoll und ziemlich
schnell importieren k&ouml;nnen. Wie man sieht, wurden nun nur noch
6.401 S&auml;tze in die eigentliche BLZ-Tabelle &uuml;bertragen. Das liegt zum einen daran, dass wir mit der WHERE-Bedingung alle zu l&ouml;schenden Bankleitzahlen ausgeschlossen haben, zum anderen und vor allem aber
daran, dass die diversen einzelnen Gesch&auml;ftsstellen nicht mit aufgenommen wurden. Durch das DISTINCT wurde verhindert, dass eine Satzkombination mehrfach vorkommt. Man kann nun diese Tabelle dazu
nutzen, Bankleitzahlen oder Banknamen automatisch heraussuchen
und vorschlagen zu lassen, wenn man Kontodaten in einer Applikation
f&uuml;r die Musikschule eintr&auml;gt. Durch die Indizes auf blz und bank_name
ist diese Suche auch ziemlich schnell.
5.4.3 mysqldump
mysqldump
Um Daten aus einem MySQL-Server zu exportieren, kann man auch das
Programm mysqldump nutzen. Es liest die Struktur und die Daten einer
oder mehrerer Datenbanken oder Tabellen aus und schreibt sie in eine
Datei. Mit dieser kann man die entsprechenden Strukturen danach wieder erneut aufbauen (sei es auf einem anderen Server oder auf dem gleichen Server zum Beispiel nach einer Neuinstallation) und die Daten eintragen lassen. Selbst das Erstellen der Datenbank selber wird auf
Wunsch &uuml;bernommen.
Beim Aufruf des Programms kann man eine der drei folgenden SyntaxVarianten nutzen:
mysqldump [OPTIONS] database [tables]
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
mysqldump [OPTIONS] --all-databases [OPTIONS]
In der ersten Variante gibt man eine Datenbank an, dazu die Tabellen,
die exportiert werden sollen. L&auml;sst man die Angabe der Tabellen weg,
werden alle Tabellen der Datenbank exportiert.
Die zweite Variante erlaubt die Auswahl mehrerer Datenbanken, f&uuml;r die
alle Tabellen exportiert werden. Zus&auml;tzlich werden mit den erzeugten
SQL-Befehlen die Datenbanken erstellt und vor dem Anlegen und Bef&uuml;llen der Tabellen in diese gewechselt.
In der dritten Variante schlie&szlig;lich werden alle Datenbanken exportiert.
Die Optionen sind in Tabelle 5.3 aufgef&uuml;hrt.
=XJULIIVP|JOLFKNHLWHQ
Kurze Version
Lange Version
Beschreibung
-A
--all-databases
Exportiere alle Datenbanken des Servers.
-a
--all
Nutze alle CREATE-Optionen von MySQL.
-#
--debug=...
Ablauf des Programms protokollieren und
verfolgen
--character-setsdir=...
Angabe des Verzeichnisses, in dem die
Zeichensatzbeschreibungen abgelegt sind
-?
--help
Ausgabe der Hilfe-Informationen
-B
--databases
Ausgabe mehrerer Datenbanken, die nach
den Optionen aufgef&uuml;hrt werden m&uuml;ssen
(siehe zweite Syntaxvariante)
-c
--complete-insert
INSERT-Befehle werden komplett mit den
Spaltennamen erzeugt.
-C
--compress
Nutzung der Datenkompression bei der
Kommunikation zwischen Client und Server
--defaultcharacter-set=...
Angabe des Standard-Zeichensatzes
--extended-insert
Nutzung der Angabe mehrerer Datens&auml;tze
mit einem INSERT-Befehl
--add-drop-table
Aufnahme des Befehls DROP TABLE vor dem
Erstellen der Tabelle
--add-locks
Hinzuf&uuml;gen von LOCK TABLE vor den INSERTBefehlen und UNLOCK TABLE danach. Dadurch
wird das Einf&uuml;gen von Datens&auml;tzen beschleunigt.
--allow-keywords
Es k&ouml;nnen Schl&uuml;sselw&ouml;rter als Spaltennamen
genutzt werden, indem jedem Spaltenname
der Tabellenname vorangestellt wird.
--delayed-insert
Einf&uuml;gen von Daten mittels INSERT DELAYED.
--master-data
Hinzuf&uuml;gen von Ort und Dateiname des
Masters bei verteilten Datenbanken
-F
--flush-logs
Wegschreiben der Log-Dateien, bevor mit
dem Export begonnen wird
-f
--force
auch bei einem Fehler mit dem Exportieren
fortfahren
-h
--host=...
Angabe des MySQL-Servers
-l
--lock-tables
Sperren aller Tabellen vor dem Exportieren
--no-autocommit
Hinzuf&uuml;gen von Befehlen zum Deaktivieren
des Autocommits und dem Best&auml;tigen am
Ende der INSERT-Befehle.
--disable-keys
Deaktivieren der Schl&uuml;ssel vor dem Eintragen
der Daten und nachtr&auml;gliches Aktivieren.
Dies kann das Erstellen der Daten an ihrem
neuen Ort beschleunigen.
-e
-K
Tabelle 5.3: Optionen von mysqldump
Kurze Version
Lange Version
Beschreibung
-n
--no-create-db
Die Befehle zum Anlegen der Datenbanken
werden nicht mit ausgegeben.
-t
--no-create-info
Die Befehle zum Anlegen der Tabellen werden nicht mit ausgegeben.
-d
--no-data
Es werden nur die Strukturen exportiert.
-O
--set-variable
var=option
Setzen von Variablen
--opt
Schnellstm&ouml;gliche Variante zum Exportieren
und Importieren von Daten. Diese Option
entspricht der gemeinsamen Nutzung von
--add-drop-table --add-locks --all
--quick --extended-insert --lock-tables
--disable-keys
-p
--password[=...]
Angabe des Kennworts oder Abfrage
-W
--pipe
Verwendung von Named Pipes f&uuml;r die
Kommunikation mit dem Server
-P
--port=...
Angabe des Ports, &uuml;ber den sich der Client
mit dem MySQL-Server verbinden soll
-q
--quick
direkte Ausgabe der Befehle ohne Pufferung
-Q
--quote-names
Umschlie&szlig;en von Tabellen- und Spaltennamen mit dem umgekehrten einfachen
Anf&uuml;hrungszeichen (`)
-r
--result-file=...
Ausgabe in die angegebene Datei statt auf
die Standardausgabe
-S
--socket=...
Angabe der zu verwendenden Socket-Datei
--tables
&Uuml;berschreiben der Option --databases
-T
--tab=...
Ausgabe der Daten als Textdatei. F&uuml;r jede
Tabelle werden zwei Dateien erstellt: eine
SQL-Datei mit den Befehlen zum Anlegen
der Struktur und eine Textdatei mit den
Daten. Diese k&ouml;nnen sp&auml;ter mit LOAD DATA
INFILE eingelesen werden. Erstellt werden
die Dateien im angegebenen Verzeichnis.
Die Textdateien lassen sich wie bei SELECT
INTO formatieren, dazu dienen die entsprechenden Optionen, die am Ende der Tabelle
beschrieben sind.
-u
--user=...
Angabe des Benutzers, der sich anmelden soll
-v
--verbose
ausf&uuml;hrlichere Ausgabe von Informationen
w&auml;hrend des Exportierens
-V
--version
Ausgabe der Version und Beenden des Programms
-w
--where=...
Angabe von WHERE-Bedingungen, die f&uuml;r die
auszugebenden Datens&auml;tze erf&uuml;llt sein m&uuml;ssen. Anf&uuml;hrungszeichen sind notwendig.
Tabelle 5.3: Optionen von mysqldump (Forts.)
=XJULIIVP|JOLFKNHLWHQ
Kurze Version
Lange Version
Beschreibung
-X
--xml
Ausgabe der Daten als wohlgeformte XMLDatei
-x
--first-slave
Sperren aller Datens&auml;tze in allen Datenbanken (bei verteilten Systemen)
--fieldsterminated-by=...
Angabe der Feldtrenner bei --tab.
Standard ist \t.
--fieldsenclosed-by=...
Angabe der Quoting-Zeichen bei --tab
--fields-optionally-enclosed-by=...
Angabe der optionalen Quoting-Zeichen bei
--tab
--fields-escapedby=...
Angabe des Fluchtzeichens bei --tab
--linesterminated-by=...
Angabe der Datensatztrenner bei --tab.
Standard ist \n.
Tabelle 5.3: Optionen von mysqldump (Forts.)
Standardm&auml;&szlig;ig werden die SQL-Befehle direkt in die Standardausgabe
geschrieben.
prompt&gt;mysqldump musikschule
-- MySQL dump 8.22
--- Host: localhost
Database: musikschule
---------------------------------------------------------- Server version3.23.51-nt
--- Table structure for table 'ausleihe'
-CREATE TABLE ausleihe (
ausleihe_id int(10) unsigned NOT NULL auto_increment,
leihinstrument_id int(10) unsigned NOT NULL default '0',
schueler_id int(10) unsigned NOT NULL default '0',
datum_von date NOT NULL default '0000-00-00',
datum_bis date default NULL,
PRIMARY KEY (ausleihe_id)
) TYPE=MyISAM;
--- Dumping data for table 'ausleihe'
---- Table structure for table 'instrument'
--
CREATE TABLE instrument (
instrument_id int(10) unsigned NOT NULL auto_increment,
instr_name varchar(50) NOT NULL default '',
instr_gruppe varchar(50) default NULL,
PRIMARY KEY (instrument_id)
) TYPE=MyISAM;
--- Dumping data for table 'instrument'
--
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
...
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
instrument
instrument
instrument
instrument
instrument
instrument
instrument
instrument
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
(1,'Querfl&ouml;te','Holzbl&auml;ser');
(2,'Klarinette','Holzbl&auml;ser');
(3,'Violine','Streicher');
(4,'Viola','Streicher');
(5,'Posaune','Blechbl&auml;ser');
(6,'Trompete','Blechbl&auml;ser');
(7,'Klavier','Tasten');
(8,'Keyboard','Tasten');
Diese l&auml;sst sich nat&uuml;rlich in eine Datei umbiegen:
prompt&gt;mysqldump musikschule &gt; musikschule.sql
Oder man nutzt die Option -r bzw. --result-file:
prompt&gt;mysqldump --result-file=musikschule.sql musikschule
Solch eine erzeugte Datei kann man mit mysql auf einem anderen Server
wieder einlesen:
prompt&gt;mysql musikschule &lt; musikschule.sql
M&ouml;chte man die Daten sp&auml;ter mit mysqlimport wieder einlesen (siehe Kapitel 5.4.4), muss man mit der Option --tab arbeiten. Die Daten werden
dann in Dateien geschrieben, die gleich den richtigen Namen besitzen:
prompt&gt;mysqldump --tab=musikschule musikschule
Damit werden in das Verzeichnis musikschule Dateien f&uuml;r alle Tabellen
der Datenbank musikschule geschrieben.
Um Daten von einem MySQL-Server auf einen anderen zu verschieben,
kann man auch eine andere, elegantere M&ouml;glichkeit nutzen. Dazu sollte
man sich auf dem Server mit dem Ausgangspunkt der Daten befinden.
Dann kann man die Ausgabe des Programms gleich als Eingabe f&uuml;r
mysql auf dem Zielserver nutzen:
=XJULIIVP|JOLFKNHLWHQ
prompt&gt;mysqldump --opt musikschule | mysql --h remotehost -C musikschule
Durch --opt wird der schnellstm&ouml;gliche Weg zum Exportieren gew&auml;hlt,
w&auml;hrend -C daf&uuml;r sorgt, dass die Kommunikation mit dem entfernten
Rechner komprimiert vonstatten geht.
5.4.4 mysqlimport
Mit dem Programm mysqlimport kann man – genau wie bei LOAD DATA INFILE – Daten aus Textdateien in die Datenbank laden. Im Grunde genom-
mysqlimport
men stellt mysqlimport nur eine Kommandozeilenschnittstelle f&uuml;r den
SQL-Befehl bereit. Viele Optionen sind identisch zu denen von LOAD DATA
INFILE. Der Aufruf des Programms geschieht mit der folgenden Syntax:
mysqlimport [OPTIONS] database textfile1 [textfile2 ...]
Von den angegebenen Textdateien werden alle vorhandenen Erweiterungen abgeschnitten und der eigentliche Dateiname als Name der Tabelle genommen, in die die Daten aus der entsprechenden Datei importiert werden sollen. So w&uuml;rden zum Beispiel die Daten der Datei
unterricht.txt in die Tabelle unterricht importiert werden. Die verwendete
Datenbank muss auch mit angegeben werden.
Als m&ouml;gliche Optionen stehen die in Tabelle 5.4 aufgef&uuml;hrten bereit.
Viele sollten bereits bekannt sein.
Kurze Version
Lange Version
Beschreibung
-#
--debug[=...]
Ablauf des Programms protokollieren und
verfolgen
-?
--help
Ausgabe der Hilfe-Informationen
–-default-character-set=...
Angabe des Standard-Zeichensatzes
--character-setsdir=...
Angabe des Verzeichnisses mit den Zeichens&auml;tzen
-c
–-columns=...
Angabe der Spalten, die f&uuml;r den Import
genutzt werden sollen. Diese Option entspricht dem Passus (col_name, ...) in LOAD
DATA INFILE.
-C
–-compress
Nutzung der Datenkompression bei der
Kommunikation zwischen Client und Server
-d
–-delete
Die zu bef&uuml;llenden Tabellen werden vor dem
Import geleert.
-f
–-force
Der Import soll weitergehen, auch wenn ein
Fehler aufgetreten ist. Existiert zum Beispiel
eine Tabelle nicht, wird das Programm ohne
diese Option abgebrochen.
Tabelle 5.4: Optionen von mysqlimport
Kurze Version
Lange Version
Beschreibung
-h
–-host=...
Angabe des MySQL-Servers
-i
–-ignore
Zu importierende Daten mit Schl&uuml;sseln, die
in der Tabelle schon vorhanden sind, werden
ignoriert. Dies entspricht der Option IGNORE
bei LOAD DATA INFILE.
-l
–-lock-tables
Sperren aller Tabellen des Servers bevor der
Import beginnt. Damit ist sichergestellt, dass
alle Tabellen synchron sind.
-L
–-local
Die Dateien werden auf dem Client eingelesen und zum Server &uuml;bertragen. Ohne diese
Angabe werden die Daten auf dem Server
gesucht.
–-low-priority
Die Daten werden mit geringerer Priorit&auml;t in
die Tabellen geschrieben (entspricht
LOW_PRIORITY bei LOAD DATA INFILE).
-p
–-password[=...]
Angabe des Kennwortes f&uuml;r den Benutzer
oder Abfragen bei Nichtangabe
-W
–-pipe
Nutzung von Named Pipes f&uuml;r die Kommunikation zwischen Client und Server
-r
–-replace
Existieren schon Daten in der Tabelle mit
Schl&uuml;sseln, die auch in der Datei vorkommen, werden die bestehenden Daten &uuml;berschrieben. Dies entspricht der Option
REPLACE in LOAD DATA INFILE.
-s
–-silent
„Stille“ Arbeitsweise. Es werden nur Fehlermeldungen ausgegeben.
-S
–-socket=...
Angabe der zu verwendenden Socket-Datei
-u
–-user=...
Angabe des Benutzers, der angemeldet werden soll
-v
–-verbose
ausf&uuml;hrliche Statusausgaben w&auml;hrend des
Programmlaufs
-V
–-version
Ausgabe der Versionsangaben und Beenden
des Programms
--fieldsterminated-by=...
Angabe der Feldtrenner. Standard ist \t.
--fieldsenclosed-by=...
Angabe der Quoting-Zeichen
--fields-optionally-enclosed-by=...
Angabe der optionalen Quoting-Zeichen
--fields-escapedby=...
Angabe des Fluchtzeichens
--lines-terminated-by=...
Angabe der Datensatztrenner. Standard ist
\n.
Tabelle 5.4: Optionen von mysqlimport (Forts.)
=XJULIIVP|JOLFKNHLWHQ
M&ouml;chte man also nun Daten importieren, kann man wie folgt vorgehen:
prompt&gt;cd musikschule
prompt&gt;mysqlimport --delete musikschule ausleihe.txt instrument.txt
musikschule.ausleihe: Records: 0 Deleted: 0 Skipped: 0 Warnings: 0
musikschule.instrument: Records: 8 Deleted: 0 Skipped: 0 Warnings: 0
Durch --delete oder -d wird daf&uuml;r gesorgt, dass keine alten Daten in den
Tabellen verbleiben. Das m&ouml;chte man nat&uuml;rlich ab und an gerne haben,
in diesem Fall aber geht es eben um den direkten Import der alten Daten.
Im Folgenden wird dann f&uuml;r jede Tabelle angegeben, wie viele Datens&auml;tze
importiert wurden, ob es doppelte gab und ob Warnungen auftraten.
M&ouml;chte man mehr &uuml;ber den aktuellen Status der Verarbeitung erfahren,
kann man die Option --verbose oder -v nutzen:
prompt&gt;mysqlimport -d -v musikschule ausleihe.txt instrument.txt
Connecting to localhost
Selecting database musikschule
Deleting the old data from table ausleihe
Loading data from file: ausleihe.txt into ausleihe
musikschule.ausleihe: Records: 0 Deleted: 0 Skipped: 0 Warnings: 0
Deleting the old data from table instrument
Loading data from file: instrument.txt into instrument
musikschule.instrument: Records: 8 Deleted: 0 Skipped: 0 Warnings: 0
Disconnecting from localhost
5.5
Schnittstellen
Es ist nun sicherlich sehr praktisch, die verschiedensten Programme zur
Verf&uuml;gung zu haben, um auf den MySQL-Server und dessen Daten zugreifen zu k&ouml;nnen. Allerdings sind dies alles Programme, die nicht unbedingt sinnvoll f&uuml;r einen Endbenutzer sind. Dieser erwartet eine Oberfl&auml;che, die die Daten sinnvoll angeordnet anzeigt, Eingabepr&uuml;fungen
vornimmt und einfache Suchm&ouml;glichkeiten anbietet. Zudem sollte die
Ablauf- oder Gesch&auml;ftslogik unter der Oberfl&auml;che verborgen sein und
nicht vom Benutzer selber beachtet werden m&uuml;ssen („Immer, wenn ein
Kunde mehr als _ 10.000 Umsatz pro Jahr macht, erh&auml;lt er automatisch
3% Rabatt.“).
Das Programm kann MySQL einem nat&uuml;rlich nicht zur Verf&uuml;gung stellen. Daf&uuml;r ist der Applikationsentwickler selber verantwortlich. Aber
um auf die Datenbank zugreifen zu k&ouml;nnen, ben&ouml;tigt er Schnittstellen.
Es gibt sie f&uuml;r die verschiedensten Programmiersprachen. Ich m&ouml;chte
hier die am h&auml;ufigsten genutzten vorstellen: Perl und C++ sowie allgemeiner und sprachunabh&auml;ngiger MyODBC. PHP wird auch sehr h&auml;ufig
6FKQLWWVWHOOHQ
f&uuml;r die Anbindung eines Web-Servers an eine MySQL-Datenbank genutzt. Da es daf&uuml;r aber ein eigenes Kapitel gibt, werde ich hier nicht n&auml;her darauf eingehen.
5.5.1 Perl
Perl ist eine ideale interpretierende Programmiersprache, um kleine
(und auch gr&ouml;&szlig;ere) Skripten zu schreiben. Sie sind schnell erstellt, trotzdem aber auch flexibel und vor allem die F&auml;higkeiten zur Zeichenkettenverarbeitung sind sehr umfangreich. Die zentrale Stelle f&uuml;r Perl im
Internet ist http://www.perl.com. W&auml;hrend unter Linux und anderen
Unix-Derivaten Perl meist schon vorhanden ist, muss man es sich unter
Windows erst installieren. Daf&uuml;r findet man unter http://www.activestate.com/ActivePerl quasi die Perl-Version f&uuml;r Windows.
Auf der beiliegenden CD-ROM finden Sie im Verzeichnis Perl die MSIInstallationsdatei f&uuml;r ActivePerl unter Windows. Der Dateiname lautet
ActivePerl-5.6.1.633-MSWin32-x86.msi.
Der Zugriff auf MySQL mit Perl geschieht &uuml;ber die Schnittstelle DBI.
Dies ist eine universelle Datenbankschnittstelle f&uuml;r Perl und unterst&uuml;tzt
unter anderem auch MySQL. Es gibt noch andere, &auml;ltere Zugriffsvarianten, aber mittlerweile sollte man auf jeden Fall DBI nutzen.
Falls DBI und der MySQL-Zugriff unter Linux noch nicht vorhanden
sind, muss man sich die entsprechenden Module von http://
www.mysql.com/Downloads/Contrib/ herunterladen. Mindestens notwendig sind Data-Dumper, DBI und msql-mysql-modules. Die entsprechenden Dateien Data-Dumper-2.101.tar.gz, DBI-1.18.tar.gz und MsqlMysql_modules-1.2216.tar.gz finden Sie auch auf der beiligenden CDROM im Verzeichnis Perl.
Dabei handelt es sich um komprimierte Tar-Archive, die mittels
prompt&gt; gunzip &lt; MODULE-VERSION.tar.gz | tar xvf -
ausgepackt werden k&ouml;nnen. MODULE-VERSION steht dabei f&uuml;r eines der
aufgef&uuml;hrten Module einschlie&szlig;lich der Versionsbezeichnung.
Danach wechselt man in das entsprechende Verzeichnis des Moduls:
prompt&gt; cd MODULE-VERSION
=XJULIIVP|JOLFKNHLWHQ
Dort baut man die Distribution und kompiliert alles:
prompt&gt;
prompt&gt;
prompt&gt;
prompt&gt;
perl Makefile.PL
make
make test
make install
Zu beachten ist noch, dass make test f&uuml;r msql-mysql-modules nur dann
erfolgreich funktionieren wird, wenn der MySQL-Server l&auml;uft.
Um DBI und die Unterst&uuml;tzung f&uuml;r MySQL unter Windows zu installieren, m&uuml;ssen Sie den PPM (Programmer's Package Manager) von
ActivePerl aufrufen. Er ben&ouml;tigt eine Internetverbindung oder – falls
vorhanden – Zugriff auf ein lokales Repository (wie zum Beispiel die
CD von ActiveState).
prompt&gt;ppm
Nun kann DBI installiert werden:
ppm&gt; install DBI
Ist dies erfolgreich geschehen, kann man die MySQL-Unterst&uuml;tzung
installieren (bitte den folgenden Befehl auf einer Zeile eingeben):
ppm&gt; install ftp
//ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
Mit
ppm&gt; exit
wird der PPM beendet und es steht die DBI und der MySQL-Support
zur Verf&uuml;gung.
Ein einfaches Perl-Programm, welches auf unsere Datenbank zugreift,
sieht so aus:
#! /usr/bin/perl
# mysql01.pl - Einfaches Beispiel zum Verbinden mit MySQL
use DBI;
use strict;
:my ($dsn) = &quot;DBI:mysql:musikschule&quot;; # Verbindungstyp und Datenbankname
my ($user_name);
# Benutzername (hier leer)
my ($password);
# Kennwort (hier leer)
my ($dbh, $sth);
# Verbindungshandle, Query-Handle
my ($query);
# SELECT-Befehl
my (@ary);
# Datensatz
6FKQLWWVWHOOHQ
# Verbindung aufbauen
$dbh = DBI-&gt;connect($dsn, $user_name, $password, {RaiseError =&gt; 1});
#SELECT-Befehl definieren
$query = &quot;SELECT raum_id, raum_name, etage, personen &quot;
.&quot;FROM raum ORDER BY raum_name&quot;;
# Anfrage vorbereiten und ausf&uuml;hren
$sth = $dbh-&gt;prepare($query);
$sth-&gt;execute();
# Spalten&uuml;berschriften ausgeben
print &quot;raum_id\traum_name\tetage\tpersonen\n\n&quot;;
# Schleife &uuml;ber alle Datens&auml;tze
while(@ary = $sth-&gt;fetchrow_array())
{
# Ausgabe des Datensatzes
print join(&quot;\t&quot;, @ary), &quot;\n&quot;;
}
# Freigeben des Query-Handles
$sth-&gt;finish();
# Verbindung beenden
$dbh-&gt;disconnect();
exit(0);
Sie finden das Skript mit dem Dateinamen mysql01.pl auf der beiliegenden CD-ROM.
Ich m&ouml;chte hier nicht die Programmierung mit Perl an sich erkl&auml;ren.
Aber anhand dieses Beispielprogramms will ich auf die Elemente eingehen, die f&uuml;r DBI notwendig sind.
#! /usr/bin/perl
# mysql01.pl - Einfaches Beispiel zum Verbinden mit MySQL
Alle Zeichen hinter einem # werden als Kommentar betrachtet und ignoriert. Die erste Zeile dient unter Unix dazu, bei Aufruf von
prompt&gt; mysql01.pl
direkt den Perl-Interpreter zu starten und das Programm auszuf&uuml;hren.
=XJULIIVP|JOLFKNHLWHQ
use DBI;
use strict;
Mit diesen beiden Befehlen wird der Perl-Interpreter dazu gebracht, das
Modul DBI zu laden, um es sp&auml;ter nutzen zu k&ouml;nnen. Mit use strict wird
daf&uuml;r gesorgt, dass Variablennamen zun&auml;chst deklariert werden m&uuml;ssen, bevor man sie verwenden kann. Das ist zwar nicht unbedingt n&ouml;tig,
aber sehr sinnvoll, um sp&auml;ter nicht ewig nach Fehlern zu suchen, die
darauf beruhen, dass man eine Variable mit $myWonderfulLongVariableName anspricht, die in Wirklichkeit $myWonderfulLongVarName hei&szlig;t
(und dann nat&uuml;rlich keinen sinnvollen Inhalt hat).
my
my
my
my
my
my
($dsn) = &quot;DBI:mysql:musikschule&quot;;
($user_name);
($password);
($dbh, $sth);
($query);
(@ary);
#
#
#
#
#
#
Verbindungstyp und Datenbankname
Benutzername (hier leer)
Kennwort (hier leer)
Verbindungshandle, Query-Handle
SELECT-Befehl
Datensatz
Mit my(...) werden Variablen deklariert. Normale Variablen haben ein $
am Anfang ihres Namens, Arrays ein @. Hier kommen jetzt als Variablennamen verschiedene Bezeichnungen ins Spiel, die h&auml;ufig im Zusammenhang mit DBI verwendet werden:
• $dsn: enth&auml;lt meist die Verbindungsdaten (DSN, Data Source Name),
hier zum Beispiel den Datenbanktyp und den Datenbanknamen.
• $user_name, $password: Diese Variablennamen sprechen wohl f&uuml;r sich.
• $dbh: Ein sogenannter Handle, der als Variable die Verbindung an sich
repr&auml;sentiert. Ihn brauchen wir im Folgenden immer wieder, da er
alle Daten enth&auml;lt, die f&uuml;r die Verbindung notwendig sind.
• $sth: Ein weiterer Handle, der f&uuml;r die Verarbeitung einer Anfrage notwendig ist. Ihm wird der SELECT-Befehl &uuml;bergeben und von ihm erh&auml;lt
man die Ergebnisse.
• $query: Der String, der die eigentliche SQL-Anfrage enth&auml;lt. Es macht
Sinn, den SQL-Befehl in einer eigenen Variable zusammenzubauen,
um sie leichter ausgeben zu k&ouml;nnen, wenn man Probleme mit der
Anfrage hat.
• @ary: Ein Array, in dem der Inhalt eines Datensatzes gespeichert wird.
Die Variable $dsn wird hier gleich mit den notwendigen Verbindungsdaten gef&uuml;llt, die durch den Doppelpunkt getrennt sind. Zun&auml;chst kommt
die Angabe DSI, dann der Datenbanktyp mysql, schlie&szlig;lich der Name der
Datenbank musikschule. Handelt es sich nicht um die Datenbank auf
localhost, kann man zum Schluss (wieder durch einen Doppelpunkt abgeteilt) auch noch den Rechnernamen angeben.
6FKQLWWVWHOOHQ
$dbh = DBI-&gt;connect($dsn, $user_name, $password, {RaiseError =&gt; 1});
Mit diesem Befehl wird die Verbindung zur Datenbank aufgebaut und
der Handle $dbh mit Leben gef&uuml;llt. {RaiseError =&gt; 1} sorgt daf&uuml;r, dass bei
einem Fehler im Verbindungsaufbau das Skript beendet wird und nicht
mit einer Warnung weiterl&auml;uft. Normalerweise wird man sicherlich eine
ausgefeiltere Fehlerbehandlung durchf&uuml;hren, aber wir haben es hier
schlie&szlig;lich nur mit einem einfachen Skript zu tun.
$query = &quot;SELECT raum_id, raum_name, etage, personen &quot;
.&quot;FROM raum ORDER BY raum_name&quot;;
$sth = $dbh-&gt;prepare($query);
$sth-&gt;execute();
Nun wird die Abfrage definiert und der Query-Handle mit prepare(...)
vorbereitet. Danach l&auml;sst er sich mit execute() ausf&uuml;hren.
print &quot;raum_id\traum_name\tetage\tpersonen\n\n&quot;;
Zun&auml;chst werden jetzt die Feldnamen ausgegeben.
while(@ary = $sth-&gt;fetchrow_array())
{
# Ausgabe des Datensatzes
print join(&quot;\t&quot;, @ary), &quot;\n&quot;;
}
Nun wird in einer Schleife so lange die Methode fetchrow_array() aufgerufen, bis sie keine Ergebnisse mehr zur&uuml;ckliefert. Diese Methode liest
den aktuellen Datensatz aus, gibt die Werte der Spalten in einem Array
zur&uuml;ck und springt dann zu n&auml;chsten Datensatz. Handelt es sich dabei
um den letzten Satz, wird beim n&auml;chsten Aufruf ein leeres Array zur&uuml;ckgegeben. Es gibt noch weitere Befehle zum Auslesen von Datens&auml;tzen,
zum Beispiel fetchrow_arrayref(), fetch() und fetchrow_hashref(), die in
anderen Situationen einsetzbar sind.
print join(&quot;\t&quot;, @ary) gibt die einzelnen Elemente des Arrays durch Ta-
bulatorzeichen getrennt aus.
$sth-&gt;finish();
$dbh-&gt;disconnect();
exit(0);
finish() gibt die Ressourcen wieder frei, die der Query-Handle ben&ouml;tigt
hat. disconnect() trennt die Verbindung zur Datenbank und exit(0)
schlie&szlig;lich beendet das Programm mit einem normalen Code.
=XJULIIVP|JOLFKNHLWHQ
Ruft man dieses Programm jetzt auf (zum Beispiel mit perl mysql01.pl),
erh&auml;lt man folgende Ausgabe:
prompt&gt;perl mysql01.pl
raum_id raum_name
etage
4
5
1
2
3
A5.21
A5.23
A5.33
B2.02
C4.16
5
5
5
2
4
personen
6
6
4
20
11
M&ouml;chte man Befehle ausf&uuml;hren, die im Allgemeinen keine Ergebnismenge zur&uuml;ckliefern, kann man statt execute() die Methode do(...)des
Verbindungshandles $dbh nutzen. Mit ihr lassen sich zum Beispiel UPDATE, DELETE und INSERT ausf&uuml;hren. Hier wieder ein kleines Beispielskript:
#! /usr/bin/perl
# mysql02.pl - Einfaches Beispiel zum Ausf&uuml;hren von DML-Befehlen
use DBI;
use strict;
:my ($dsn) = &quot;DBI:mysql:musikschule&quot;; # Verbindungstyp und Datenbankname
my ($user_name);
# Benutzername (hier leer)
my ($password);
# Kennwort (hier leer)
my ($dbh);
# Verbindungshandle
my ($query);
# SELECT-Befehl
my ($rows);
# Anzahl der betroffenen Zeilen
# Verbindung aufbauen
$dbh = DBI-&gt;connect($dsn, $user_name, $password, {RaiseError =&gt; 1});
# UPDATE ausf&uuml;hren
$rows = $dbh-&gt;do(&quot;UPDATE raum SET personen = 9 WHERE raum_id = 2&quot;);
# Verbindung beenden
$dbh-&gt;disconnect();
exit(0);
Sie finden das Skript mit dem Dateinamen mysql02.pl auf der beiliegenden CD-ROM.
do(...) liefert die Menge der betroffenen Zeilen zur&uuml;ck, wobei allerdings
INSERT, UPDATE und DELETE immer 0E0 vermelden. Bei einem Fehler w&uuml;rde
dagegen der Wert undef ausgegeben werden.
6FKQLWWVWHOOHQ
Richtig nett wird es nat&uuml;rlich, wenn man die SQL-Befehle selber zusammenbaut. Dann kann man zum Beispiel folgendes Skript schreiben, welches einen Tabellennamen als Parameter enth&auml;lt und den Inhalt dieser
Tabelle ausgibt:
#! /usr/bin/perl
# mysql03.pl table_name - Einfaches Beispiel zum Anzeigen von Tabellen
use DBI;
use strict;
my
my
my
my
my
my
($dsn) = &quot;DBI:mysql:musikschule&quot;;
($user_name);
($password);
($dbh, $sth);
($query);
(@ary);
#
#
#
#
#
#
Verbindungstyp und Datenbankname
Benutzername (hier leer)
Kennwort (hier leer)
Verbindungshandle, Query-Handle
SELECT-Befehl
Datensatz
# Verbindung aufbauen
$dbh = DBI-&gt;connect($dsn, $user_name, $password, {RaiseError =&gt; 1});
#SELECT-Befehl definieren
$query = &quot;SELECT * FROM &quot;.$ARGV[0];
# Anfrage vorbereiten und ausf&uuml;hren
$sth = $dbh-&gt;prepare($query);
$sth-&gt;execute();
# Spalten&uuml;berschriften ausgeben
print join(&quot;\t&quot;, @{$sth-&gt;{NAME}}), &quot;\n&quot;;
# Schleife &uuml;ber alle Datens&auml;tze
while(@ary = $sth-&gt;fetchrow_array())
{
# Ausgabe des Datensatzes
print join(&quot;\t&quot;, @ary), &quot;\n&quot;;
}
# Freigeben des Query-Handles
$sth-&gt;finish();
# Verbindung beenden
$dbh-&gt;disconnect();
exit(0);
=XJULIIVP|JOLFKNHLWHQ
Sie finden das Skript mit dem Dateinamen mysql03.pl auf der beiliegenden CD-ROM.
Hier haben wir die $query zusammengesetzt, um mit $ARGV[0] den Namen
der Tabelle einbauen zu k&ouml;nnen. Nat&uuml;rlich muss man eigentlich noch
Fehlerbehandlungsroutinen einbauen…
Interessant ist noch die folgende Zeile:
print join(&quot;\t&quot;, @{$sth-&gt;{NAME}}), &quot;\n&quot;;
$sth-&gt;{NAME} liefert eine Referenz auf ein Array zur&uuml;ck (die dann mit
@{...} aufgel&ouml;st wird), in der die Namen der zur&uuml;ckgegebenen Spalten
stehen. Somit kann man hier unabh&auml;ngig von der Tabelle die Spaltennamen ausgeben lassen:
prompt&gt;perl mysql03.pl instrument
instrument_id instr_name
instr_gruppe
1
Querfl&ouml;te
Holzbl&auml;ser
2
Klarinette
Holzbl&auml;ser
3
Violine Streicher
4
Viola Streicher
5
Posaune Blechbl&auml;ser
6
Trompete
Blechbl&auml;ser
7
Klavier Tasten
8
Keyboard
Tasten
Um eine SQL-Abfrage universell verwendbar zu machen, gibt es (haupts&auml;chlich) zwei verschiedene Varianten: der jeweilige Aufbau eines SQLBefehls oder die Verwendung von Platzhaltern:
• Die erste Variante haben wir im Prinzip schon kennengelernt: innerhalb des Abfrage-Strings wird eine Variable genutzt:
$query = &quot;SELECT * FROM schueler WHERE nachname LIKE '$name'&quot;;
$sth = $dbh-&gt;prepare($query);
$sth-&gt;execute();
$name wird von Perl innerhalb von doppelten Anf&uuml;hrungszeichen
durch den Inhalt der Variablen ersetzt. M&ouml;chte man doppelte Anf&uuml;hrungszeichen innerhalb des SQL-Befehls nutzen, muss man sie durch
ein Fluchtzeichen (\) maskieren:
$query = &quot;SELECT * FROM lehrer WHERE plz = \&quot;$plz\&quot;&quot;;
Eleganter und weniger fehleranf&auml;llig ist die Verwendung von qq{}. Alles zwischen den geschweiften Klammern (f&uuml;r die man im &Uuml;brigen
auch andere Zeichen wie // oder () nutzen kann, die allerdings h&auml;ufiger selbst in Strings vorkommen) wird dann als Zeichenkette interpre-
6FKQLWWVWHOOHQ
tiert und so ausgewertet, als ob es von doppelten Anf&uuml;hrungszeichen
umschlossen w&auml;re. Man muss sich dabei aber keine Gedanken um das
Maskieren der Anf&uuml;hrungszeichen machen:
$query = qq{SELECT * FROM lehrer WHERE plz = &quot;$plz&quot;};
Die zweite Variante ist etwas aufw&auml;ndiger. Daf&uuml;r erm&ouml;glicht sie die
mehrfache Verwendung von SQL-Befehlen mit verschiedenen Werten, ohne dass der Befehl vom Server neu analysiert werden m&uuml;sste.
Das spart Zeit, wenn man h&auml;ufig gleiche Anfragen, nur mit unterschiedlichen Werten ausgestattet, schickt. Allerdings ist dieser Vorteil
bei MySQL gerade nicht gegeben, da MySQL die SQL-Befehle nicht f&uuml;r
eine sp&auml;tere Verwendung zwischenspeichert. Es kann sich aber trotzdem anbieten, den Zugriff auf diese Weise zu realisieren, falls man sp&auml;ter einmal auch auf andere Datenbanksysteme zugreifen m&ouml;chte.
Will man Platzhalter nutzen, verwendet man an Stelle der Werte das
Fragezeichen im SQL-Befehl:
$query = &quot;SELECT * FROM schueler WHERE nachname = ? AND vorname = ?&quot;;
$sth = $dbh-&gt;prepare($query);
Bei der Ausf&uuml;hrung des Befehls werden execute() nun die entsprechenden Parameter in der angegebenen Reihenfolge mitgegeben:
$sth-&gt;execute(&quot;Schmidt&quot;, &quot;Thomas&quot;);
Platzhalter lassen sich auch f&uuml;r die Ausgabe verwenden. So kann man
die Ergebnisspalten direkt mit Variablen verkn&uuml;pfen, die dann bei jedem fetch automatisch mit den aktuellen Werten gef&uuml;llt werden. Das
folgende Skript gibt die Adressen aller Sch&uuml;ler aus, deren Nachname
mit den als Parameter &uuml;bergebenen Buchstaben beginnt:
#! /usr/bin/perl
# mysql04.pl lastname - Einfaches Beispiel zum Verkn&uuml;pfen von
#
Platzhaltern
use DBI;
use strict;
my
my
my
my
my
my
my
($dsn) = &quot;DBI:mysql:musikschule&quot;; # Verbindungstyp und Datenbankname
($user_name);
# Benutzername (hier leer)
($password);
# Kennwort (hier leer)
($dbh, $sth);
# Verbindungshandle, Query-Handle
($query);
# SELECT-Befehl
($queryname) = $ARGV[0];
# Filterkriterium
($lastname, $firstname, $street, $plz, $city); # Ausgabevariablen
=XJULIIVP|JOLFKNHLWHQ
# Anf&uuml;gen eines Prozentzeichens, um immer auch nach Namensst&uuml;cken suchen
# zu k&ouml;nnen
$queryname = $queryname.&quot;%&quot;;
# Verbindung aufbauen
$dbh = DBI-&gt;connect($dsn, $user_name, $password, {RaiseError =&gt; 1});
#SELECT-Befehl definieren
$query = &quot;SELECT nachname, vorname, strasse, plz, ort &quot;
.&quot;FROM schueler WHERE nachname LIKE ?&quot;;
# Anfrage vorbereiten und ausf&uuml;hren
$sth = $dbh-&gt;prepare($query);
$sth-&gt;execute($queryname);
# Ausgabespalten mit Variablen verbinden
$sth-&gt;bind_col(1, \$lastname);
$sth-&gt;bind_col(2, \$firstname);
$sth-&gt;bind_col(3, \$street);
$sth-&gt;bind_col(4, \$plz);
$sth-&gt;bind_col(5, \$city);
# Schleife &uuml;ber alle Datens&auml;tze
print &quot;$firstname $lastname\n$street\n$plz $city\n\n&quot;
while $sth-&gt;fetch();
# Freigeben des Query-Handles
$sth-&gt;finish();
# Verbindung beenden
$dbh-&gt;disconnect();
exit(0);
Sie finden das Skript mit dem Dateinamen mysql04.pl auf der beiliegenden CD-ROM.
Entscheidend f&uuml;r die Ausgabebindung ist hier der Befehl
bind_col(...). Er sorgt daf&uuml;r, dass die angegebenen Variablen mit der
entsprechenden Ausgabespalte der Abfrage verbunden werden. Alternativ kann man auch alle Variablen auf einmal verbinden, indem
man den Befehl bind_columns(...) nutzt:
$sth-&gt;bind_columns(\$lastname, \$firstname, \$street, \$plz, \$city);
Wichtig ist noch, dass bind_col(...) bzw. bind_columns(...) erst nach
execute(...) ausgef&uuml;hrt wird.
6FKQLWWVWHOOHQ
5.5.2 C++
Um mittels der Programmiersprache C++ auf MySQL zugreifen zu k&ouml;nnen, ben&ouml;tigt man MySQL++, die entsprechende API von MySQL. Sie
bietet eine umfassende Klassenstruktur, die man &auml;hnlich nutzen kann
wie andere Klassen der STL (Standard Template Library) von C++. Man
kann mit MySQL++ sehr einfache und gut lesbare Programme schreiben, aber sie bietet eigentlich auch alles an, was man in irgendeiner
Form f&uuml;r den Zugriff und die Kommunikation mit MySQL ben&ouml;tigt.
MySQL++ findet man auf den Web-Seiten von MySQL im ContribBereich (http://www.mysql.com/Downloads/Contrib/).
Die ben&ouml;tigten Dateien f&uuml;r Red Hat Linux und Windows (Borland und
Visual C++) finden Sie auch auf der beiliegenden CD-ROM im Verzeichnis MySQL++.
Ein einfaches Beispiel f&uuml;r den Zugriff auf MySQL ist das folgende Programm, welches den Beispielen von MySQL++ entnommen und f&uuml;r die
Musikschule leicht modifiziert wurde:
// mysql01.cpp
// Ausgabe von Daten
#include
#include
#include
#include
&lt;windows.h&gt;
&lt;iostream&gt;
&lt;iomanip&gt;
&lt;sqlplus.hh&gt;
int main() {
try {
Connection con(&quot;musikschule&quot;);
// Erstellen eines Query-Objektes, welches mit con verbunden ist
Query query = con.query();
// Definieren der Abfrage
query &lt;&lt; &quot;select * from raum&quot;;
// Ausf&uuml;hren der Query und R&uuml;ckgabe des Ergebnisses
Result res = query.store();
// Anzahl der Datens&auml;tze
cout &lt;&lt; &quot;Records Found: &quot; &lt;&lt; res.size() &lt;&lt; endl &lt;&lt; endl;
Row row;
=XJULIIVP|JOLFKNHLWHQ
// &Uuml;berschrift
cout.setf(ios::left);
cout &lt;&lt; setw(10) &lt;&lt; &quot;raum_id&quot;
&lt;&lt; setw(20) &lt;&lt; &quot;raum_name&quot;
&lt;&lt; setw(7) &lt;&lt; &quot;etage&quot;
&lt;&lt; &quot;personen&quot; &lt;&lt; endl
&lt;&lt; endl;
// Iterator &uuml;ber die Ergebnismenge
Result::iterator i;
for (i = res.begin(); i != res.end(); i++) {
row = *i;
// Ausgabe der Daten
cout &lt;&lt; setw(10) &lt;&lt; row[0]
&lt;&lt; setw(20) &lt;&lt; row[1]
&lt;&lt; setw(7) &lt;&lt; row[&quot;etage&quot;]
&lt;&lt; row[3] &lt;&lt; endl;
}
}
catch (BadQuery er) {
// Abfangen aller Fehler (au&szlig;er s.u.)
cerr &lt;&lt; &quot;Error: &quot; &lt;&lt; er.error &lt;&lt; endl;
return -1;
}
catch (BadConversion er) {
// Konvertierungs-Fehler
cerr &lt;&lt; &quot;Error: Tried to convert \&quot;&quot; &lt;&lt; er.data &lt;&lt; &quot;\&quot; to a \&quot;&quot;
&lt;&lt; er.type_name &lt;&lt; &quot;\&quot;.&quot; &lt;&lt; endl;
return -1;
}
return 0;
}
Sie finden den Quelltext mit dem Dateinamen mysql01.cpp auf der beiliegenden CD-ROM.
Kurz die einzelnen Schritte erl&auml;utert:
Connection con(&quot;musikschule&quot;);
Hiermit wird ein Objekt con erzeugt, welches eine Verbindung zu einer
Datenbank aufbaut. Es lassen sich neben dem Namen der Datenbank
die &uuml;blichen Verbindungsparameter mit angeben.
Query query = con.query();
query &lt;&lt; &quot;select * from raum&quot;;
Result res = query.store();
6FKQLWWVWHOOHQ
Mittels con.query() wird ein Query-Objekt erzeugt, welches seine Anfragen &uuml;ber die Verbindung con stellt. Dieses Objekt wird dann &uuml;ber &lt;&lt; mit
einem SQL-Befehl gef&uuml;llt und &uuml;ber store() ausgef&uuml;hrt. Letztere Funktion
liefert eine Ergebnismenge vom Typ Result zur&uuml;ck.
cout &lt;&lt; &quot;Records Found: &quot; &lt;&lt; res.size() &lt;&lt; endl &lt;&lt; endl;
res.size() liefert die Anzahl der Datens&auml;tze zur&uuml;ck, die die Abfrage erge-
ben hat.
Row row;
Result::iterator i;
for (i = res.begin(); i != res.end(); i++) {
row = *i;
Eine Row kann die Daten eines Datensatzes enthalten. Um alle Datens&auml;tze der Ergebnismenge ausgeben zu k&ouml;nnen, nutzt man einen Iterator
vom Typ Result::iterator.
cout &lt;&lt;
&lt;&lt;
&lt;&lt;
&lt;&lt;
setw(10) &lt;&lt; row[0]
setw(20) &lt;&lt; row[1]
setw(7) &lt;&lt; row[&quot;etage&quot;]
row[3] &lt;&lt; endl;
Auf die einzelnen Elemente einer Zeile kann man entweder &uuml;ber die Position der Spalte im Datensatz oder &uuml;ber den Namen der Spalte zugreifen.
catch (BadQuery er) {
cerr &lt;&lt; &quot;Error: &quot; &lt;&lt; er.error &lt;&lt; endl;
return -1;
}
catch (BadConversion er) {
cerr &lt;&lt; &quot;Error: Tried to convert \&quot;&quot; &lt;&lt; er.data &lt;&lt; &quot;\&quot; to a \&quot;&quot;
&lt;&lt; er.type_name &lt;&lt; &quot;\&quot;.&quot; &lt;&lt; endl;
}
BadQuery und BadConversion sind Exceptions, die bei entsprechenden Fehlern geworfen werden.
Als Ergebnis erh&auml;lt man eine &uuml;bersichtliche Tabelle mit allen R&auml;umen:
prompt&gt;mysql01
Records Found: 5
raum_id
raum_name
etage personen
1
2
3
4
5
A5.33
B2.02
C4.16
A5.21
A5.23
5
2
4
5
5
=XJULIIVP|JOLFKNHLWHQ
4
9
11
6
6
Ein anderes Beispiel zeigt den Zugriff auf die Metadaten einer Abfrage:
// mysql02.cpp
// Ausgabe von Meta-Daten
#include
#include
#include
#include
&lt;windows.h&gt;
&lt;iostream&gt;
&lt;iomanip&gt;
&lt;sqlplus.hh&gt;
int main() {
try {
Connection con(use_exceptions);
con.connect(&quot;musikschule&quot;);
Query query = con.query();
query &lt;&lt; &quot;SELECT * FROM schueler&quot;;
Result res = query.store();
cout &lt;&lt; &quot;Records Found: &quot; &lt;&lt; res.size() &lt;&lt; endl &lt;&lt; endl;
cout.setf(ios::left);
for (unsigned int i
cout &lt;&lt; setw(3)
&lt;&lt; setw(15)
&lt;&lt; setw(25)
&lt;&lt; endl;
}
= 0; i &lt; res.names().size(); i++) {
&lt;&lt; i
&lt;&lt; res.names(i).c_str()
&lt;&lt; res.types(i).sql_name()
cout &lt;&lt; endl;
return 0;
}
catch (BadQuery er) {
cerr &lt;&lt; &quot;Error: &quot; &lt;&lt; er.error &lt;&lt; endl;
return -1;
}
catch (BadConversion er) {
cerr &lt;&lt; &quot;Error: Tried to convert \&quot;&quot; &lt;&lt; er.data &lt;&lt; &quot;\&quot; to a \&quot;&quot;
&lt;&lt; er.type_name &lt;&lt; &quot;\&quot;.&quot; &lt;&lt; endl;
return -1;
}
}
Sie finden den Quelltext mit dem Dateinamen mysql02.cpp auf der beiliegenden CD-ROM.
6FKQLWWVWHOOHQ
Hier sei besonders auf die Nutzung der Elemente von Result hingewiesen:
for (unsigned int i
cout &lt;&lt; setw(3)
&lt;&lt; setw(15)
&lt;&lt; setw(25)
&lt;&lt; endl;
= 0; i &lt; res.names().size(); i++) {
&lt;&lt; i
&lt;&lt; res.names(i).c_str()
&lt;&lt; res.types(i).sql_name()
res.names(...).c_str() gibt Zugriff auf die Spaltennamen der Ergebnismenge, w&auml;hrend res.types(...).sql_name() die Spaltentypen von MySQL
ausgibt.
Das Ergebnis lautet dann:
prompt&gt;mysql02
Records Found: 5
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
schueler_id
nachname
vorname
geburtsdatum
strasse
plz
ort
telefon
mobil
email
einzug
bankname
blz
kontonr
kontoname
geschlecht
INT UNSIGNED NOT NULL
VARCHAR NOT NULL
VARCHAR NULL
DATE NULL
VARCHAR NULL
VARCHAR NULL
VARCHAR NULL
VARCHAR NULL
VARCHAR NULL
VARCHAR NULL
TINYINT NULL
VARCHAR NULL
VARCHAR NULL
VARCHAR NULL
VARCHAR NULL
TINYINT NULL
Auch bei MySQL++ gibt es die M&ouml;glichkeit, mit Platzhaltern zu arbeiten.
Darauf will ich hier aber nicht weiter eingehen, sondern verweise auf
die Dokumentation, die zu MySQL++ auf den Web-Seiten von MySQL
zu finden ist. Sie enth&auml;lt noch einige weitere Beispiele, die zeigen, wie
man die C++-API sinnvoll nutzen kann.
5.5.3 MyODBC
Entwickelt man ein Programm, welches mit einer Datenbank zusammenarbeitet, wird man im Allgemeinen die Schnittstelle verwenden, die zum
Datenbanksystem geh&ouml;rt. Das erm&ouml;glicht eine umfassende Kontrolle der
Kommunikation und ist meistens auch recht performant. M&ouml;chte man
aber ein Programm entwickeln, welches mit m&ouml;glichst vielen verschiede-
=XJULIIVP|JOLFKNHLWHQ
nen Datenbanksystemen zusammenarbeitet, ben&ouml;tigt man eine Zwischenschicht, die die Verbindungen zur Datenbank verwaltet und die
einzelnen SQL-Anweisungen an die Datenbank &uuml;bermittelt.
Solch eine Zwischenschicht ist ODBC (Open Database Connectivity).
Diese Schnittstelle wurde von Microsoft entworfen und dient haupts&auml;chlich dazu, Windows-Programmen die Kommunikation mit Datenbanken (egal ob unter Windows oder Unix) zu erm&ouml;glichen. Mittlerweile gibt es auch unter verschiedenen Unix-Systemen Applikationen,
die mit ODBC laufen, allerdings ist dies ein recht seltener Fall.
Um mit ODBC auf eine Datenbank zugreifen zu k&ouml;nnen, ben&ouml;tigt man
einen entsprechenden ODBC-Treiber f&uuml;r das Datenbank-System, der die
ODBC-Aufrufe in die entsprechenden Anweisungen f&uuml;r die Datenbank
umwandelt. F&uuml;r MySQL gibt es MyODBC, ein Treiber f&uuml;r Windows und
Unix, der einen gro&szlig;en Teil der m&ouml;glichen ODBC-Befehle umsetzt. Da
ODBC f&uuml;r einen Unix-Client sehr selten genutzt wird, werde ich im Folgenden nur auf die Windows-Variante eingehen.
Unterst&uuml;tzt ein Programm ODBC, kann es theoretisch jede Datenbank
ansprechen, die entsprechende Treiber anbietet. Theoretisch deshalb,
weil viele Applikationen dann doch recht spezielle SQL-Befehle einzelner Datenbank-Systeme nutzen oder auf Systemtabellen zugreifen, die
nur in einem einzelnen RDBMS vorkommen. Macht man sich aber die
M&uuml;he, wirklich plattform&uuml;bergreifend zu entwickeln, kann man zum
Beispiel zun&auml;chst mit einer kleinen Datenbank arbeiten, um dann sp&auml;ter auf ein deutlich gr&ouml;&szlig;eres und besser skalierbares System umzusteigen.
MyODBC erh&auml;lt man auf den Web-Seiten von MySQL unter http://
www.mysql.com/downloads/api-myodbc.html. Dort kann man sich eine
komprimierte Datei mit dem Namen myodbc-VERSION-OS.zip herunterladen, wobei VERSION die aktuelle Version ist und OS f&uuml;r das Betriebssystem steht: „win95“ Windows 95, Windows 98 und Windows ME;
„nt“ f&uuml;r Windows NT, Windows 2000 und Windows XP. Diese Datei
packt man aus (zum Beispiel mit WinZIP) und startet das Installationsprogramm SETUP.EXE (siehe Abbildung 5.13).
Die entsprechenden Dateien myodbc-2.50.39-win95.zip und myodbc2.50.39-nt.zip finden Sie auch auf der beiliegenden CD-ROM im Verzeichnis MyODBC.
6FKQLWWVWHOOHQ
Abbildung 5.13: Startbildschirm des Setups von MyODBC
Wenn man die Schaltfl&auml;che Continue anklickt, gelangt man in das
n&auml;chste Fenster (Abbildung 5.14), in dem man das entsprechende Produkt ausw&auml;hlt – hier ist allerdings nur eines verf&uuml;gbar…
Abbildung 5.14: Auswahl des Treibers bei der Installation von MyODBC
=XJULIIVP|JOLFKNHLWHQ
Nach einem kurzen Kopiervorgang erscheint ein Dialog zum Verwalten
der ODBC-Datenquellen (Abbildung 5.15). Mit ihm kann man die automatisch mit eingerichtete MyODBC-Verbindung sample-MySQL zu einem MySQL-Server konfigurieren. Den entsprechenden Dialog (Abbildung 5.16) erreicht man, wenn man auf die Schaltfl&auml;che Setup... klickt.
Die einzelnen Optionen will ich im Folgenden beschreiben:
• Windows DSN-name: Dies ist der Name der ODBC-Verbindung. Er
wird auch in der Liste der Verbindungen angezeigt und &uuml;ber ihn
kann man die Verbindung in anderen Programmen ansprechen.
• MySQL host (name or IP): Der Server, auf dem sich die MySQL-Datenbank befindet. Handelt es sich um den lokalen Rechner, sollte man
hier localhost eintragen, ansonsten den entsprechenden Rechnernamen oder dessen IP-Adresse.
• MySQL database name: Der Name der Datenbank, die angesprochen
werden soll.
• User: Name des Benutzers, der angemeldet werden soll.
• Password: Kennwort des anzumeldenden Benutzers.
• Port (if not 3306): Port, &uuml;ber den der MySQL-Server angesprochen
wird.
• SQL command on connect: SQL-Befehl, der gleich nach dem Verbinden
ausgef&uuml;hrt werden soll.
• Options that affects the behaviour of MyODBC: Optionen, mit denen
man das Verhalten des MyODBC-Treibers steuern kann. In Abh&auml;ngigkeit von der verwendeten Applikation kann es notwendig sein, eine
oder mehrere der angegebenen Optionen zu aktivieren. Um zum Beispiel Daten mit Microsoft Excel weiterzuverarbeiten, empfiehlt es
sich, die Option Return matching rows zu aktivieren. Weitere Optionen
sind unter anderem im Manual von MySQL beschrieben.
Um auch sp&auml;ter die ODBC-Verbindungen konfigurieren zu k&ouml;nnen,
kann man den Windows-eigenen Dialog aufrufen. Unter Windows
2000 zum Beispiel erreicht man ihn &uuml;ber Start/Einstellungen/Systemsteuerung, dort dann unter Verwaltung/Datenquellen (ODBC) (siehe
auch Abbildung 5.17). &Uuml;ber die Schaltfl&auml;che Hinzuf&uuml;gen... (bzw. Add...
bei der Konfigurationsoberfl&auml;che des MyODBC-Installers) gelangt man
in das in Abbildung 5.18 dargestellte Fenster, in dem man einen Treiber
ausw&auml;hlen kann, um eine neue Datenquelle (zum Beispiel f&uuml;r eine andere Datenbank oder einen anderen Server) zu erstellen.
Um zu testen, ob die Verbindung auch richtig eingerichtet ist, gibt es
unter den Installationsdateien von MyODBC das Programm admndemo.exe. Mit diesem Tool lassen sich Verbindungen zu einer ODBCDatenquelle herstellen und SQL-Befehle absetzen.
6FKQLWWVWHOOHQ
Startet man das Tool, &ouml;ffnet sich gleich ein Dialog, in dem man Dateidatenquellen und Computerdatenquellen ausw&auml;hlen kann. Die Dateidatenquellen interessieren hier weniger, daher sollte man gleich auf die
Registerkarte Computerdatenquelle wechseln (siehe Abbildung 5.19).
Dort kann man dann zum Beispiel sample-MySQL ausw&auml;hlen. Nach dem
Verbindungsaufbau steht einem ein Eingabefenster zur Verf&uuml;gung, in
dem man SQL-Befehle ausf&uuml;hren kann (siehe Abbildung 5.20). Dazu
gibt man zum Beispiel einen SELECT-Befehl ein und kann mit (Strg)(E)
oder &uuml;ber den Men&uuml;punkt Command/Execute den Befehl ausf&uuml;hren
(siehe Abbildung 5.21). Wenn man hier Ergebnisse sieht, hat man das
Ziel erreicht und kann die ODBC-Verbindung meist auch mit anderen
Programmen erfolgreich nutzen.
Es gibt noch einige andere Funktionen des Programms admndemo.exe,
die hier aber nicht weiter aufgef&uuml;hrt werden sollen, so zum Beispiel die
M&ouml;glichkeit, sich Datenbank-, Tabellen- und Indexstrukturen ausgeben
zu lassen.
Abbildung 5.15: ODBC-Datenquellen im Installationsprogramm von MyODBC
=XJULIIVP|JOLFKNHLWHQ
Abbildung 5.16: Einstellungsdialog von MyODBC
Abbildung 5.17: ODBC-Datenquellen unter Windows 2000
6FKQLWWVWHOOHQ
Abbildung 5.18: Hinzuf&uuml;gen einer neuen Datenquelle
Abbildung 5.19: Auswahl einer Datenquelle in admndemo.exe
=XJULIIVP|JOLFKNHLWHQ
Abbildung 5.20: Eingabefenster bei admndemo.exe
Abbildung 5.21: Erfolgreiche ODBC-Verbindung mit admndemo.exe
6FKQLWWVWHOOHQ
5.6
Fragen
1. Wie kann man sich in regelm&auml;&szlig;igen Abst&auml;nden Status&auml;nderungen
anzeigen lassen?
2. Auf welchem Weg l&auml;sst sich eine Datenbank komplett auf einen an-
deren Server transportieren?
3. &Uuml;ber welches Modul sollte man in Perl eine MySQL-Datenbank an-
sprechen?
4. Wie kann man in mysql die Befehle und Ausgaben aufzeichnen?
=XJULIIVP|JOLFKNHLWHQ
Herunterladen