MySQL FIND_IN_SET() erklärt: Kommagetrennte Werte sicher durchsuchen (mit Beispielen)

目次

1. Einführung: Häufige Situationen, in denen FIND_IN_SET notwendig wird

Wenn Sie mit Daten in MySQL arbeiten, können Sie Fälle antreffen, in denen „mehrere Werte in einer einzigen Spalte, durch Kommas getrennt, gespeichert werden.“ Beispielsweise können vom Benutzer ausgewählte Tags, Kategorieninformationen oder Konfigurationsflags als ein einzelner String wie php,python,sql gespeichert werden.

Eine solche Struktur wird aus Sicht der Datenbanknormalisierung nicht empfohlen. Je nach bestehendem Systemdesign oder wenn flexible Dateneingaben Priorität haben, kann es jedoch in der Praxis notwendig sein, dieses Format zu verwenden.

Ein Lebensretter, wenn die Tag-Suche knifflig wird

Angenommen, Sie möchten prüfen, ob ein Benutzer das Tag „python“ hat. Mit dem üblichen =‑Operator oder dem LIKE‑Operator gibt es Genauigkeitsbeschränkungen aufgrund von Teilübereinstimmungen und umliegenden Zeichen, was zu falschen Ergebnissen führen kann.

Hier kommt die FIND_IN_SET()‑Funktion ins Spiel.

FIND_IN_SET() ist eine MySQL‑Funktion, die die Position (den Index) eines bestimmten Strings innerhalb eines kommagetrennten Strings bestimmt. Wird der String gefunden, gibt sie den Index zurück (beginnend bei 1). Wird er nicht gefunden, gibt sie 0 zurück. Mit diesem Verhalten können Sie feststellen, ob Tags, Kategorien oder Einstellungen genau und flexibel enthalten sind.

Häufige Anwendungsfälle

Typische Szenarien, in denen FIND_IN_SET glänzt, umfassen:

  • Wenn Sie einen bestimmten Wert aus kommagetrennten „Tags“ oder „Kategorien“, die in einem Feld gespeichert sind, extrahieren möchten
  • Wenn Sie CSV‑artige Werte, die in einem Administrationsbildschirm eingegeben wurden, als Suchbedingungen verwenden möchten
  • Wenn Sie eine flexible Filterung gegen Metainformationen in einem CMS wie WordPress benötigen
  • Wenn Sie eine bestehende Tabelle verarbeiten möchten, in der Mehrfachauswahlwerte in einer Spalte gespeichert sind, ohne das Schema zu ändern

Gleichzeitig kann ein falscher Einsatz von FIND_IN_SET Leistungsverschlechterungen oder falsch‑positive/inkorrekte Übereinstimmungen verursachen. In diesem Artikel erklären wir alles von der Grundsyntax über praktische Beispiele, Fallstricke bis hin zu besseren Alternativen, anhand von realen Szenarien.

2. Was ist die FIND_IN_SET‑Funktion? (Grundsyntax und Rückgabewert)

Die MySQL‑Funktion FIND_IN_SET() ist eine Funktion, die die Position eines angegebenen Wertes innerhalb eines kommagetrennten Strings prüft. Sie ist besonders nützlich, wenn mehrere Werte zusammen in einem einzigen Feld gespeichert werden.

Diese Funktion ist spezifisch für MySQL und ist standardmäßig in anderen Datenbanken (wie PostgreSQL oder SQLite) nicht verfügbar, sodass sie als MySQL‑spezifisches Merkmal betrachtet werden kann.

Grundsyntax

FIND_IN_SET(search_value, comma_separated_string)
  • search_value : Der String, den Sie finden möchten
  • comma_separated_string : Die kommagetrennte Liste, in der gesucht werden soll

Beispiel

Betrachten Sie das folgende SQL:

SELECT FIND_IN_SET('python', 'php,python,sql');

In diesem Fall ist 'python' das zweite Element, sodass der Rückgabewert 2 ist.

Andererseits, wenn der angegebene Wert nicht in der Liste existiert, wird 0 zurückgegeben:

SELECT FIND_IN_SET('ruby', 'php,python,sql');
-- Result: 0

Zusätzlich, wenn eines der Argumente NULL ist, ist der Rückgabewert ebenfalls NULL.

SELECT FIND_IN_SET(NULL, 'php,python,sql');
-- Result: NULL

