Installation eines LAMP Webservers mit Ubuntu

22 08 2012

Normalerweise nutze ich für meinen Test-Webserver die XAMPP Sammlung, da dieses keinerlei Installation erfordert und das komplette Paket portabel ist, also beispielsweise mit einem USB Stick überall hin mitgenommen und auf einem anderen Computer weiter verwendet werden kann. Trotzdem kann es manchmal von Vorteil sein, die Komponenten direkt zu installieren.

Die Mär, dass eine Installation eines funktionierenden Webservers mit allen wichtigen Komponenten für Testzwecke schwierig sei möchte ich heute ausräumen. Natürlich taugt ein solches System noch nicht für den Produktiveinsatz, sollte also nicht öffentlich an das Netz angebunden werden. Dazu benötigt es noch einigen Feinschliff insbesondere was die Sicherheit gegenüber böswilligen Angriffen angeht.

Im Folgenden wollen wir uns die gebräuchlichste Software installieren. Die wären der Apache Webserver, als Datenbank MySQL sowie die Skriptsprache PHP. Nimmt man dann noch unser Betriebssystem hinzu, wissen wir jetzt auch, wofür LAMP steht, nämlich für Linux, Apache, MySQL, PHP.

Was das genau für Programme sind, was man damit überhaupt anstellen kann, das ist nicht Inhalt dieses Artikels. Hier soll es lediglich um die Installation in Linux gehen. Ein grundsätzliches Verständnis der Materie wird also vorausgesetzt.

Apache
Installieren des Apache Webservers:

sudo apt-get install apache2

Der Server soll nicht von außen erreichbar sein. Deshalb sagen wir Apache, dass er nur auf localhost hören soll. Hierzu bearbeiten wir die ports.conf:

sudo vi /etc/apache2/ports.conf

Listen 80
ändern in
Listen localhost:80

Jetzt können wir unseren Webserver schon testen, indem wir die Adresse http://localhost/ in unsere Browser-Adresszeile eintippen.

Wollen wir Subdomains erstellen, kopieren wir uns das Default-Template aus /etc/apache2/sites-available in eine neue Datei mit dem Namen unseres virtuellen Hosts und editieren diese. Meine Subdomain heißt „ramtatta“, außerdem habe ich den Default-Pfad von /var/www/ noch abgeändert in mein Home-Verzeichnis.

sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ramtatta
sudo vi /etc/apache2/sites-available/ramtatta

<VirtualHost *:80>
   ServerName ramtatta.localhost
   ServerAdmin webmaster@localhost
   DocumentRoot /home/aaaaa/htdocs/RamTatTa
   <Directory /home/aaaaa/htdocs/RamTatTa/>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      # Die folgenden beiden Einträge waren unter Apache 2.2 gültig.
      # Order allow,deny
      # allow from all
      # Für Apache 2.4 müssen diese durch den nachstehenden Eintrag ersetzt werden:
      Require all granted
   </Directory>
   ErrorLog ${APACHE_LOG_DIR}/error.log
   LogLevel warn
   CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Damit die Umleitung funktioniert, müssen wir noch unsere hosts erweitern.
sudo vi /etc/hosts

Hinzufügen dieser Zeile:
127.0.0.1 ramtatta.localhost

Jetzt muss der virtuelle Host noch aktiviert und der Apache durchgestartet werden.
sudo a2ensite
sudo /etc/init.d/apache2 restart

Aufrufen können wir die Subdomain folgendermaßen: http://ramtatta.localhost/

Möchten wir unsere Links mittels mod_rewrite verschönern, so müssen wir dieses ggf. auch erst noch aktivieren.
sudo a2enmod rewrite
sudo /etc/init.d/apache2 restart

PHP
Installieren von PHP:

sudo apt-get install php libapache2-mod-php

Unsere HTML Seiten legen wir per Default in /var/www ab. PHP testen wir, indem wir hier eine Datei index.php mit folgendem Inhalt erzeugen.

vi /var/www/index.php
   <?php
   phpinfo();
   ?>

