Dynamische Webseiten mit PHP

Datenbankanbindung und -abfragen

SQL

Die meisten Datenbanken verwenden zur Verwaltung und Abfrage der Datenbank eine standardisierte Abrfagesprache namens SQL (Structured Query Language).

MySQL ist eine dieser Datenbanken, die weitgehend den Standard ANSI SQL92 (Entry Level) bedient. Wie bei professionellen Datnebanken üblich ist MySQL zunächst erst einmal nur eine Datenbankengine, auf die verschiedene Frontends (grafische Darstellungen Datenbank und ihrer Inhalte) aufgesetzt werden können. Mit Hilfe des Frontends lässt sich die Datenbank dann verwalten und abfragen.

Hier ein paar Beispiele für MySQL-Frontends:

  • PHPMyAdmin (Frontend in PHP geschrieben und sehr beliebt)
  • Sequel Pro (Mac)
  • MySQL-Front (Win)


Zusammenspiel von PHP und MySQL

Verbindungsaufbau mit der Datenbank

MySQL wird natürlich durch die Abfragesprache SQL abgefragt. In PHP existiert eine Bibliothek mit Kommandos, die es erlauben, SQL Befehle auszuführen. Bevor das aber möglich ist muß sich PHP zunächst

  • mit der Datenbankengine verbinden (1),
  • dann die Datenbank auswählen (2) und
  • kann dann den SQL-Befehl absetzen (3).

Drei Schritte zur MySQL-Abfrage:

$db = mysql_connect("xy.uni-lukiel:3306", „account“, „pw“);
mysql_select_db(„meineDatenbank“, $db);
$result = mysql_query($mysqlAbfrage,$db);

Dies muß zu Beginn jeder PHP-Seite geschehen, auf der auf die Datenbank zugegriffen werden soll. Wenn sich die Serverdaten ändern, würde das bedeuten, daß alle Seiten korrigiert werden müßten. Daher empfielt sich ein Auslagern der wichtigsten Variablen in eine Config-Datei, die dann in jede Seite eingebunden wird. Das Ändern in dieser Config-Datei hat dann Auswirkungen auf das gesamte Projekt.

Die Config-Datei:

$DbServer = "xy.uni-lukiel:3306"; # MySQL-Server
$DbServerPort = "3306"; # Port
$Db = "meineDatenbank"; # Datenbank
$DbServerUsername = "account"; # Benutzername
$DbServerPassword = "pw"; # Passwort

Das Einbinden der Config-Datei in jedes PHP-Dokument mit Datenbankabfrage würde dann lediglich so aussehen:

include("../inc/config.php");

Was ist PHP, was SQL?

Der PHP Teil der Abrage ist folgender:

$result = mysql_query($mysql,$db);

$mysql ist eine einfache Stringvariable. In diese Variable wird die SQL-Abfrage geschrieben:

$mysql = „select * from tabelle“;

Es ist auch die Einbettung von SQL Abfragen in den PHP-Code möglich:

$result = mysql_query(„select * from tabelle“,$db);

In vielen Frontends ist es möglich reine SQL-Abfragen (also nur „select * from tabelle“) einzugeben und ausführen zu lassen. Das ist manchmal hilfreich, um zu erfahren ob die SQL-Abfrage oder der PHP-Code einen Fehler verursacht.


Basisbefehle

SQL ist aber nicht nur eine Abfragesprache (Query Language), sondern auch eine Manipulationssprache (Data Manipulation Language, DML) zur Speicherung und Veränderung von Informationen und eine Beschreibungssprache (Data Description Language, DDL) zur Definition von Informationstrukturen. (Diemer 1985:18)

Also ist es möglich mit PHP ein vollständiges Frontend für MySQL zu entwickeln (wie PHPMyAdmin das tut).

Befehle für die Datenbank

CREATE DATABASE name
Dient zum Anlegen von Datenbanken.

DROP DATABASE [IF EXISTS] name
Löschen von Datenbanken