Rückgabewert‑Regeln

ConditionReturn Value
The value exists in the list1 or greater (its position)
The value does not exist in the list0
Either argument is NULLNULL

Durch die effektive Nutzung des Rückgabewerts können Sie FIND_IN_SET nicht nur zum Suchen einsetzen, sondern auch für Fälle wie das „Überprüfen der Reihenfolge, in der ein Wert erscheint“.

Wichtiger Hinweis: 0 bedeutet „Nicht gefunden“

Wenn der Rückgabewert 0 ist, bedeutet das „nicht in der Liste gefunden“. In MySQL wird 0 als FALSE (FALSCH) behandelt, sodass die direkte Verwendung in einer WHERE‑Klausel zu Verwirrung führen kann, wenn Sie das Verhalten nicht verstehen.

Im nächsten Abschnitt zeigen wir grundlegende Abfragebeispiele für die Verwendung von FIND_IN_SET mit realen Tabellendaten.

3. Praktisches Beispiel 1: Grundlegende Verwendung (Eine einfache SELECT‑Abfrage)

Die FIND_IN_SET()‑Funktion tut genau das, was ihr Name suggeriert – „innerhalb einer Menge finden“. Aber wie sollte man sie schreiben, wenn man sie auf echte Tabellendaten anwendet?
Hier gehen wir die einfachste Verwendung mit einer grundlegenden SELECT‑Anweisung durch.

Beispielhafte Tabelle vorbereiten

Angenommen, die folgende Tabelle:

Tabellenname: user_tags

idnametags
1Tanakaphp,python,sql
2Suzukijava,ruby
3Satopython,c,go

Die Spalte tags speichert von Benutzern registrierte Fähigkeits‑Tags als kommagetrennte Zeichenkette.

Beispiel: Suche nach Benutzern, die „python“ enthalten

Um nur Benutzer zu extrahieren, die das Tag „python“ haben, schreiben Sie das folgende SQL:

SELECT * FROM user_tags
WHERE FIND_IN_SET('python', tags);

Ergebnis:

idnametags
1Tanakaphp,python,sql
3Satopython,c,go

Wie gezeigt, werden nur Datensätze zurückgegeben, bei denen „python“ in der Spalte tags enthalten ist.

Exakte Zeichenketten‑Übereinstimmung ist entscheidend

FIND_IN_SET() vergleicht basierend auf exakter Zeichenketten‑Gleichheit. Das bedeutet, dass Teilzeichenketten wie „py“ oder „pyth“ nicht gefunden werden. Wenn Sie Teilzeichenketten benötigen, würden Sie LIKE verwenden, aber ein Ausdruck wie LIKE '%python%' kann fälschlicherweise anderen Inhalt treffen und ist für kommagetrennte Listen riskant. Daher ist FIND_IN_SET im Allgemeinen besser für kommagetrennte Listen geeignet.

Beispiel: Suche mit einer Variablen in SQL

Wenn Sie den Suchwert dynamisch ändern möchten, können Sie eine Variable verwenden:

SET @skill = 'python';

SELECT * FROM user_tags
WHERE FIND_IN_SET(@skill, tags);

Dieses Muster ist auch nützlich, wenn man es in Anwendungen oder gespeicherten Prozeduren integriert.

4. Praktisches Beispiel 2: Unterstützung dynamischer Suchen (Variablen und Formular‑Integration)

In realen Web‑Anwendungen und Geschäftssystemen muss man häufig Suchbedingungen dynamisch in SQL aufbauen.
Zum Beispiel möchte man nach Werten suchen, die Benutzer in einem Formular ausgewählt haben, oder nach Werten, die das System automatisch mit FIND_IN_SET() erzeugt.

Hier sind praktische Nutzungsmuster unter Annahme von Variablen und Backend‑Integration.

Dynamische Suche mit SQL‑Variablen

Wenn Sie MySQL‑Sitzungsvariablen (@variable_name) verwenden, können Sie oben einen Suchwert definieren und ihn in mehreren Abfragen wiederverwenden:

-- Store the tag you want to search for in a variable
SET @target_tag = 'python';

-- Dynamic search with FIND_IN_SET
SELECT * FROM user_tags
WHERE FIND_IN_SET(@target_tag, tags);

