Im ersten Teil dieser Artikelseite habe ich ausführlich die verschiedenen Methoden zum Aufbau eine Suche mit PHP berichtet:
- Es gibt die ganz einfache direkte Suche mit LIKE über eine oder mehrere Datenbanktabellen
- Man kann über Schlagworte und Kategorien indexieren
- Und natürlich gibt es noch die Volltextindexierung
Die direkte Suche wollte ich erst allen ersparen, habe beim Recherchieren nun aber doch eine Variante entdeckt, die schicker ist, als die die alle einsetzen ;-) Deshalb der Vollständigkeit halber einen kleinen Exkurs zu direkten Suche…
Die gebräuchlichste Variante (ohne Beweise mache ich eine Wette, das sie von den meisten etwa in der Art eingesetzt wird) besteht im Kern aus dem SQL-Stament und sieht für eine imaginäre Kontaktdatenbank etwa so aus:
SELECT `id`, `vorname`, `nachname` FROM `kontakte` WHERE `nachname` LIKE '%suchbegriff%'
Das Statement ist einfach erweiterbar - wenn man zusätzlich den Vornamen durchsuchen möchte, kann man das Stament wie folgt erweitern:
SELECT `id`, `vorname`, `nachname` FROM `kontakte` WHERE `nachname` LIKE '%suchbegriff%' OR `vorname` LIKE '%suchbegriff%'
Einfach, aber nicht sehr sexy. Besonders unübersichtlich wirds, wenn man ziemlich viele Spalten durchsuchen möchte. Ein weiterer Minuspunkt ist die Bool’sche Suche: die funktioniert nur statisch, in dem man das SQL-Statement mit ANDs und ORs spickt und wild mit Klammern verschachtelt.
Was die wenigsten wissen: Seit MySQL 4 bietet MySQL eine ziemlich performante Volltextsuche und eine schicke Schnittstelle um Datensätze wie mit Google zu durchsuchen. Die Schlagworte heissen hier: MATCH … AGAINST! Und so kann es aussehen:
SELECT `id`, `vorname`, `nachname`
FROM `kontakte`
WHERE MATCH(`nachname`)
AGAINST ('suchbegriff')
Das selbe nochmal, nur das nun auch der Vorname durchsucht wird:
SELECT `id`, `vorname`, `nachname`
FROM `kontakte`
WHERE MATCH(`nachname`, `vorname`)
AGAINST ('suchbegriff')
Um zu suchen, wie man es von Google gewohnt ist, nämlich durch den Ausschluss von Worten (mit -) oder das Erzwingen des Vorhandenseins bestimmter Worte (mit +) muss man den Bool’schen Modus aktivieren:
SELECT `id`, `vorname`, `nachname`
FROM `kontakte`
WHERE MATCH(`nachname`, `vorname`)
AGAINST ('+fritz -meier' IN BOOLEAN MODE)
So werden zum Beispiel nur die “Fritz”en gefunden, die nicht “Meier” mit Nachnamen heissen. Sehr praktisch ist die eingebaute Gewichtung. MySQL listet Datensätze automatisch weiter oben, die beide Begriffe enthalten und stuft Datensätze herab, die nur einen der Begriffe enthalten. Je nach Häufigkeit wird ebenfalls differenziert.
Damit die Suche performant abläuft, ist es ratsam MySQL auf einen Volltextindex zugreifen zu lassen. So müssen nicht alle Datensätze beim Suchen gescannt werden und MySQL hat mehr Zeit für andere Datenbank-Aufgaben.
Die Effektivität des Indizes und damit auch der Suche lässt sich übrigens noch durch eine Stoppwortliste steigern. Da MySQL von Haus aus nur mit einer englischen Stoppwortliste ausgestattet ist, ist es ratsam eine deutsche anzulegen. Thomas Schefter hat sich die Mühe gemacht und eine Stoppwortliste für den Einsatz mit MySQL zum Download bereitgestellt.
MySQL wird über die Variable “ft_stopword_file” mit der Stoppwortliste gefüttert. Einen sehr interessanten Artikel über das Finetuning der Volltextsuche gibt es im hauseigenen Nachschlagewerk von MySQL unter dem Namen “MySQL-Volltextsuche feineinstellen“.

