Laden wir jetzt wieder http://localhost/ im Browser, wird eine Seite mit vielen Informationen zu unserer Serverumgebung dargestellt.

MySQL
Installieren von MySQL. Den de facto Standard zur Administration von MySQL Datenbanken im Web stellt PHPMyAdmin dar. Um uns gleich daran zu gewöhnen, installieren wir das gleich mit.

sudo apt-get install mysql-server php5-mysql phpmyadmin

Ich selbst habe mich selbst an die Software Navicat gewöhnt. Auch in der kostenlosen Version bietet dieses Programm sehr viele schöne Funktionen und ist in seiner Eigenschaft als echtes Programm jederzeit flotter als die Weboberfläche von PHPMyAdmin. Einziges Manko ist, dass es sich eigentlich um Windows-Binaries handelt, das lediglich gebündelt mit der Wine Laufzeitumgebung als Linux-Version angeboten werden.

Auf die Datenbank können wir jetzt also auch zugreifen. Hierzu tippen wir in der Shell

mysql -u root

bzw. laden im Browser die Adresse http://localhost/phpmyadmin.

Eclipse
Einen sehr mächtigen Editor für die Entwicklung unserer PHP Dateien finden wir in Eclipse. Dieser ist grundsätzlich für die Java-Entwicklung gedacht, mit den PHP Development Tools (PDT) können wir diesen aber auch sehr gut für PHP verwenden.

Installation des Grundpaketes für Eclipse:

sudo apt-get install eclipse

Das Programm starten wir und klicken uns durch zur automatischen Installation der PDT:
Help -> Install new software… -> Work with: Indigo Update Site wählen -> Programming Languages -> PHP Development Tools (PDT) -> Installieren

Xdebug
Ein großer Nachteil von PHP ist, dass sich dieses normalerweise nicht wirklich debuggen lässt. Abhilfe schafft die Xdebug Erweiterung. Wir installieren zunächst das Paket.

sudo apt-get install php5-xdebug

Jetzt müssen wir das Binary und die Ini-Datei finden. Dazu aktualisieren wir unsere Datenbank für locate und lassen uns dann den Pfad für die xdebug.so und xdebug.ini ausgeben.

sudo updatedb

locate xdebug.so
/usr/lib/php5/20090626/xdebug.so

locate xdebug.ini
/etc/php5/cli/conf.d/xdebug.ini

Die Ini Datei editieren wir. Normalerweise sollte hier der Pfad für die Binary schon eingetragen sein, wir kontrollieren dies aber zur Sicherheit. Dann tragen wir noch ein paar Variablen ein, mit denen wir Xdebug aktivieren und starten den Apache neu.

sudo vi /etc/php5/cli/conf.d/xdebug.ini
   zend_extension=/usr/lib/php5/20090626/xdebug.so
   xdebug.remote_enable=1
   xdebug.remote_handler=dbgp
   xdebug.remote_mode=req
   xdebug.remote_host=127.0.0.1
   xdebug.remote_port=9000
sudo /etc/init.d/apache2 restart
Advertisements




MySQL Newlines entfernen

18 12 2011

Auf RamTatTa hatte ich einen kleinen Bug, dass ich Leerzeilen am Ende eines Feldes nicht entfernt habe. Da der ein oder andere Reporter gerne noch ein paar Mal Enter drückt am Ende seiner Eingabe wurde die Anzeige teilweise unnötig verlängert. Den Fehler hatte ich im Code schnell behoben, doch was ist mit den bereits in der Datenbank gespeicherten Daten? Die sollen ebenfalls korrigiert werden.

Man könnte mit REPLACE arbeiten, allerdings würden dann sämtliche Newlines gelöscht, auch mitten im Text. Das darf natürlich nicht passieren. Also nutzen wir die eingebaute Funktion TRIM, die allerdings in ihrer Standardfunktionalität lediglich Leerzeichen entfernt. Also müssen wir explizit angeben, dass wir Newlines (\n) gelöscht haben möchten. Mit „both“ geben wir an, dass sowohl Newlines am Anfang wie auch am Ende des Strings entfernt werden sollen. Dies in ein UPDATE verpackt, schreibt gleich wieder die korrigierten Daten in die Datenbank.