Damit lässt sich der Suchwert leicht austauschen und es funktioniert gut in gespeicherten Prozeduren oder Batch‑Verarbeitung.

Anwendungsintegration: PHP‑Beispiel

Wenn Sie zum Beispiel PHP verwenden, um basierend auf einer Web‑Formular‑Eingabe SQL auszuführen, könnten Sie folgenden Code schreiben:

<?php
$tag = $_GET['tag']; // Example: form input "python"

// Build SQL (a prepared statement is recommended)
$sql = "SELECT * FROM user_tags WHERE FIND_IN_SET(?, tags)";

$stmt = $pdo->prepare($sql);
$stmt->execute([$tag]);
$results = $stmt->fetchAll();
?>

In Kombination mit einem vorbereiteten Statement bietet dies zudem einen soliden Schutz vor SQL‑Injection.

WordPress‑Anwendungsfall: Tag‑Suche in benutzerdefinierten Feldern

In WordPress können Sie benutzerdefinierte Felder mit meta_query durchsuchen, aber wenn Sie FIND_IN_SET einbinden wollen, müssen Sie im Allgemeinen direktes SQL verwenden, etwa so:

Beispiel: wenn das benutzerdefinierte Feld _user_tags den Wert "php,python,sql" speichert

global $wpdb;
$tag = 'python';

$sql = $wpdb->prepare(
  "SELECT * FROM {$wpdb->prefix}postmeta WHERE meta_key = %s AND FIND_IN_SET(%s, meta_value)",
  '_user_tags', $tag
);
$results = $wpdb->get_results($sql);

Dieser Ansatz ermöglicht flexible Suchen, die die Standard‑Funktionen von WordPress nicht bewältigen können.

Wichtig: Achten Sie auf Leerzeichen und Voll‑Breiten‑Kommas

Bei Verwendung von FIND_IN_SET kann jedes zusätzliche Leerzeichen oder Voll‑Breiten‑Zeichen in der kommagetrennten Zeichenkette Treffer verhindern.
Daher wird empfohlen, eine Vorverarbeitung durchzuführen, z. B.:

  • Entfernen Sie Leerzeichen mit der Funktion TRIM()
  • Normalisieren Sie das Komma‑Format (Voll‑Breite → Halb‑Breite)
  • Validieren Sie Eingaben auf der Anwendungsseite

5. Fortgeschrittene Techniken mit FIND_IN_SET (GROUP_CONCAT, Unterabfragen, JOIN)

Die FIND_IN_SET‑Funktion kann mehr als einfache Einzelfeld‑Suchen verarbeiten. Durch die Kombination mit anderen SQL‑Funktionen und Unterabfragen können Sie flexiblere und komplexere Suchlogik erstellen. Dieser Abschnitt stellt drei gängige erweiterte Muster vor.

Kombination mit GROUP_CONCAT

Zuerst die Integration mit GROUP_CONCAT(), das mehrere Zeilen als einen einzelnen kommagetrennten String behandeln kann. Das ist nützlich, wenn Sie aus einer Tabelle eine Liste von Tags erstellen und diese als Bedingung für die Suche in einer anderen Tabelle verwenden möchten.

Beispiel: Werte in der Spalte tags von user_tags mit einer Tag‑Liste aus master_tags vergleichen

SELECT *
FROM user_tags
WHERE FIND_IN_SET('python', (
  SELECT GROUP_CONCAT(tag_name)
  FROM master_tags
));

In dieser Abfrage wird die Tag‑Liste in master_tags in einen einzigen kommagetrennten String konvertiert, und FIND_IN_SET() prüft, ob Übereinstimmungen vorhanden sind.

Beachten Sie, dass die von GROUP_CONCAT erzeugte String‑Länge ein Limit hat (Standard sind 1024 Zeichen). Wenn Sie viele Werte haben, prüfen Sie die Einstellung group_concat_max_len.

Verwendung einer Unterabfrage zum dynamischen Abrufen eines Wertes

Als Nächstes ein Muster, bei dem Sie dynamisch den Suchzielwert mit einer Unterabfrage abrufen und ihn an FIND_IN_SET übergeben.

Beispiel: Eine Suchbedingung aus einer Verwaltungstabelle abrufen und die Daten entsprechend filtern

SELECT *
FROM user_tags
WHERE FIND_IN_SET(
  'python',
  (SELECT setting_value FROM search_conditions WHERE id = 1)
);