Befehle für die Tabelle

CREATE TABLE tname (feld typ [spez. Anweisungen],…)
Anlegen einer Tabelle
DROP TABLE [IF EXISTS] tname
Löschen einer Tabelle
ALTER TABLE tname CHANGE feldalt feldneu typ
ALTER TABLE tname ADD feld typ
Ändern von Tabellen


PRIMARY KEY (id)
Der Primärschlüssel dient zum Auffinden eines Datensatzes in einer Tabelle (id). Er muß

eindeutig sein
er muß kompakt sein, weil a) für ihn ein Index angelegt wird und b) er in anderen Tabellen als Verweis dient.

Daher ist es sinnvoll ihm eine fortlaufende Nummer zu geben:

create table tabellenname (
id INT NOT NULL AUTO_INCREMENT,
…,
PRIMARY KEY (id));

Unique

Wenn eine Spalte nur eindeutige Werte (unique) hat, kann der Index für diese Spalte schneller und efizienter angelegt werden. Ist ein Feld unique verhindert SQL das Einfügen eines Datensatzes, wenn der in diesem Feld keinen eindeutigen Wert hat!

Befehle für die Daten

Diese Abfragen werden naturgemäß am häufigsten benötgt:

Hinzufügen

INSERT INTO tname (feld1, feld2,…) VALUES (wert1, wert2,…)
neuer Datensatz
LOAD DATA INFILE ’pfadangabe’ INTO TABLE tname FIELDS TERMINATED BY ’trennzeichen’ (feld1, feld2,…)

Die mit auto_increment zuletzt erzeugte ID kann mit folgender Konstruktion schnell ermittelt werden:

$neu_id = mysql_insert_id();


Ändern

UPDATE tname SET feld1=wert1, feld2=wert2,… WHERE …
Feldänderung
REPLACE INTO tname (feld1, feld2,…) VALUES (wert1, wert2,…)
ersetzt einen Datensatz wenn der Schlüssel gleich ist, sonst wie INSERT


Löschen

DELETE FROM tname WHERE…
Datensatz löschen

Suchbefehle

Weil die Suche so zentral ist, soll ihnen ein eigener Abschnitt gewährt werden.

(1) SELECT id FROM tname
(2) SELECT id,nname,vname FROM tname
(3) SELECT * FROM tname

(1) Alle ids der Tabelle tname werden zurückgegben.
(2) Die Werte der Felder id,nname,vname der Tabelle tname werden zurückgegben.
(3) Alle Felder der Tabelle tname werden zurückgegben.

SELECT COUNT (feld) FROM tname

Anzahl der Datensätze der Tabelle tname

SELECT feld1, feld2,… FROM tname WHERE...

WHERE
Hinter dem Schlüsselwort WHERE können nun die Einschränkungen definiert werden.

WHERE...

autor='Siegert'
alle Datensätze in denen im Feld autor 'Siegert' steht

autor>‘L‘

Alle Autoren nach L

id IN (2,7,31…)

id muss im set sein

LIMIT n
LIMIT offset,n

die ersten n Datensätze ab offset, beginnend bei 0

LIKE ’%er%’

% ist eine wildcard. Alle Autoren in denen ein „er“ vorkommt, egal ob „Meier“ oder „Siegert“ werden gefunden. Die Suche ist case-sensitive, achtet also auf Gross- und Kleinschreibung. Soll die Gross- und Kleinschreibung ignoriert werden kann mann die Suche folgendermassen durchführen:
SELECT 'A' LIKE UPPER(spalte) FROM tabelle;

Mehrere WHERE-Bedingungen können mit AND verknüpft werden.

ORDER BY feld

Fundstellen werden aufsteigend sortiert, nach dem angegeben Feld.

DESC

... und mit diesem Zusatz absteigend.


GROUP BY / HAVING
Wenn aus einer Literaturdatenbank, in der viele Autoren mehrfach vorkommen, eine Autorenliste generiert werden soll, in der jeder Autor nur einmal auftaucht, dann wird GROUP BY verwendet.

