1. Einführung
Die Herausforderung, kommagetrennte Daten in MySQL zu durchsuchen
Wenn Sie mit Datenbanken arbeiten, kann es vorkommen, dass mehrere Werte in einer einzigen Spalte durch Kommas getrennt gespeichert werden. Beispielsweise kann eine Spalte einen String wie "1,3,5" enthalten, und Sie möchten nur die Datensätze extrahieren, die den Wert „3“ enthalten.
In solchen Fällen liefert der Standard‑=‑Operator oder die IN‑Klausel oft nicht das erwartete Ergebnis. Das liegt daran, dass ein kommagetrennter String als ein einziger String‑Wert behandelt wird, sodass Vergleiche gegen den gesamten String und nicht gegen einzelne Elemente darin ausgewertet werden.
Was ist die FIND_IN_SET‑Funktion?
In solchen Situationen ist die MySQL‑Funktion FIND_IN_SET sehr nützlich.
Sie ermöglicht es Ihnen, einfach zu bestimmen, ob ein bestimmter Wert in einem kommagetrennten String vorkommt.
Zum Beispiel, betrachten Sie die folgende SQL‑Anweisung:
SELECT * FROM users WHERE FIND_IN_SET('3', favorite_ids);
In dieser Abfrage können Sie Datensätze extrahieren, bei denen der kommagetrennte String in der Spalte favorite_ids (z. B. "1,2,3,4") den Wert „3“ enthält.
Zweck dieses Artikels und Zielgruppe
Dieser Artikel erklärt, wie man die FIND_IN_SET‑Funktion von den Grundlagen an klar und strukturiert verwendet. Von der Basissyntax über praktische Beispiele, Vergleiche mit anderen Suchmethoden, wichtige Überlegungen bis hin zu FAQs – dieser Leitfaden liefert praktisches Wissen für die reale Entwicklung.
Der Artikel richtet sich an:
- Web‑Engineers und Backend‑Entwickler, die regelmäßig MySQL einsetzen
- Entwickler, die mit bestehenden Systemen arbeiten, die kommagetrennte Daten speichern
- SQL‑Anfänger, die Schwierigkeiten mit Teil‑Übereinstimmungen und wertbasierten Suchen haben
2. Grundsyntax und Verhalten der FIND_IN_SET‑Funktion
Syntax von FIND_IN_SET
FIND_IN_SET ist eine MySQL‑Funktion, die prüft, ob ein bestimmter Wert in einem kommagetrennten String vorkommt. Die Grundsyntax lautet wie folgt:
FIND_IN_SET(search_value, comma_separated_string)
Beispiel:
SELECT FIND_IN_SET('3', '1,2,3,4'); -- Result: 3
In diesem Beispiel, da „3“ an dritter Stelle steht, gibt die Funktion den numerischen Wert 3 zurück.
Rückgabewert‑Regeln
Die FIND_IN_SET‑Funktion verhält sich nach den folgenden Regeln:
| Condition | Result |
|---|---|
| The search value exists in the list | Its position in the list (starting from 1) |
| The search value does not exist | 0 |
| Either argument is NULL | NULL |
Beispiel (Rückgabe der Position)
SELECT FIND_IN_SET('b', 'a,b,c'); -- Result: 2
Beispiel (Wert nicht gefunden)
SELECT FIND_IN_SET('d', 'a,b,c'); -- Result: 0
Beispiel (NULL enthalten)
SELECT FIND_IN_SET(NULL, 'a,b,c'); -- Result: NULL
Beispielhafte Verwendung in einer WHERE‑Klausel
Am häufigsten wird diese Funktion zum Filtern innerhalb einer WHERE‑Klausel eingesetzt.
SELECT * FROM users WHERE FIND_IN_SET('admin', roles);
In diesem Beispiel werden nur Zeilen zurückgegeben, bei denen die Spalte roles den String „admin“ enthält. Enthält die Spalte einen Wert wie "user,editor,admin", wird ein Treffer erzielt.
Wichtige Hinweise zu Zahlen und Strings
FIND_IN_SET führt Vergleiche als Strings durch, was bedeutet, dass es sich wie folgt verhält:
SELECT FIND_IN_SET(3, '1,2,3,4'); -- Result: 3
SELECT FIND_IN_SET('3', '1,2,3,4'); -- Result: 3
Obwohl die Funktion sowohl mit numerischen als auch mit String‑Werten funktioniert, können unklare Datentypen zu unerwartetem Verhalten führen. Daher ist es bewährte Praxis, Werte nach Möglichkeit explizit als Strings zu behandeln.
3. Praktische Beispiele
Suche in einer Spalte, die kommagetrennte Strings speichert
In realen Systemen kommt es häufig vor, dass mehrere Werte (z. B. IDs oder Berechtigungen) in einer einzigen Spalte als kommagetrennter String abgelegt werden. Betrachten Sie zum Beispiel die folgende users‑Tabelle.
| id | name | favorite_ids |
|---|---|---|
| 1 | Taro | 1,3,5 |
| 2 | Hanako | 2,4,6 |
| 3 | Jiro | 3,4,5 |
Wenn Sie „Benutzer, die 3 enthalten“ abrufen möchten, ist die FIND_IN_SET‑Funktion äußerst praktisch.
SELECT * FROM users WHERE FIND_IN_SET('3', favorite_ids);
Die Ausführung dieses SQL‑Befehls liefert die Datensätze für „Taro“ und „Jiro“.
Funktioniert einwandfrei, selbst wenn Werte numerisch aussehen
Selbst wenn favorite_ids scheinbar Zahlen enthält, führt FIND_IN_SET zeichenbasierte Vergleiche durch, daher ist es am sichersten, das Argument als Zeichenkette in Anführungszeichen zu übergeben.
-- OK
SELECT * FROM users WHERE FIND_IN_SET('5', favorite_ids);
-- Works, but strictly speaking not recommended
SELECT * FROM users WHERE FIND_IN_SET(5, favorite_ids);
Um Abfragen lesbar und das Verhalten vorhersehbar zu halten, wird empfohlen, den Wert explizit als Zeichenkette anzugeben.
Dynamische Suchen (Platzhalter und Variablen)
Beim dynamischen Erzeugen von SQL aus einer Webanwendung ist es üblich, Variablen oder Bind‑Parameter zu verwenden.
Wenn Sie eine MySQL‑Variable verwenden, sieht das so aus:
SET @target_id = '3';
SELECT * FROM users WHERE FIND_IN_SET(@target_id, favorite_ids);
Beim Binden aus einer Anwendungsschicht (wie PHP, Python oder Node.js) können Sie dies ähnlich mit Platzhaltern handhaben.
Wie man die Suche nach mehreren Werten handhabt
Leider kann FIND_IN_SET nur nach einem Wert gleichzeitig suchen.
Wenn Sie Datensätze abrufen möchten, die „3 oder 4“ enthalten, müssen Sie dies mehrmals mit OR schreiben.
SELECT * FROM users
WHERE FIND_IN_SET('3', favorite_ids) OR FIND_IN_SET('4', favorite_ids);
Wenn die Bedingungen komplexer werden, sollten Sie entweder das SQL in Ihrer Anwendung dynamisch erstellen oder eine Migration zu einer normalisierten Tabellenstruktur in Betracht ziehen.
4. Vergleich von FIND_IN_SET mit anderen Suchmethoden
Häufige Alternativen: IN und LIKE
In MySQL können Sie neben FIND_IN_SET auch die IN‑Klausel oder die LIKE‑Klausel sehen, die verwendet werden, um zu prüfen, ob ein Wert enthalten ist. Jede Methode verhält sich jedoch anders, und die falsche Verwendung kann zu falschen Abfrageergebnissen führen.
Hier klären wir, wie sie sich von FIND_IN_SET unterscheiden und wann jede Vorgehensweise zu verwenden ist.
Vergleich mit der IN‑Klausel
Die IN‑Klausel wird typischerweise verwendet, um zu prüfen, ob ein Wert einem von mehreren konstanten Werten entspricht.
-- Example of IN (this does NOT search inside "favorite_ids" for the value 3)
SELECT * FROM users WHERE favorite_ids IN ('3');
In diesem Fall werden nur Datensätze zurückgegeben, bei denen favorite_ids eine exakte Übereinstimmung mit „3“ ist. Das bedeutet, Werte wie „1,3,5“ passen nicht – nur eine Zeile, bei der der Spaltenwert exakt „3“ ist, wird zurückgegeben.
Im Gegensatz dazu prüft FIND_IN_SET die Position eines Elements innerhalb einer kommagetrennten Liste, sodass Sie Datensätze, die „3“ enthalten, genau so abrufen können:
SELECT * FROM users WHERE FIND_IN_SET('3', favorite_ids);
✅ Wichtige Nutzungsempfehlung:
IN: Verwenden Sie sie mit normalisierten Tabellen (z. B.SELECT * FROM posts WHERE category_id IN (1, 3, 5))FIND_IN_SET: Verwenden Sie sie mit denormalisierten, kommagetrennten Zeichenketten
Vergleich mit der LIKE‑Klausel
Technisch können Sie LIKE für Teilübereinstimmungen verwenden, aber es birgt wichtige Fallstricke.
-- A common mistake with LIKE
SELECT * FROM users WHERE favorite_ids LIKE '%3%';
Diese Abfrage bedeutet nicht wirklich „enthält den Wert 3“ – sie trifft auf jede Zeichenkette zu, die das Zeichen „3“ enthält, was dazu führen kann, dass fälschlicherweise „13“, „23“ oder „30“ übereinstimmen.
Damit ist es unmöglich, zuverlässig zu erkennen, ob 3 als eigenständiger Wert existiert.
✅ Wichtige Nutzungsempfehlung:
LIKE: Nützlich für unscharfe Textsuche, erkennt jedoch keine kommagetrennten GrenzenFIND_IN_SET: Prüft genau, ob ein eigenständiger Wert in kommagetrennten Listen vorkommt
Leistungsunterschiede
| Method | Uses Index | Search Target | Speed |
|---|---|---|---|
IN | Yes | Number or single value | ◎ Very fast |
LIKE | Depends on pattern | Text scan | △ Can become slow depending on conditions |
FIND_IN_SET | No | Full scan | × May be slow |
Insbesondere kann FIND_IN_SET keine Indizes nutzen und löst häufig vollständige Tabellenscans aus. Wenn Sie mit großen Datensätzen arbeiten, sollten Sie das Schema möglicherweise überdenken.
5. Wichtige Hinweise und bewährte Verfahren
Nicht kompatibel mit Werten, die Kommas enthalten
Die FIND_IN_SET-Funktion geht von einer einfachen, durch Kommas getrennten Liste von Werten aus. Daher verhält sich die Funktion nicht wie beabsichtigt, wenn ein einzelnes Element in der Liste selbst ein Komma enthält.
Falsches Beispiel:
SELECT FIND_IN_SET('1,2', '1,2,3,4'); -- Result: 1
Die Verwendung auf diese Weise kann zu falschen Treffern führen, weil die gesamte Zeichenkette unsachgemäß ausgewertet wird.
Sie sollten diese Funktion nur verwenden, wenn Sie sicherstellen können, dass einzelne Werte keine Kommas enthalten.
Leistungsbedenken
Da FIND_IN_SET keine Indizes nutzen kann, führt es einen vollständigen Tabellenscan durch. Infolgedessen kann die Abfrageleistung bei großen Tabellen erheblich sinken.
Umgehungen:
- Anstatt kommagetrennte Werte zu speichern, normalisieren Sie die Beziehung und verwalten sie in einer separaten Tabelle.
- In leistungskritischen Umgebungen sollten Sie temporäre Tabellenerweiterungen oder JOIN-basierte Strategien in Betracht ziehen.
Zum Beispiel, wenn Sie eine Zwischentabelle wie user_favorites erstellen, können Sie Indizes für schnellere Suchen nutzen:
SELECT users.*
FROM users
JOIN user_favorites ON users.id = user_favorites.user_id
WHERE user_favorites.favorite_id = 3;
Lesbarkeit und Wartbarkeit
Obwohl FIND_IN_SET praktisch erscheinen mag, hat es mehrere Nachteile:
- Abfragen sind nicht intuitiv (sie geben Positionswerte zurück)
- Das Hinzufügen oder Entfernen von Werten ist umständlich
- Die Datenintegrität ist schwer durchzusetzen (mehrere Bedeutungen in einer einzigen Spalte)
Daher ist es, wenn Wartbarkeit und Datenintegrität wichtig sind, die Überarbeitung des Schemas selbst oft die beste Vorgehensweise.
Wenn Sie FIND_IN_SET verwenden müssen
Es gibt Situationen, in denen Sie keine andere Wahl haben, als mit kommagetrennten Spalten zu arbeiten – etwa bei Altsystemen oder Drittanbieterprodukten. In solchen Fällen sollten Sie die folgenden Vorsichtsmaßnahmen beachten:
- Zuerst andere Filterbedingungen anwenden, um den Suchbereich zu reduzieren
- Formatierungsfehler wie doppelte Kommas oder führende/abschließende Leerzeichen verhindern
- Zusätzliche Verarbeitung nach Möglichkeit in der Anwendungsschicht durchführen
6. Häufig gestellte Fragen (FAQ)
Kann FIND_IN_SET Indizes verwenden?
Nein, FIND_IN_SET kann keine Indizes verwenden. Intern teilt und bewertet es die Zeichenkette, sodass es nicht von MySQLs Indexoptimierung profitiert.
Infolgedessen kann die Verwendung auf großen Tabellen die Abfrageleistung verlangsamen. Für leistungskritische Systeme sollten Sie das Schema neu entwerfen oder die Daten normalisieren.
Funktioniert es korrekt mit gemischten Zahlen und Zeichenketten?
Im Allgemeinen ja – beachten Sie jedoch, dass Vergleiche als Zeichenketten durchgeführt werden. Wenn numerische und Zeichenkettenwerte gemischt werden, kann unerwartetes Verhalten auftreten.
Zum Beispiel geben beide der folgenden Beispiele eine Übereinstimmung für 3 zurück:
SELECT FIND_IN_SET(3, '1,2,3,4'); -- Result: 3
SELECT FIND_IN_SET('3', '1,2,3,4'); -- Result: 3
In Fällen wie FIND_IN_SET('03', '01,02,03') kann die Formatierung mit führenden Nullen das Matching-Verhalten beeinflussen.
Am sichersten ist es, die Werteformatierung zu standardisieren.
Wie kann ich nach mehreren Werten gleichzeitig suchen?
Da FIND_IN_SET nur einen einzelnen Suchwert akzeptiert, müssen Sie, wenn Sie nach Datensätzen suchen wollen, die „3 oder 4“ enthalten, es mehrmals mit OR aufrufen:
SELECT * FROM users
WHERE FIND_IN_SET('3', favorite_ids)
OR FIND_IN_SET('4', favorite_ids);
Wenn die Bedingungen komplexer werden, sollten Sie in Erwägung ziehen, SQL dynamisch in der Anwendungsschicht zu erstellen oder zu einer normalisierten Tabellenstruktur zu migrieren.
FIND_IN_SET verursacht Leistungsprobleme. Was soll ich tun?
Die folgenden Strategien sind wirksam:
- Auf ein normalisiertes Tabellendesign umsteigen
- Zuerst Filterbedingungen anwenden, um den Suchbereich zu reduzieren
- Nur bei kleinen Datensätzen verwenden
- Eine Migration zu strukturierten Formaten wie Volltextsuche oder JSON-Datentypen in Betracht ziehen
Moderne MySQL-Versionen unterstützen JSON-Datentypen. Zum Beispiel, wenn Sie die Spalte roles als JSON-Array verwalten, können Sie JSON_CONTAINS() für flexible und effiziente Suchen verwenden.
Wird FIND_IN_SET in Zukunft veraltet sein?
Seit MySQL 8.0 ist FIND_IN_SET nicht offiziell veraltet. Allerdings werden denormalisierte Datenstrukturen (kommagetrennte Spalten) nicht empfohlen, sodass die praktische Nutzung dieser Funktion voraussichtlich im Laufe der Zeit abnehmen wird.
Beim Neugestalten Ihrer Datenbank ist es ideal, normalisierte Strukturen oder JSON-basierte Designs zu übernehmen.
7. Fazit
Überprüfung der Funktionen und Vorteile von FIND_IN_SET
Die Funktion FIND_IN_SET ist außerordentlich nützlich in MySQL beim Durchsuchen kommagetrennter Zeichenketten. Sie ist besonders hilfreich, wenn Sie Datensätze extrahieren müssen, die einen bestimmten Wert in einer einzelnen Spalte mit mehreren Werten enthalten.
Mit ihrer einfachen Syntax ermöglicht sie Prüfungen auf einzelne Wertübereinstimmungen, die mit den Klauseln LIKE oder IN nur schwer exakt zu erreichen sind. Diese Fähigkeit, einzelne Elemente in einer kommagetrennten Liste zu erkennen, ist ihre größte Stärke.
Wichtige Überlegungen bei der Verwendung
Gleichzeitig gibt es mehrere Einschränkungen und wichtige Überlegungen, sodass sie nicht ohne sorgfältiges Nachdenken übermäßig verwendet werden sollte:
- Indizes können nicht verwendet werden (was die Suche verlangsamen kann)
- Nicht kompatibel mit Werten, die Kommas enthalten
- Geht von einer denormalisierten Struktur aus
- Unterstützt nur Ein‑Wert‑Suchen (mehrere Suchen erfordern
OR‑Bedingungen)
Das Verständnis dieser Eigenschaften ist entscheidend, um die Funktion angemessen zu nutzen.
Wann Sie sie verwenden sollten — und wann nicht
| Situation | Should You Use It? | Reason |
|---|---|---|
| Small dataset, infrequent searches | ✅ Yes | Easy to implement and low development cost |
| Dependent on a legacy system structure | ✅ Use selectively | Useful when refactoring is difficult |
| Large dataset, high-frequency access | ❌ Not recommended | Performance degradation becomes significant |
| Schema can be normalized | ❌ Avoid | JOINs or intermediate tables are more efficient |
Wie man das in der Praxis anwendet
- Betrachten Sie es als flexibles Werkzeug, um innerhalb bestehender Datenbankstrukturen zu arbeiten
- Nutzen Sie es als Referenzpunkt bei der Entscheidung, ob künftig ein normalisiertes Datenmodell eingeführt werden soll
- Anstatt es als Schnelllösung zu verwenden, sollten Sie genau verstehen, was die Funktion tatsächlich bewirkt
Für Entwickler, die Wartbarkeit und Lesbarkeit priorisieren, ist es am besten, diese Funktion als etwas zu betrachten, das Sie „vorübergehend verwenden – aber schließlich ablegen“ sollten.