Hier wird die Suchbedingung in einer Verwaltungstabelle gespeichert, sodass Sie das Suchverhalten allein durch Aktualisieren von Systemeinstellungen ändern können.
Dies kann für konfigurierbare Administrationsoberflächen und Dashboard‑artige Anwendungen praktisch sein.

Im Vergleich zu JOIN: JOIN ist in einem normalisierten Schema besser

FIND_IN_SET ist praktisch, aber wenn Ihr Datenbankdesign korrekt normalisiert ist, ist die Suche mit JOIN effizienter und sicherer.

Zum Beispiel können Sie bei einer Many‑to‑Many‑Beziehung über eine Junction‑Tabelle die Suche sauber mit JOIN implementieren:

Beispielstruktur:

  • users‑Tabelle
  • tags‑Tabelle
  • user_tag_relation‑Tabelle (Junction‑Tabelle, die user_id und tag_id enthält)
    SELECT users.*
    FROM users
    JOIN user_tag_relation ON users.id = user_tag_relation.user_id
    JOIN tags ON user_tag_relation.tag_id = tags.id
    WHERE tags.name = 'python';
    

Dieses Design verbessert die Suchleistung und erleichtert zukünftige Daten‑Erweiterungen.

Welchen Ansatz sollten Sie wählen?

ApproachBest For
FIND_IN_SET + GROUP_CONCATWhen you want to dynamically control a filter list
FIND_IN_SET + SubqueryWhen you want to pull conditions from a management table
JOINNormalized schemas, large data volumes, performance-focused systems

Wie Sie sehen, wird FIND_IN_SET() deutlich flexibler, wenn es mit anderen SQL‑Funktionen kombiniert wird. Je nach Schema und Zielsetzung können jedoch JOIN oder andere Ansätze geeigneter sein, sodass die Wahl anhand von Design und Zweck erfolgen sollte.

6. Fallstricke und Einschränkungen von FIND_IN_SET (Leistung und Design)

FIND_IN_SET ist eine praktische Funktion, die flexible Suchen in kommagetrennten Zeichenketten ermöglicht, aber sollten Sie sie nicht unbedacht einsetzen.
In diesem Abschnitt erläutern wir häufige Praxisprobleme im Zusammenhang mit Leistung und Risiken im Datenbankdesign.

Schlechte Leistung, weil Indizes nicht verwendet werden können

Der größte Nachteil von FIND_IN_SET ist, dass es verhindert, dass Indizes auf der Zielspalte verwendet werden.

Zum Beispiel betrachten Sie die folgende Abfrage:

SELECT * FROM user_tags
WHERE FIND_IN_SET('python', tags);

Selbst wenn die Spalte tags indiziert ist, zwingt die Verwendung von FIND_IN_SET zu einem vollständigen Tabellenscan, d.h. MySQL muss jede Zeile lesen und den String jedes Mal parsen.

Infolgedessen kann bei großen Datensätzen (Tausende bis Zehntausende von Zeilen und mehr) die Suchgeschwindigkeit stark abnehmen.

Empfohlene Maßnahmen:

  • Erwägen Sie eine Normalisierung mittels einer Junction‑Tabelle, wenn es sinnvoll ist
  • Wenn Sie FIND_IN_SET unbedingt verwenden müssen, schränken Sie die Kandidaten zuerst ein (verwenden Sie LIMIT oder kombinieren Sie mit anderen WHERE ‑Bedingungen)

Es fördert eine nicht normalisierte Struktur

Das Speichern kommagetrennter Werte in einer einzelnen Spalte verletzt Prinzipien der Datenbanknormalisierung.

Zum Beispiel sieht die Zeichenkette "php,python,sql" bequem aus, aber sie führt zu Problemen wie:

  • Schwierige Aggregation und statistische Verarbeitung pro Wert
  • Schwer, nur einen der Werte zu aktualisieren oder zu löschen
  • Einfach, dass Duplikate und Tippfehler auftreten (z. B. „Python“ vs. „python“)

Langfristig wird dies oft zu einem wesentlichen Nachteil in Bezug auf Lesbarkeit, Wartbarkeit und Skalierbarkeit, insbesondere in der Teamentwicklung oder bei skalierbaren Diensten.

Suchfehler aufgrund von Nicht‑Komma‑Zeichen oder Leerzeichen

