Die Flagge des Marasek

Dekostreifen

English

Aktuell Texte Der Comic Impressum Kalender Suche PHP-Klassen Container-Wizard main.s21

Kategorien

Buch
Computer
Computerspiele
Film
Geschichte
Gesellschaft
Idee
Kunst
Natur
Persönlich
Politik
Programmieren
Religion & Philosophie
Weblog
Weltpolitik
Weltsicht
{{login}}

MySQL ist rehabilitiert

Permalink
Vorheriger: Harry Potter und der HalbblutprinzNächster: Frankreich
Eingeordnet in: Computer, Programmieren

Heute habe ich mir die MySQL 5.0 heruntergeladen und installiert, und sofort zwei wichtige Kriterien überprüft.

JOIN mit USING

Frühere MySQL-Versionen scheiterten daran, eine <tabelle1> JOIN <tabelle2> USING <schlüssel> ordentlich hinzubekommen. Der wesentliche Vorteil von join...using gegenüber join ... ON ist, dass es zum einen wesentlich kürzer ist und zum anderen der Schlüssel selbst nicht mehr ambig ist. Nicht so unter MySQL, das USING lediglich als Alias für ein intern zu JOIN ... ON verwendete, ohne zu berücksichtigen, dass der Schlüssel nicht mehr ambig war. Er musste folglich im SELECT-Bereich der Abfrage explizit mit <tabelle1>.<schlüssel> angesprochen werden - lästig.

Das Ergebnis ist sehr gut: es funktioniert. Somit habe ich hier generell den gleichen Komfort wie unter PostgreSQL.

Nested JOINS

Seitdem ich mit Postgresql arbeite, wird normalisiert, was nur sinnvoll normalisiert werden kann, und dem Nutzer als fehlerunträchtiges Dropdown präsentiert. Ein kleines, einleuchtendes Beispiel sind Titel. Eine Person hat einen akademischen Titel (Prof. Dr.), den man zur Anrede verwendet (Sehr geehrter...). Auf einem Brief schreibt man aber gerne eine längere Variante: "Prof. Dr. rer. nat.". Es gibt auch Titel wie "Diplom-Grafikdesigner" oder "Philologe MA", die keinen Anredentitel haben, aber auch ihren Platz auf Visitenkarten finden. Die dümmstmögliche Variante - und ja, ich habe sie sehen müssen - sind zwei Varchar-Felder pro Person, für den langen und den kurzen Titel. Das ist natürlich gruselig; nicht nur, dass man alle möglichen richtig und falsch geschriebenen Varianten von "Filologe MA" wird finden müssen, sondern es kann so natürlich auch vorkommen, dass zwei widersprüchliche Titel eingetragen sind, etwa "Dr." aber "Prof. Dr. rer. nat.". Naheliegend ist es, eine Liste mit Langtiteln zu führen, die Kurztitel implizieren. Dazu erstellt man zwei Tabellen, eine mit Langtiteln, die per Fremdschlüssel mit einer Kurztiteltabelle verbunden ist. Es wird ein "Prof. Dr. rer. nat" erstellt und ihm der "Prof. Dr." zugewiesen. In einer Auswahlliste erscheinen nur die Langtitel, aus denen der eingebende Benutzer einen auswählen kann.

Nehmen wir vier Tabellen an:

Geschlecht

