Vergleichsoperator

Hallo HTML.de-Community!
Habe da ein kleines Problem mit einer SQL-Abfrage und versuche es mal anhand eines Beispiels zu erläutern:
Ich habe eine Tabelle (Spalten etwa so: id, titel, tags) bei welcher in der Spalte tags (wie der Name schon sagt) Suchtags für den Titel enthalten sind.

Mein Problem:
Wenn ich in ein auf der Website enthaltenes Suchfeld „fett“ eingebe und in einer Zeile der Tabelle unter tags steht „fett dick“, dann wird mir die entsprechende Zeile nicht angezeigt.
Habe das mit etwa diesem SQL-Code gemacht:
[PHP]$sql = „SELECT * FROM tabelle WHERE tags = ‚fett‘“[/PHP]

Also die Frage ist konkret:
Gibt es eine Art Vergleichsoperator, welcher true ausgibt wenn zB nur ein Teil eines Strings übereinstimmt?
Man könnte das glaube ich irgendwie mit „%“ oder „_“ machen habe ich mal gelesen, aber wie?

Ich danke euch schon jetzt…
LG Vitus

Ich sage dir die Tabelle
id, titel, tags
wird nicht funktionieren weil: Was ist wenn du 2 tags haben willst ?

Mit dem % warst Du nicht weit weg.

$sql = "SELECT * FROM `tabelle` WHERE tags LIKE '%fett%'";

ergibt aber wie mein Vorposter schon sagt durchaus auch mehrere Einträge.

Ah danke, das mit dem % funktioniert zwar wie es soll, aber scheint für eine Suche tatsächlich nicht das passende zu sein (auch wegen eurem Grund).

Hättet ihr vielleicht noch eine Idee, wie ich soetwas mit Such-Tags lösen könnte? Oder muss ich für jeden tag eine eigene Spalte anlegen (hoffe/glaube nicht)?

Kommt drauf an was du genau erreichen willst. Nur dann kann man auch sagen was „richtig“ ist.

Da hast du wohl recht, deshalb erzähle ich nun mal meinen Plan:

Ich wollte eine Art kleines Lexikon schreiben und dafür mittels PHP und MySQL ein Inhaltsverzeichnis. Also jede Zeile der Tabelle ist ein Eintrag dieses Verzeichnisses, welches man auf der Website auch einsehen kann.
Um die Nutzerfreundlichkeit zu erhöhen wollte ich auch ein Suchfeld um schneller zu einem Eintrag zu gelangen. Nun habe ich mir das mit Tags (wie ichs oben schon beschrieben habe, dass das Suchfeld die Spalte mit den Tags durchsucht) überlegt. Aber scheint ja anscheinend nicht die beste Lösung zu sein…

Hoffe das hilft euch etwas weiter.
Eigentlich möchte ich halt so ne Lexikoninterne Suche basteln…
LG Vitus

Du solltest eine zusätzliche Tabelle anlegen mit allen Tags und dazu den IDs deiner Kapitel oder was auch immer zu denen sie gehören. Dann durchsuchst du die Tag-Tabelle und machst dann einen JOIN auf die Kapitel-Tabelle.

Wenn du die trockene Theorie zu dem Thema lesen willst, schau hier: http://de.wikipedia.org/wiki/Normalisierung_(Datenbank )
In deinem Fall hast du die 1. Normalform verletzt:

Jedes Attribut der Relation muss einen atomaren Wertebereich haben.

Das heißt, zusammengesetzte, mengenwertige oder geschachtelte Wertebereiche (relationenwertige Attributwertebereiche) sind nicht erlaubt. Damit sind auch Wiederholungsgruppen nicht zugelassen. Kurz: Kein Attributwertebereich kann in weitere (sinnvolle) Teilbereiche aufgespalten werden (Beispiel: Die Adresse darf nicht als Attribut verwendet werden, sondern muss – sofern es der zugrunde liegende Prozess erfordert – in PLZ, Ort, Straße, Hausnummer aufgeteilt werden).

Lass das mal mit den Tags, das ergibt in dem Kontext nicht besonders viel Sinn, finde ich. Da kannst du besser einfach die Spalten „Titel“ und „Inhalt“ durchsuchen. Aber das eilt nicht, das lässt sich später locker dazubauen. Mach erst die grundlegende Funktionalität fertig.

Den Eintrag über Normalisierung solltest du aber trotzdem lesen. :slight_smile:

Ok, danke. Dann lasse ich das mit den Tags vorläufig mal sein.

Den Wikipediaeintrag zur Normalisierung habe ich gelesen. Es war mit zuvor tatsächlich nicht bewusst, wie nützlich das später mal sein kann. Werde versuchen es auf meine Tabelle/n anzuwenden. Danke für den Tipp. :smiley:

LG Vitus

Da ich kein MySQL-Spezi bin, poste ich hier nur mal meine Bedenken, die ich aus der Arbeit mit Oracle Datenbanken kenne:

Hmm, „einfach“ die Spalten Titel und Inhalt durchsuchen ist womöglich auch nicht die beste Lösung. Dadurch ergeben sich, zumindest in Oracle, mehrere Probleme, bzw. sollte man sich dazu folgende Fragen stellen:
Fragestellungen:

  1. Wie viele Einträge wird die Tabelle später haben?
  2. Wie viele Bytes umfassen die Spalten Inhalt und Titel?
  3. Wird die Tabelle ständig erweitert?

Um eine Hohe Performance zu erreichen, sollte man die Spalten, auf die später Abfragen erfolgen (neben dem PK) mit einem Index versehen, damit das dbms die Abfragen möglichst schnell ausführen kann. Der Index pro Spalte ist, zumindest bei Oracle, in Abhängigkeit zu anderen Parametern begrenzt. Hinzu kommt noch, dass Indizes nichts bringen, wenn man in Abfragen skalare SQL-Funktionen oder den LIKE Befehl in Verbindung mit Wildcards wie % oder ? nutzt. Diese lösen in Oracle automatisch einen FULL TABLE SCAN aus. Das bedeutet, das dbms schaut sich jede einzelne Zeile der angesprochenen Tabelle an. Bei Tabellen mit über einer Millionen Zeilen dauert so eine Abfrage gut und gerne zehn Sekunden. Oracle achtet beim vergleichen von Strings auch auf Groß- und Kleinschreibung, was den Entwickler dazu zwingt, die Eingabe des Users und den zu vergleichenden String in der db mit upper(‚string‘) oder lower(‚string‘) auf „einen gemeinsamen Nenner“ zu bringen.

Warum ist das evtl. zu beachten?
Zum einen soll der User bestimmt nicht lange auf sein Suchergebnis warten müssen. In Zeiten von Google, bei denen Suchanfragen in unter 2/10 einer Sekunde bearbeitet sind, hat der User keine Lust zehn Sekunden (mit Seitenaufbau etc.) auf seine Suchanfrage zu warten.
Wenn du für die Rechenzeit bezahlen musst, die das DBMS verrichtet, dann kann das ganze auch recht teuer werden.

Was du schreibst, ist alles gut und richtig und wissenswert, aber für diesen Thread glaube ich erstmal etwas zu sehr Overengineering. :wink:

Sobald es um Millionen an Einträgen geht, braucht es Caching- oder Stemming-Techniken oder ähnliches.