FIND_IN_SET ist sehr empfindlich. Wenn die Daten Probleme wie die folgenden enthalten, schlägt das Matching fehl:

  • Leerzeichen um Werte herum (Leerzeichen, Tabs, Zeilenumbrüche)
  • Vollbreite Kommas (、)
  • Unerwartete Anführungszeichen (Doppelte oder einfache Anführungszeichen)

Beispiel:

FIND_IN_SET('python', 'php, python ,sql')
-- => No match (because it becomes " python " with spaces)

Gegenmaßnahmen:

  • Entfernen Sie Leerzeichen beim Einfügen mit TRIM()
  • Verarbeiten Sie die Eingabe vorab mit REPLACE(tags, ' ', '')
  • Beschränken Sie die Eingabe im Frontend (unnötige Leerzeichen/Symbole entfernen)

Gut als vorübergehende Lösung, nicht ideal für den dauerhaften Einsatz

FIND_IN_SET ist sehr nützlich als temporäre Umgehungslösung, um eine bestehende nicht normalisierte Tabelle kurzfristig nutzbar zu halten.
Für neu konzipierte Systeme oder solche, die langfristig gewartet und erweitert werden sollen, sollten Sie es jedoch nach Möglichkeit vermeiden – oder zumindest einen Plan haben, in Zukunft zu einem normalisierten Design zu migrieren.

7. Häufige Missverständnisse und Fehlerszenarien (Unterschiede zu LIKE / Umgang mit Zahlen)

FIND_IN_SET wirkt einfach, aber wenn Sie es nicht korrekt einsetzen, können unerwartete Ergebnisse auftreten.
In diesem Abschnitt behandeln wir häufige Missverständnisse und Fehler aus der Praxis sowie praktische Lösungen.

Fehler 1: Das Unterschied zwischen LIKE und FIND_IN_SET nicht verstehen

Der häufigste Fehler besteht darin, den Unterschied zwischen LIKE und FIND_IN_SET() nicht zu verstehen, was zu falschen Suchbedingungen führt.

-- Common incorrect usage
SELECT * FROM user_tags WHERE tags LIKE '%python%';

Diese Abfrage mag zunächst korrekt erscheinen, aber sie trifft auf alle Daten, die die Teilzeichenkette python enthalten.

Zum Beispiel kann sie "cpython", "pythonista" oder "java,pythonic" treffen, was Sie wahrscheinlich nicht wollen.
Wenn Sie nur „python“ als eigenständiges Element in einer kommagetrennten Liste wie php,python,sql abgleichen möchten, birgt ein Teil‑Match LIKE ein hohes Risiko für Fehlalarme.

Wenn Sie bestätigen müssen, dass „python“ als eigener Wert existiert, ist FIND_IN_SET() das richtige Werkzeug.

-- Correct usage
SELECT * FROM user_tags WHERE FIND_IN_SET('python', tags);

Fehler 2: FIND_IN_SET mit numerischen Werten verwenden und verwirrt sein

FIND_IN_SET geht davon aus, dass beide Argumente als Zeichenketten behandelt werden.

Bei solchen Daten sagen Entwickler manchmal das Verhalten falsch voraus:

-- tags column contains: 1,2,10,20
SELECT * FROM user_tags WHERE FIND_IN_SET(1, tags);

Manche könnten annehmen, 1 würde auch 10 treffen, aber in Wirklichkeit trifft FIND_IN_SET(1, '1,2,10,20') nur das Element „1“ an Position 1.

Because FIND_IN_SET splits values and checks exact equality, 1 is different from 10 or 21.
Da FIND_IN_SET Werte aufteilt und auf exakte Gleichheit prüft, ist 1 anders als 10 oder 21.

However, developers may still misunderstand this behavior and incorrectly assume “1” will hit “10.”
Entwickler können dieses Verhalten jedoch weiterhin missverstehen und fälschlich annehmen, dass „1“ „10“ trifft.

Recommendation: Always treat values explicitly as strings to avoid ambiguity and confusion.
Empfehlung: Werte immer explizit als Zeichenketten behandeln, um Mehrdeutigkeiten und Verwirrung zu vermeiden.

Mistake 3: Whitespace, Full-Width Commas, or Newlines Prevent Matching

Fehler 3: Leerzeichen, Vollbreite‑Kommas oder Zeilenumbrüche verhindern das Matching