Probleme hatte ich dann noch mit der Ersetzung. Weder ein „\n“, noch ein „\r\n“ hat bei mir irgend etwas ersetzt. Erst nachdem ich den Character-Code verwendete, waren die Leerzeilen verschwunden.

update ramtatta_reviews set urls = trim(both char(13) from urls);




CSV Datei aus MySQL Datenbank generiern

12 11 2011

Ich wollte aus der MySQL Datenbank für das RamTatTa Fanzine drei Felder als CSV exportieren. Dafür gab es ein paar Bedingungen.
– Jedes Feld soll in Hochkommata („) eingeschlossen sein
– Felder sollen durch Komma (,) getrennt sein
– Das letzte Feld soll die aus der ID des Datensatzes zusammengebaute URL sein

Das erreiche ich mit folgendem Select:

select concat(
  '"', 
  ifnull(
    replace(band, '"', '""'),
    ""
  ), '","',
  replace(titel, '"', '""'), 
  '","http://www.ramtatta.de/reviews,id-', id, '.html"'
) as csv
from ramtatta_reviews
order by id asc;

 

Diese Befehle kurz erläutert:

concat – Füge alle Ergebnisse zu einer einzigen Zeile zusammen

ifnull – Concat gibt kein Ergebnis zurück, sobald ein Feld NULL enthält, also leer ist. Da das Feld „band“ leer sein kann, ich aber trotzdem alles Andere ausgegeben haben möchte, wandle ich hiermit NULL in Leer („“) um.

replace – Da die Felder mit Hochkommata getrennt sind, würde es zu Problemen führen, falls sich in den Feldern ebensolche befinden. Ein Feld
Sehr „gutes“ Album
würde in der CSV so aussehen:
„Sehr „gutes“ Album“
Damit würde das Feld in der CSV Datei also bei „Sehr “ aufhören. Damit dies nicht geschieht, müssen die Hochkommatas maskiert werden, indem diese verdoppelt werden. Im Endeffekt sähe das dann so aus:
„Sehr „“gutes““ Album“

Diese Datei kann nun in einer Tabellenkalkulation geladen werden. Die Einstellungen für LibreOffice Calc sehen so aus:

Und so sieht das Ergebnis aus:





INDEX command denied to user … for table …

31 08 2011

Eigentlich ist der Update-Prozess beim phpBB Board ganz gut gemacht. Bei meinem heutigen Versuch, ein solches Forum auf den neuesten Stand zu bringen erhielt ich doch ein paar Fehlermeldungen in dieser Form:
Fehler :: INDEX command denied to user 'zwiwwelsupp'@'localhost' for table 'phpbb3_login_attempts'
SQL :: CREATE INDEX att_ip ON phpbb3_login_attempts(attempt_ip, attempt_time)

Zwar heißt es noch, diese Fehler seien nicht kritisch, dies sehe ich allerdings gerade bei höher frequentierten Datenbanken anders. Ein guter Index kann die Zugriffszeiten auf die Tabellen enorm beschleunigen. Deshalb sollte man diesen Fehler nicht einfach so hinnehmen, sondern etwas dagegen tun.

Was ist hier passiert? Ganz einfach, der Hoster verbietet den CREATE INDEX Befehl auf seinen Datenbanken. Warum auch immer, Indexe sind doch eigentlich etwas Gutes. Selbst wenn man diese unsinnig einsetzt, außer seiner Performance kann man damit nichts kaputt machen. Bleibt mir also schleierhaft, weshalb man so etwas sperrt.

Sei es wie es ist, einen Index kann man auch ohne diesen Befehl erzeugen. Dazu nutzt man einfach den ALTER TABLE Befehl, d.h. man bearbeitet die Tabelle derart, dass ein neuer Index hinzugefügt wird. Um den Unterschied zu verdeutlichen:
CREATE INDEX <index_name> ON <tabelle> (<feldname 1>, ..., <feldname n>);
ALTER TABLE <tabelle> ADD INDEX <index_name> (<feldname 1>, ..., <feldname n>);