SELECT autor FROM litDB GROUP BY autor

GROUP BY kann in Kombination mit WHERE verwendet werden. Mit der HAVING Klausel kann man sich dann auf die durch GROUP BY erzeugten Gruppen beziehen:

SELECT autor FROM litDB GROUP BY autor HAVING autor>’L’


Umgang mit mehreren Tabellen

Bei der Suche in mehreren Tabellen stellt sich z.B. die Frage welche id denn gemeint ist, die von Tabelle A oder die von Tabelle B. Also muß ma die Felder mit dem Tabellennamen und dem Feldnamen referenzieren. Als Trenner wird ein Punkt gesetzt:

tname.feldname

Eine andere Möglichkeit ist, den Feldern neue Namen für die Ergebnisausgabe zuzuweisen. Eine Technik, die besonders bei den Aggregatfunktionen (s.u.) sinnvoll ist.

Mit AS läßt sich in der Ergebnistabelle ein Feld anlegen:

SELECT artikel.nummer,
artikel.preis AS netto,
artikel.preis * artikel.mwst AS brutto
FROM artikel
			

Ergebnis:

nummer     netto    brutto
111234      10       11.60
735471      20       23,20
			…
			


Ausgangstabellen für die fogenden Beispiele:

band ba_kreuz album label
IDnamelabelid IDbandidalbumid IDtitel idfirma
1 Blondie 1 1 1 2 1 Apostrophe 1 Polydor
2 Zappa 2 2 2 1 2 Parallel Lines 2 Vergin
3 Heaven 17 1 3 3 4 3 Paint and Paint
4 Haircut 100 3 4 4 3 4 The Luxury Gap

Aggregatfunktionen

MySQL kennt eine Reihe von sogenannten Aggregatfunktionen, die aus den Spaltenwerten einer Tabelle bereits bei der Abfrage einen Wert ermitteln.

Folgende Aggregatfunktionen kennt MySQL:

FunktionBeschreibung
count(Spalte) Anzahl der Felder dieser Spalte, die nicht null sind
count(*) Anzahl aller Felder der Spalte
AVG(Spalte) Gibt den Mittelwert der Felder einer Spalte zurück
MIN(Spalte) Gibt den kleinsten Wert der Felder der Spalte zurück
MAX(Spalte) Gibt den größten Wert der Felder der Spalte zurück
SUM(Spalte) Gibt die Summe der Werte der Felder der Spalte zurück
STD(Spalte) Gibt die Standardabweichung zurück

Beispiel:

(-> Ausgangstabellen)


Cross Join

SELECT name, titel FROM band,album

gleichbedeutend mit

SELECT name, titel FROM band CROSS JOIN album

Kreuzverband (=FULL JOIN, vollständiger Verbund): Jeder Datensatz der Tabelle band wird mit der Tabelle album verbunden.
Die Anzahl der Datensätze des Ergebnises ist also das Produkt der Datensätze von band und album (4*4 = 16).

(-> Ausgangstabellen)

Die Verknüpfung wird in der angegebenen Reihenfolge vorgenommen.
Mit der ON Klausel können die Ergebnisse eingeschränkt werden.

(-> Ausgangstabellen)

Left Join

LEFT JOIN (= LEFT OUTER JOIN, qualifizierter äußerer Verbund):
Alle Datensätze der linken Tabelle werden übernommen und kombiniert

(-> Ausgangstabellen)

Right Join

RIGHT JOIN (= RIGHT OUTER JOIN, qualifizierter äußerer Verbund):
Alle Datensätze der rechten Tabelle werden übernommen und kombiniert

(-> Ausgangstabellen)


Unterabfragen

Unterabfragen stehen in Klammern und sich Bestandteil eines übergeordneten SELECT (ab MySQL Version 4.1.0).

SELECT firma FROM label WHERE id=(SELECT MAX(id) FROM band)