FIND_IN_SET is very sensitive. If the data includes issues like the following, matching will fail:
FIND_IN_SET ist sehr empfindlich. Wenn die Daten Probleme wie die folgenden enthalten, schlägt das Matching fehl:

  • Whitespace around values (spaces, tabs, newlines) → Leerzeichen um Werte herum (Leerzeichen, Tabs, Zeilenumbrüche)
  • Full-width commas (、) → Vollbreite Kommas (、)
  • Unexpected quotes (double quotes or single quotes) → Unerwartete Anführungszeichen (Doppelte oder einfache Anführungszeichen)

Beispiel:

FIND_IN_SET('python', 'php, python ,sql')
-- => No match (because it becomes " python " with spaces)

Gegenmaßnahmen:

  • Entfernen Sie Leerzeichen beim Einfügen mit TRIM()
  • Verarbeiten Sie die Eingabe vorab mit REPLACE(tags, ' ', '')
  • Beschränken Sie die Eingabe im Frontend (entfernen Sie unnötige Leerzeichen/Symbole)

Zusammenfassung: Wichtige Punkte für die sichere Verwendung von FIND_IN_SET

Common PitfallFix
Confusing it with LIKE and getting false positivesUse FIND_IN_SET when exact value matching is required
Unexpected behavior with numeric valuesTreat numbers as strings and compare explicitly
Whitespace/full-width characters break matchingNormalize and preprocess data consistently

Wenn Sie FIND_IN_SET verwenden, ohne diese Verhaltensweisen zu verstehen, könnten Sie denken, „die Suche funktioniert“, während in Wirklichkeit die erwarteten Datensätze nicht extrahiert werden, was zu ernsthaften Fehlern führen kann.

Im nächsten Abschnitt behandeln wir „alternative Ansätze“, die diese Probleme an der Wurzel lösen.

8. Alternativen zu FIND_IN_SET (Bewährte Verfahren)

FIND_IN_SET ermöglicht flexible Suchen in kommagetrennten Zeichenketten, ist jedoch nicht geeignet für große Datensätze oder Systeme, die Skalierbarkeit erfordern.
In diesem Abschnitt stellen wir empfohlene Alternativen (bewährte Verfahren) vor, die die Verwendung von FIND_IN_SET vermeiden.

Wechsel zu einem normalisierten Tabellendesign

Der am meisten empfohlene Ansatz ist, die Datenbank zu normalisieren und Werte als einzelne Zeilen zu verwalten.
Anstatt mehrere Werte in einer kommagetrennten Spalte zu speichern, verwenden Sie eine Junction‑Tabelle (Relationstabelle), um viele‑zu‑viele‑Beziehungen klar darzustellen.

Beispiel: Beziehung zwischen Benutzern und Tags

Traditionelle (denormalisierte) Struktur:

user_idtags
1php,python,sql

Normalisierte Struktur:

users‑Tabelle

idname
1Tanaka

tags‑Tabelle

idname
1php
2python
3sql

user_tag_relation (Junction‑Tabelle)

user_idtag_id
11
12
13

Mit dieser Struktur können Sie flexibel mit JOIN suchen, ohne FIND_IN_SET zu verwenden:

SELECT users.*
FROM users
JOIN user_tag_relation ON users.id = user_tag_relation.user_id
JOIN tags ON user_tag_relation.tag_id = tags.id
WHERE tags.name = 'python';

Dieser Ansatz ermöglicht, dass Indizes effektiv arbeiten und verbessert die Leistung und Skalierbarkeit erheblich.

Verwendung des JSON‑Typs (MySQL 5.7+)

Ab MySQL 5.7 können Sie JSON‑Spalten verwenden. Anstatt kommagetrennte Zeichenketten zu speichern, können Sie Werte als JSON‑Array ablegen und mit JSON‑Funktionen suchen.

Beispiel:

["php", "python", "sql"]

Suchbeispiel:

SELECT * FROM user_tags
WHERE JSON_CONTAINS(tags_json, '"python"');

Damit bleiben Tags strukturiert, verhindern falsche Treffer durch Leerzeichen und reduzieren Probleme mit der Datenqualität.
Zusätzlich kann JSON‑spezifisches Indexieren (MySQL 8.0+) die Leistung weiter steigern.