Für unser obiges Beispiel gäbe das dann also:
ALTER TABLE `phpbb3_login_attempts` ADD INDEX att_ip (`attempt_ip`, `attempt_time`);

Das Ergebnis ist das Selbe:
Index





Überführung einer Word-Tabelle in eine MySQL Datenbank v2

7 10 2007

Vorgegeben war ein Word-Dokument, dessen Inhalte in eine MySQL Datenbank überführt werden sollten. Die Tabellenstruktur war (leider!) vorgegeben, so musste ich mich vor allem mit den Unwägbarkeiten eines für mich absolut nicht nachvollziehbaren Tabellenaufbau arrangieren.

Variante 1 (siehe weiter unten) hat sich doch als zu aufwändig erwiesen. Daher wird die Tabelle jetzt erst korrekt in Excel formatiert. Dann sollte das Einfügen in die Tabelle quasi automatisch ablaufen. Die Tabelle sieht im Aufbau also wie folgt aus (und zwar exakt so, damit die weiteren Schritte funktionieren):

Speichern der Tabelle im CSV Format. Die gespeicherte Datei anschließend mit UEStudio oder einem anderen Tools ins UTF8 Format konvertieren, damit Umlaute korrekt eingefügt werden können (natürlich ist es auch möglich, im phpMyAdmin einfach den korrekten Zeichensatz auszuwählen, war mir nur zu lästig das auszuprobieren…). Diese Schritte gleichen weitestgehend dem Beitrag weiter unten.

Erstellen einer temporären Tabelle in der Datenbank (einmalig).

