MyISAM vs. InnoDB – was ist besser?

Diese Frage lässt sich eigentlich nicht beantworten, denn wie es sooft der Fall ist (z.B. auch bei Windows vs. Linux vs. Mac), haben beide Systeme ihre Vorteile und je nachdem, was man gerade braucht, nutzt man besser MyISAM oder InnoDB. Aber woher weiß man, welches der beiden MySQL-Storage-Engines man braucht? Dazu muss man wissen, welche Vorteile und Nachteile die Systeme haben. Ich habe dazu mal einiges an Wissen zusammengetragen.

Eigenschaften von InnoDB

  • Referentielle Integrität wird automatisch eingehalten
    • Das muss zuvor explizit festgelegt werden
  • SELECT wird schneller ausgeführt
    • INSERT und UPDATE ist dafür langsamer
  • Schreibzugriffe auf Datensätze können gesperrt werden

Eigenschaften MyISAM

  • Häufiger genutzt und gängigster Standard (hohe Stabilität)
  • INSERT und UPDATE werden schneller ausgeführt als bei InnoDB
    • SELECT ist dafür langsamer
  • Integrierte Volltextsuche
  • Schreibzugriffe nur auf ganze Tabellen

Wann setzt man InnoDB ein?

InnoDB eignet sich vor allem bei großen Datenbanken, wo viele Daten miteinander verknüpft sind. Wenn hier Daten gelöscht werden, löscht InnoDB alle referenzierten Daten automatisch mit. Das macht es der Anwendung hinter der Datenbank leichter, die referentielle Integrität einzuhalten.
Prominente Beispiele für Web-Anwendungen mit InnoDB sind unter anderem:

Wann setzt man MyISAM ein?

Bei kleinen Datenbanken oder Anwendungen, wo viel und oft Daten geändert werden. Hier ist MyISAM deutlich performanter, weil INSERT und UPDATE schneller sind. Und natürlich wenn man Texte durchsuchen möchte (Volltextsuche).
Prominente Beispiele für Web-Anwendungen mit MyISAM sind unter anderem:

Und wenn ich beides brauche?
Natürlich ist es möglich, beide Storage Engines für verschiedene Tabellen in der selben Datenbank zu verwenden. So setzt Mediawiki z.B. für die Standard-Suche die MySQL Volltextsuche von MyISAM ein und der Rest der Datenbank verwendet InnoDB.

Schlusswort

Es gibt also nicht DIE beste Storage Engine für MySQL. Je nach Verwendungszweck eignet sich InnoDB oder MyISAM besser.
Ich persönlich nutze lieber InnoDB, aber ihr könnt euch nun selbst eine Meinung bilden.

Getter- und Setter-Methoden generieren

Was tun, wenn man eine Klasse mit mehreren Dutzend Member-Variablen hat und keine Lust dazu, für jede einzelne Getter- und Setter-Methoden zu schreiben? Natürlich automatisieren wir das Verfahren. Ich habe dazu drei Möglichkeiten herausgesucht. Da ist bestimmt für jeden etwas dabei.

Möglichkeit 1: Zend Studio
Wer eine lizensierte Version vom Zend Studio besitzt, kann sich hier die Getter und Setter ganz einfach über den Menüpunkt Source und Generate Getters and setters… erstellen lassen.

Möglichkeit 2: Magische Methode __call()
Wem das Zend Studio (verständlicherweise) zu teuer ist, der kann Getter- und Setter-Methoden auch über __call() abfangen und bearbeiten.
Einige halten dies jedoch für unsaubere Programmierung (Ich gehöre nicht dazu).

Möglichkeit 3: Ein eigenes Skript schreiben
Immer wenn es eine Aufgabe gibt, die sich häufig wiederholt, ist es sinnvoll, ein Skript dafür zu schreiben, das uns die Arbeit abnimmt. Wie oft ist es mir schon passiert, dass ich gesagt habe „das mach ich kurz selbst“ und am Ende wäre es viel schneller gewesen, ein Skript für die Aufgabe zu schreiben. Für Getter- und Setter-Methoden eignet sich ebenfalls ein kleines Skript. Meins sieht in etwa so aus:

class MeineKlasse
{
	protected $foo;
	protected $bar;
	protected $fooBar;
}
 
echo '<code>';
$class = new ReflectionClass(new MeineKlasse());
$properties = $class->getProperties();
$phpCode = '';
foreach($properties as $property)
{
	$name = $property->getName();
	if(strpos($name, '_') === 0)
	{
		$name = substr($name, 1);
	}
	$func = ucfirst($name);
	$phpCode .= "\n\npublic function get{$func}()\n";
	$phpCode .= "{\n";
	$phpCode .= "\treturn \$this->{$name};\n";
	$phpCode .= "}\n\n";
	$phpCode .= "public function set{$func}(\${$name})\n";
	$phpCode .= "{\n";
	$phpCode .= "\t\$this->{$name} = \${$name};\n";
	$phpCode .= "}";
}
echo $phpCode;
echo '</code>';

Das Skript nimmt sich die Klasse und lässt sich alle Member-Variablen geben. Anschließend nehme ich den Variablennamen und lasse mir daraus PHP-Code generieren.

Zukünftige Features in PHP 5.4 / PHP 6

Heute wage ich mal einen Blick in die Zukunft von PHP. Demnächst erscheint eine erste Alpha-Version zu PHP 5.4 mit einigen neuen Features. Ein paar der wichtigsten neuen Features möchte ich nun vorstellen. Ob tatsächlich alle der hier aufgeführten Features mit dem Release von PHP 5.4 fertig werden oder ob diese nicht für PHP 6 aufgeschoben werden, steht noch in den Sternen.

Type Hinting

Type Hinting ist eines der am meisten gewünschten Features in PHP. Dabei wird in der Parameterangabe von Funktionen und Methoden auch der Variablentyp mit übergeben. Ob und in welcher Form dieses Feature in einer der zukünftigen PHP Versionen erscheinen wird, muss noch diskutiert werden. Problematisch ist dabei u.a. das Verhalten, wenn ein falscher Typ angegeben wird. Soll ein Fehler ausgegeben werden oder wird die Variable einfach umgewandelt?

function addiere(int $x, int $y)
{
	return $x + $y;
}
 
var_dump(addiere("9", "1"));

Array dereferencing

Mit dieser Funktion lassen sich Array-Angaben direkt hinter einem Funktionsaufruf ausführen.

function getAnyArray()
{
	return array("Apfel", "Birne", "Banane");
}
 
echo getAnyArray()[2]; // Ausgabe: Banane

Aus meiner Sicht ein super nützliches Feature, weil man sich dadurch das Zwischenspeichern in eine Variable und damit eine Zeile Code sparen kann.

UTF-8 / UTF-16

Hier sind sich die PHP-Entwickler noch nicht ganz einig. Man möchte, dass die interne String-Behandlung mit einer der modernen Zeichenkodieriung wie UTF-8 oder UTF-16 arbeitet, aber das bringt viele Probleme mit sich. Außerdem steht noch offen, welche Zeichenkodierung verwendet wird. UTF-8 ist zum gängigen Standard geworden, UTF-16 dagegen würde die Ausführung verlangsamen, weil der Speicherverbrauch größer wird.

Traits (Mehrfache Klassenvererbung)

Mit Traits können Klassen von mehreren Elternklassen die Funktionalitäten erben. Im Moment lässt sich über extends immer nur eine Klasse erweitern.

Hier ein Traits-Beispiel:

trait PKW
{
	public function getGeschwindigkeit()
	{
		return 'xxx';
	}
}
 
abstract class Auto
{
	public function getKmStand()
	{
		return 'xxx';
	}
}
 
class Limousine extends Auto use PKW
{
	// ...
}
 
$meinAuto = new Limousine();
echo $meinAuto-&gt;getGeschwindigkeit();
echo $meinAuto-&gt;getKmStand();