CREATE TABLE "benchmarking"."l_gender" (
"lg_id" int(10) unsigned NOT NULL auto_increment,
"lg_gender" varchar(45) default NULL,
PRIMARY KEY ("lg_id")
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Kurzitel (Anredentitel)

CREATE TABLE "benchmarking"."l_title" (
"lti_id" int(10) unsigned NOT NULL auto_increment,
"lti_title" varchar(45) default NULL,
PRIMARY KEY ("lti_id")
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Langtitel (Brieftitel)

CREATE TABLE "benchmarking"."l_addresstitle" (
"lat_id" int(10) unsigned NOT NULL auto_increment,
"lat_addresstitle" varchar(100) default NULL,
"lti_id" int(10) unsigned default NULL,
PRIMARY KEY ("lat_id"),
KEY "FK_l_addresstitle_1" ("lti_id"),
CONSTRAINT "FK_l_addresstitle_1" FOREIGN KEY ("lti_id") REFERENCES "l_title" ("lti_id")
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Personen

CREATE TABLE "benchmarking"."d_person" (
"dp_id" int(10) unsigned NOT NULL auto_increment,
"dp_name" varchar(45) default NULL,
"dp_surname" varchar(45) default NULL,
"lg_id" int(10) unsigned default NULL,
"lat_id" int(10) unsigned default NULL,
PRIMARY KEY ("dp_id"),
KEY "FK_d_person_1" ("lat_id"),
KEY "FK_d_person_2" ("lg_id"),
CONSTRAINT "FK_d_person_2" FOREIGN KEY ("lg_id") REFERENCES "l_gender" ("lg_id"),
CONSTRAINT "FK_d_person_1" FOREIGN KEY ("lat_id") REFERENCES "l_addresstitle" ("lat_id")
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Ich erstelle zwei Geschlechter, zwei Kurztitel (Prof. Dr. und Dr.) sowie mehrere Langtitel, denen ich passende Kurztitel bzw. gar nichts zuweise. Wenn ich einige Personen eingetragen habe, kann ich mit den Abfragen beginnen:

select dp_name, dp_surname from d_person - für die Personen.
select lg_gender, dp_name, dp_surname from d_person JOIN l_gender USING (lg_id) - das Geschlecht kommt dazu. Ich mache einen Inner Join, da ich davon ausgehe, dass das Frontend das Geschlecht als Pflichtfeld erfordert.
select lat_addresstitle, lg_gender, dp_name, dp_surname from (d_person LEFT JOIN l_addresstitle USING (lat_id)) JOIN l_gender USING (lg_id) - ich nehme den Adresstitel hinzu als LEFT JOIN, da nicht jeder einen Titel hat.
select lat_addresstitle, lg_gender, lti_title, dp_name, dp_surname from (d_person LEFT JOIN (l_addresstitle LEFT JOIN l_title USING (lti_id)) USING (lat_id)) JOIN l_gender USING (lg_id)
Man beachte die Positionierung. l_addresstitle und l_title werden zusammengeführt in einem eigenen Unterbereich, da sie ja thematisch zusammengehören. Mit dem Ergebnis dieser Abfrage als ganzes wird d_person verbunden, und mit diesem Resultat schliesslich l_gender. Diese Abfrage ist sehr übersichtlich und daher weitaus einfacher zu handhaben als eine Abfrage mit JOIN ... ON oder gar WHERE <table1>.<id> = <table2>.<id>.

Frühere Versionen reagierten hier mit einem schnöden #1054 - Unknown column '<datenbank>.l_title.lat_id' in 'on clause' . Aber erst wenn man solche Abfragen formulieren kann, ist man frei, die Datenbank so zu entwerfen, wie es das Konzept einer relationalen Datenbank vorsieht.

Fazit

Mit 5.0 macht MySQL einen gewaltigen Sprung nach vorne, dabei bin ich noch nicht sonderlich auf Views und Stored Procedures eingegangen. Sichten sind vor allem praktisch, um eine grosse Abfrage in mehrere kleine Abfragen zu unterteilen, die nachher zusammengefügt werden oder um einem Frontend SQL-Formulierungsarbeit abzunehmen. Ich verwende Sichten vor allem als vorgefertigte Abfragen, die durch Nutzereingaben parametrisiert werden können.
Obwohl ich zwischendurch sehr frustriert über MySQL war, freut es mich, das MySQL nachgezogen hat, da es meine erste Datenbank war und, naja, nennt mich sentimental, ich daher dafür noch eine gewisse Sympathie hege.
Auch ist MySQL natürlich sehr flexibel, da ich ja durch die Wahl zwischen verschiedenen Storage-Typen den Kompromiss zwischen Geschwindigkeit / Features selbst bestimmen kann.

Kommentieren

Bitte beachten: Kommentare sind nicht sofort sichtbar, sondern werden erst nach einer kurzen Prüfung freigegeben, sofern keine rechtliche Beanstandung vorliegt.
Rechtlich bedenkliche Inhalte werden entweder entschärft oder nicht veröffentlicht.

* Titel  
* Nickname  
* Kommentar