Aufteilen und Wiederaufbauen auf der Anwendungsebene

Wenn Sie das Design nicht ändern können und die aktuelle Struktur beibehalten müssen, können Sie dennoch ein ähnliches Verhalten implementieren, indem Sie auf der Anwendungsebene in ein Array aufteilen und iterieren oder bei Bedarf in eine SQL‑IN‑Klausel umwandeln.

Beispiel (PHP):

$tags = explode(',', $record['tags']);
if (in_array('python', $tags)) {
    // Execute processing
}

Damit wird die Belastung der Datenbank reduziert und eine sicherere Verarbeitung ermöglicht.

Verwenden Sie FIND_IN_SET als „Ausnahme“, nicht als Standard

Wie wiederholt erwähnt, ist FIND_IN_SET als temporäre Übergangslösung sehr nützlich, um bestehende denormalisierte Tabellen kurzfristig nutzbar zu halten.
Für neue Systeme oder solche, die langfristig gewartet und erweitert werden sollen, sollten Sie es nach Möglichkeit vermeiden – oder zumindest einen Plan haben, in Zukunft zur Normalisierung zu migrieren.

ApproachBest Fit
Normalization + JOINWhen performance and scalability matter
JSON type + JSON functionsWhen you want flexible structured storage
Application-side processingTemporary handling or read-only use cases
FIND_IN_SETShort-term workaround for legacy DBs where schema changes are difficult

9. FAQ: Häufige Fragen und Antworten

Bei FIND_IN_SET tauchen im praktischen Einsatz und beim Lernen viele Fragen und Unklarheiten auf.
Hier haben wir häufig gestellte Fragen in einem Q&A‑Format zusammengestellt, das gut zu gängigen Suchintentionen passt.

Q1. Wann ist es korrekt, FIND_IN_SET zu verwenden?

A.
FIND_IN_SET wird verwendet, wenn Sie prüfen möchten, ob ein bestimmter Wert in einer kommagetrennten Zeichenkette enthalten ist.
Es ist geeignet für Situationen wie:

  • Wenn das Design erfordert, mehrere Werte in einer Spalte zu speichern (z. B. Tags, Berechtigungen, Flags)
  • Wenn Sie eine alte denormalisierte Datenbank durchsuchen möchten, ohne sie zu ändern
  • Für kleine bis mittlere Datensätze, bei denen die Nutzung begrenzt ist (Admin‑Tools, interne Oberflächen)

Allerdings ist es nicht für die Kernproduktion oder die Verarbeitung großer Datenmengen geeignet.

Q2. Was ist der Unterschied zwischen FIND_IN_SET und LIKE?

A.
LIKE '%value%' führt eine partielle Übereinstimmung durch, das heißt, es kann unabhängig davon passen, was vor oder nach dem Teilstring steht.
Im Gegensatz dazu sucht FIND_IN_SET('value', comma_separated_string) mit einer exakten Übereinstimmung für jedes kommagetrennte Element.

-- LIKE example (matches anything containing "python")
tags LIKE '%python%'

-- FIND_IN_SET example (matches only "python" as an independent element)
FIND_IN_SET('python', tags)

Ein häufiger LIKE-Fallstrick ist, dass „python“ mit „cpython“ oder „pythonista“ übereinstimmen kann.

Q3. Warum verlangsamt FIND_IN_SET SQL‑Abfragen?

A.
Da FIND_IN_SET eine Funktion ist, die einen vollständigen Scan ohne Nutzung von Indizes erzwingt.
Sie prüft jede Zeile und analysiert den String, um Werte zu vergleichen, sodass die Verarbeitungszeit bei steigender Datenmenge schnell zunimmt.

Deshalb kann sie bei Tabellen mit vielen Datensätzen erhebliche Leistungsprobleme verursachen.

Q4. Können beim Suchen von Zahlen „1“ und „10“ verwechselt werden?

A.
Da FIND_IN_SET eine exakte Übereinstimmung durchführt, behandelt es im Allgemeinen „1“ und „10“ als unterschiedliche Werte.
Allerdings kann das Verhalten bei Unterschieden in Leerzeichen, Typumwandlung oder Eingabeformatierung von Ihren Erwartungen abweichen.

-- Correct example
FIND_IN_SET('1', '1,2,10') -- => 1 (first position)