CREATE TABLE temp (
	autor varchar(80) NOT NULL,
	stueck varchar(150) NOT NULL,
	thema1 varchar(150) DEFAULT NULL,
	thema2 varchar(150) DEFAULT NULL,
	thema3 varchar(150) DEFAULT NULL,
	stichwort1 varchar(90) DEFAULT NULL,
	stichwort2 varchar(90) DEFAULT NULL,
	stichwort3 varchar(90) DEFAULT NULL,
	stichwort4 varchar(90) DEFAULT NULL,
	`alter` varchar(80) DEFAULT NULL,
	ort varchar(80) DEFAULT NULL,
	link varchar(120) DEFAULT NULL
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

Einfügen der mit Excel exportierten CSV Daten über phpMyAdmin. Dazu die Tabelle „temp“ auswählen und bei „Importieren“ die Datei angeben und als Dateiformat CSV selektieren.

Folgende SQL Statements ausführen:

-- Tabelle "angebot" füllen
INSERT INTO angebot SELECT NULL, autor, stueck, ort, link, `alter` FROM temp;

-- Tabelle "stichwort" füllen
CREATE TEMPORARY TABLE temp_stichwort(stichwort varchar(90) DEFAULT NULL) ENGINE=MyISAM;
INSERT INTO temp_stichwort SELECT stichwort1 FROM temp;
INSERT INTO temp_stichwort SELECT stichwort2 FROM temp;
INSERT INTO temp_stichwort SELECT stichwort3 FROM temp;
INSERT INTO temp_stichwort SELECT stichwort4 FROM temp;
INSERT INTO stichwort SELECT NULL, stichwort FROM temp_stichwort WHERE stichwort != '' GROUP BY stichwort ORDER BY stichwort ASC;
DROP TABLE temp_stichwort;

-- Tabelle "themenfeld" füllen
CREATE TEMPORARY TABLE temp_themenfeld(thema varchar(150) DEFAULT NULL) ENGINE=MyISAM;
INSERT INTO temp_themenfeld SELECT thema1 FROM temp;
INSERT INTO temp_themenfeld SELECT thema2 FROM temp;
INSERT INTO temp_themenfeld SELECT thema3 FROM temp;
INSERT INTO themenfeld SELECT NULL, thema FROM temp_themenfeld WHERE thema != '' GROUP BY thema ORDER BY thema ASC;
DROP TABLE temp_themenfeld;

-- Tabelle "zusammen" füllen
INSERT INTO zusammen SELECT angebot.ID, stichwort.IDSTW, '1' FROM angebot, temp, stichwort WHERE temp.stichwort1 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.stichwort1 = stichwort.Stichwort ORDER BY angebot.ID ASC;
INSERT INTO zusammen SELECT angebot.ID, stichwort.IDSTW, '2' FROM angebot, temp, stichwort WHERE temp.stichwort2 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.stichwort2 = stichwort.Stichwort ORDER BY angebot.ID ASC;
INSERT INTO zusammen SELECT angebot.ID, stichwort.IDSTW, '3' FROM angebot, temp, stichwort WHERE temp.stichwort3 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.stichwort3 = stichwort.Stichwort ORDER BY angebot.ID ASC;
INSERT INTO zusammen SELECT angebot.ID, stichwort.IDSTW, '4' FROM angebot, temp, stichwort WHERE temp.stichwort4 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.stichwort4 = stichwort.Stichwort ORDER BY angebot.ID ASC;

-- Tabelle "zusammenth" füllen
INSERT INTO zusammenth SELECT angebot.ID, themenfeld.IDTHE, '1' FROM angebot, temp, themenfeld WHERE temp.thema1 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.thema1 = themenfeld.Thema ORDER BY angebot.ID ASC;
INSERT INTO zusammenth SELECT angebot.ID, themenfeld.IDTHE, '2' FROM angebot, temp, themenfeld WHERE temp.thema2 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.thema2 = themenfeld.Thema ORDER BY angebot.ID ASC;
INSERT INTO zusammenth SELECT angebot.ID, themenfeld.IDTHE, '3' FROM angebot, temp, themenfeld WHERE temp.thema3 != '' AND angebot.autor = temp.autor  AND angebot.stueck = temp.stueck AND temp.thema3 = themenfeld.Thema ORDER BY angebot.ID ASC;

-- Tabelle "temp" leeren
TRUNCATE TABLE temp;

Jetzt können die Daten abgefragt werden um zu prüfen, ob alles korrekt lief. Das SELECT-Statement ist nicht ganz trivial, ich greife auf die Funktion group_concat zurück, um die Stichworte bzw. Themenfelder für die Darstellung in einem Feld zusammenzufügen. Die ganze Sache hätte man sicherlich einfacher halten können, da die maximale Anzahl der Stichworte / Themenfelder fix und durchaus überschaubar ist. Aber die Tabellenstruktur war wie bereits angesprochen leider vorgegeben… Crazy Smilie

Die Themenfelder abfragen:

SELECT
	angebot.Autor,
	angebot.Stueck,
	GROUP_CONCAT(themenfeld.Thema) Thema
FROM angebot
JOIN themenfeld
JOIN zusammenth ON angebot.ID = zusammenth.ID AND themenfeld.IDTHE = zusammenth.IDTHE
GROUP BY angebot.ID
ORDER BY angebot.Autor ASC, angebot.Stueck ASC
LIMIT 0,5;
+---------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+
| Autor                     | Stueck                            | Thema                                                                                                     |
+---------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+
| Aischylos                 | Die Orestie                       | Recht und Gerechtigkeit,Schuld und Sühne                                                                  |
| Albee, Edward             | Wer hat Angst vor Virginia Woolf? | Schuld und Sühne,Selbst- und Fremdbestimmung,Sinn und Sinnverlust                                         |
| Alfano, Franco            | Cyrano de Bergerac (Oper)         | Recht und Gerechtigkeit,Gelingen und Scheitern: Liebesgeschichten,Wirklichkeit und Phantasie: Gegenwelten |
| Alfieri, Richard          | Sechs Tanzstunden in sechs Wochen | Wirklichkeit und Phantasie: Gegenwelten                                                                   |
| Andersen, Hans Christian  | Die Schneekönigin                 | Ohne                                                                                                      |
+---------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+
5 rows in set (0.09 sec)

Die Stichworte abfragen:

SELECT
	angebot.Autor,
	angebot.Stueck,
	GROUP_CONCAT(stichwort.Stichwort) Stichwort
FROM angebot
JOIN stichwort
JOIN zusammen ON angebot.ID = zusammen.ID AND stichwort.IDSTW = zusammen.IDSTW
GROUP BY angebot.ID
ORDER BY angebot.Autor ASC, angebot.Stueck ASC
LIMIT 0,5;
+---------------------------+-----------------------------------+--------------------------------------------------+
| Autor                     | Stueck                            | Stichwort                                        |
+---------------------------+-----------------------------------+--------------------------------------------------+
| Aischylos                 | Die Orestie                       | Recht und Gerechtigkeit,Rache,Griech. Mythologie |
| Albee, Edward             | Wer hat Angst vor Virginia Woolf? | Lebenslügen,Sehnsucht,Beziehungen                |
| Alfano, Franco            | Cyrano de Bergerac (Oper)         | Wahrheit,Verkleidung,Liebe                       |
| Andersen, Hans Christian  | Die Schneekönigin                 | Mut,Freundschaft,Märchen                         |
| Aperghis, George          | Rotkäppchen (Oper)                | Märchen                                          |
+---------------------------+-----------------------------------+--------------------------------------------------+
5 rows in set (0.59 sec)




Überführung einer Word-Tabelle in eine MySQL Datenbank

3 10 2007

Die Problemstellung war, eine Word-Tabelle in eine MySQL Datenbank zu überführen. Nun könnte man alle Daten per Hand in die Datenbank eintippen, was aber einiges an Aufwand bedeutet hätte. Also musste eine möglichst automatisierte Lösung her. Zuerst wurde die Tabelle in Excel per Copy & Paste übertragen, was tatsächlich auch ganz gut funktionierte. Ich habe hier nur OpenOffice Calc zur Verfügung, die weitere Verarbeitung also damit. Das Ergebnis sah so aus:

Diese Daten sollten jetzt in diese Tabellenstruktur. Diese war fest so vorgegeben, hier also leider kein Spielraum die Struktur an die Daten anzupassen.

mysql> describe Angebot;
+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| ID     | int(3)       | NO   | PRI | NULL    | auto_increment |
| Autor  | varchar(80)  | NO   |     |         |                |
| Stueck | varchar(150) | NO   |     |         |                |
| Ort    | varchar(80)  | NO   |     |         |                |
| Link   | varchar(120) | NO   |     |         |                |
| Alter  | varchar(80)  | NO   |     |         |                |
+--------+--------------+------+-----+---------+----------------+

mysql> describe Stichwort;
+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| IDSTW     | int(3)      | NO   | PRI | NULL    | auto_increment |
| Stichwort | varchar(90) | NO   |     |         |                |
+-----------+-------------+------+-----+---------+----------------+

mysql> describe Themenfeld;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| IDTHE | int(3)       | NO   | PRI | NULL    | auto_increment |
| Thema | varchar(150) | NO   |     |         |                |
+-------+--------------+------+-----+---------+----------------+

mysql> describe zusammen;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| ID    | varchar(3) | NO   |     |         |       |
| IDSTW | varchar(4) | NO   |     |         |       |
| NR    | varchar(4) | NO   |     |         |       |
+-------+------------+------+-----+---------+-------+

mysql> describe zusammenth;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| ID    | varchar(3) | NO   |     |         |       |
| IDTHE | varchar(4) | NO   |     |         |       |
| NRTH  | varchar(4) | NO   |     |         |       |
+-------+------------+------+-----+---------+-------+

Los ging es mit den Tabellen „Angebot“, „Stichwort“ und „Themenfeld“. Hierzu fügte ich neue Tabellen in Calc ein und kopierte jeweils die Struktur in die Tabellen, wie von der Datenbank vorgegeben.

Diese Seiten werden jetzt einzeln als CSV exportiert. Als Feldbegrenzer habe ich das Semikolon (;) gewählt.

Die weitere Bearbeitung erfolgte mit dem Texteditor UEStudio ’06. Hier habe ich die CSV Dateien geladen und sortiert. Dabei auch gleich noch alle doppelten Zeilen gelöscht, was besonders bei den Stichworten und Themenfeldern einiges ausmachte. In der Datenbank benötige ich keine Redundanzen und die Sortierung macht die Sache noch etwas übersichtlicher.

So sah die Datei vorher aus:

Jetzt wird sortiert:

Und das Ergebnis:

Diese Daten können so per phpMyAdmin in die Datenbank importiert werden.

mysql> select * from Angebot order by id asc limit 0,3;
+----+----------------+-----------------------------------+-----+------+-------+
| ID | Autor          | Stueck                            | Ort | Link | Alter |
+----+----------------+-----------------------------------+-----+------+-------+
|  1 | Albee, Edward  | Wer hat Angst vor Virginia Woolf? | MA  |      | Ab 12 |
|  2 | Aischylos      | Die Orestie                       | KA  |      | Ab 12 |
|  3 | Alfano, Franco | Cyrano de Bergerac (Oper)         | KA  |      | Ab 12 |
+----+----------------+-----------------------------------+-----+------+-------+

Schwieriger sollte es bei den Verknüpfungstabellen „zusammen“‚ und „zusammenth“‚ werden. Hier mussten erst zwei neue Calc Tabellen erstellt werden… (Alles weitere sind bisher nur Vorüberlegungen)

Erstellen einer Hilfstabelle „temp“:

CREATE TABLE `temp` (
	`id` INT NOT NULL ,
	`Autor` VARCHAR( 255 ) NOT NULL ,
	`Stueck` VARCHAR( 255 ) NOT NULL ,
	`f1` VARCHAR( 255 ) NULL ,
	`f2` VARCHAR( 255 ) NULL ,
	`f3` VARCHAR( 255 ) NULL ,
	`f4` VARCHAR( 255 ) NULL
) ENGINE = MYISAM ;
mysql> describe temp;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id     | int(11)      | NO   |     |         |       |
| Autor  | varchar(255) | NO   |     |         |       |
| Stueck | varchar(255) | NO   |     |         |       |
| f1     | varchar(255) | YES  |     | NULL    |       |
| f2     | varchar(255) | YES  |     | NULL    |       |
| f3     | varchar(255) | YES  |     | NULL    |       |
| f4     | varchar(255) | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+

Die Themen umwandeln in die IDs der Tabelle „themenfeld“. Dies ist mit allen Feldern (fn) durchzuführen.

UPDATE temp, themenfeld
SET temp.f1 = themenfeld.IDTHE
WHERE temp.f1 = themenfeld.Thema;

Die ID des Stücks aus der Tabelle „angebot'“ holen.

UPDATE temp, angebot
SET temp.id = angebot.ID
WHERE temp.Autor = angebot.Autor
AND temp.Stueck = angebot.Stueck;

Die Tabelle zusammenth wird jetzt mit den Werten aus dieser temporären Tabelle gefüllt

INSERT INTO zusammenth
SELECT id, f1, '1'
FROM temp;

INSERT INTO zusammenth
SELECT id, f2, '2'
FROM temp
WHERE f2 != '';

INSERT INTO zusammenth
SELECT id, f3, '3'
FROM temp
WHERE f3 != '';

ALTER TABLE zusammenth ORDER BY ID ASC, NRTH ASC;

Abschließend noch die gesammelten Update Statements:

-- ***** Stichwort *****

-- Daten laden
LOAD DATA LOCAL INFILE '[CVS-Datei]' REPLACE INTO TABLE `temp` FIELDS TERMINATED BY ';' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\r\n';

-- Feldbezeichnung ersetzen durch die ID
UPDATE temp, Stichwort SET temp.f1 = Stichwort.IDSTW WHERE temp.f1 = Stichwort.Stichwort;
UPDATE temp, Stichwort SET temp.f2 = Stichwort.IDSTW WHERE temp.f2 = Stichwort.Stichwort;
UPDATE temp, Stichwort SET temp.f3 = Stichwort.IDSTW WHERE temp.f3 = Stichwort.Stichwort;
UPDATE temp, Stichwort SET temp.f4 = Stichwort.IDSTW WHERE temp.f4 = Stichwort.Stichwort;

-- ID ersetzen
UPDATE temp, Angebot SET temp.id = Angebot.ID WHERE temp.Autor = Angebot.Autor AND temp.Stueck = Angebot.Stueck;

-- Einfügen
INSERT INTO zusammen SELECT id, f1, '1' FROM temp WHERE f1 != '';
INSERT INTO zusammen SELECT id, f2, '2' FROM temp WHERE f2 != '';
INSERT INTO zusammen SELECT id, f3, '3' FROM temp WHERE f3 != '';
INSERT INTO zusammen SELECT id, f4, '4' FROM temp WHERE f4 != '';

-- Leeren der Temp-Tabelle (nur zur Sicherheit)
TRUNCATE TABLE temp;


-- ***** Themenfeld *****

-- Daten laden
LOAD DATA LOCAL INFILE '[CVS-Datei]' REPLACE INTO TABLE `temp` FIELDS TERMINATED BY ';' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\r\n';

-- Feldbezeichnung ersetzen durch die ID
UPDATE temp, Themenfeld SET temp.f1 = Themenfeld.IDTHE WHERE temp.f1 = Themenfeld.Thema;
UPDATE temp, Themenfeld SET temp.f2 = Themenfeld.IDTHE WHERE temp.f2 = Themenfeld.Thema;
UPDATE temp, Themenfeld SET temp.f3 = Themenfeld.IDTHE WHERE temp.f3 = Themenfeld.Thema;

-- ID ersetzen
UPDATE temp, Angebot SET temp.id = Angebot.ID WHERE temp.Autor = Angebot.Autor AND temp.Stueck = Angebot.Stueck;


-- Einfügen
INSERT INTO zusammenth SELECT id, f1, '1' FROM temp WHERE f1 != '';
INSERT INTO zusammenth SELECT id, f2, '2' FROM temp WHERE f2 !='';
INSERT INTO zusammenth SELECT id, f3, '3' FROM temp WHERE f3 !='';




Konvertieren einer MySQL Datenbank ins UTF-8 Unicode Format

8 04 2007

Bisher lief meine Datenbank im latin1_swedish_ci Format, welches als Standard bei MySQL definiert ist, wenn man keine eigenen Einstellungen vornimmt. Nun wollte ich diese auf das universelle UTF-8 Format umstellen. Eine wichtige Quelle hierfür stellt das Kapitel Zeichensatz-Unterstützung in der MySQL Dokumentation dar.

Als ersten Schritt muss die Datenbank an sich umgestellt werden. Das geht noch ganz einfach mit diesem Befehl:

ALTER DATABASE `[DB-Name]` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci

Nun geht es aber darum, auch die einzelnen Felder zu konvertieren. Das kann man umständlich per Hand tun. Da es aber scheinbar keine geeignete Methode gibt, alle Felder auf einmal umzustellen und ich keine Lust hatte mehrere hundert SQL Befehle von Hand zu tippen habe ich mir ein kleines PHP Skript erstellt. Dieses ist sicherlich nicht der Weisheit letzter Schluss, tut aber seinen Dienst.


Hiermit sollte eine Liste mit SQL Befehlen ausgegeben werden, die zum Einen sämtliche Felder, die nicht im UTF-8 Format vorliegen ins UTF-8 Unicode Format konvertiert, zusätzlich aber auch die Standardeinstellungen für die Tabellen anpasst.

Zusätzlich muss der Webseite noch mitgeteilt werden, dass diese jetzt UTF-8 verwendet. Dies erreicht man mit dem folgenden Meta-Tag:


Um die MySQL Verbindung ebenfalls umzustellen, sollte in Skripten direkt nach dem Connect dieses Statement abgesetzt werden:

SET NAMES "utf8"

Bei mir sieht das im PHP so aus:

mysql_query('SET NAMES "utf8"') or die ("Kann den Zeichensatz nicht auf utf-8 stellen");