-- Commonly misunderstood example
FIND_IN_SET(1, '1,2,10') -- => also 1 (works, but is ambiguous)

Empfehlung: Behandeln Sie Werte immer als Zeichenketten, um unbeabsichtigtes Verhalten zu vermeiden.

Q5. Kann ich FIND_IN_SET in WordPress verwenden?

A.
Sie können FIND_IN_SET nicht über Standard‑WordPress‑Funktionen wie meta_query verwenden, aber Sie können es einsetzen, indem Sie direktes SQL mit $wpdb ausführen.

global $wpdb;
$sql = $wpdb->prepare("
  SELECT * FROM {$wpdb->prefix}postmeta
  WHERE meta_key = %s AND FIND_IN_SET(%s, meta_value)
", 'your_meta_key', 'search_value');

$results = $wpdb->get_results($sql);

Wenn Ihr Design jedoch stark von benutzerdefinierten Feldern abhängt, sollten Sie auch Alternativen in Betracht ziehen (z. B. die Verwaltung mehrerer Meta‑Keys).

Q6. Was ist der Unterschied zu JSON‑Spalten? Sind sie praktischer als FIND_IN_SET?

A.
Die Verwendung einer JSON‑Spalte in MySQL 5.7+ ermöglicht es, Daten strukturiert zu halten und mit JSON_CONTAINS() zu suchen.
Sie ist im Allgemeinen hinsichtlich Genauigkeit, Skalierbarkeit und Flexibilität FIND_IN_SET überlegen.

-- JSON search example
SELECT * FROM users WHERE JSON_CONTAINS(tags_json, '"python"');

In modernen Designs ist es zunehmend üblich, JSON‑Spalten gegenüber FIND_IN_SET zu bevorzugen.

10. Fazit: FIND_IN_SET ist eine „praktische Ausnahme“ und eine Chance, Ihr Schema zu überdenken

In diesem Artikel haben wir die MySQL‑Funktion FIND_IN_SET() behandelt – von der Grundsyntax und praktischen Beispielen bis zu Fallstricken und empfohlenen Alternativen.

Sie mag wie eine kleine Funktion erscheinen, aber wenn sie korrekt eingesetzt wird, kann sie ein leistungsstarkes Werkzeug sein, das Ihre Möglichkeiten bei Datenbankoperationen erweitert.

Überprüfung der wichtigsten Merkmale von FIND_IN_SET

FeatureExplanation
✅ Flexible comma-separated searchingEnables “per-value” matching that can be difficult with LIKE
✅ Works well with legacy denormalized databasesCan solve problems without changing the schema
⚠ Performance issues because indexes can’t be usedCan slow down queries significantly on large tables
⚠ Sensitive to input and storage inconsistenciesWhitespace or full-width symbols can break matching

Wann man sie einsetzen sollte (und wann nicht)

Gute Anwendungsfälle:

  • Der Datensatz ist klein und die Nutzung ist begrenzt
  • Legacy‑Systeme sind schwer zu refaktorisieren und Sie benötigen eine schnelle Lösung
  • Sie benötigen eine temporäre Lösung in Admin‑Ansichten oder bei Batch‑Verarbeitung

Situationen, in denen man sie vermeiden sollte:

  • Große Datensätze, bei denen die Suchgeschwindigkeit wichtig ist
  • Workflows, die häufige Updates, Aggregationen oder wechselnde Bedingungen erfordern
  • Designs, die für langfristige Erweiterung und Wartung vorgesehen sind

FIND_IN_SET ist eine „praktische Ausnahme“. Die wirkliche Lösung ist ein besseres Schema‑Design

FIND_IN_SET ist im Wesentlichen ein Workaround, wenn strukturelle Einschränkungen bestehen.
Wenn Sie ein neues Schema entwerfen, sollten Sie diese beiden Optionen in Betracht ziehen:

  • Normalisieren Sie die Datenbank und verwalten Sie Many-to-Many-Beziehungen mit einer Junction‑Tabelle
  • Wenn Sie Flexibilität benötigen, verwenden Sie eine JSON‑Spalte , um strukturierte Daten zu speichern

Wenn dieser Artikel Ihnen hilft, besser zu verstehen, wann FIND_IN_SET nützlich ist, seine Einschränkungen und warum die Überarbeitung des Schemas oft die beste Lösung ist, ist das ein Gewinn.