Verwenden Sie eine Form von Fuzzy-Matching. Dies wird höchstwahrscheinlich auch keine Vorteile aus Indizes ziehen. Es gibt Tom Haighs Vorschlag, der die Zeile in Ihrem Beispiel finden wird, aber auch falsche Positive zurückgeben kann.Sie könnten auch REGEXP
/RLIKE
verwenden, die Fuzzy Matching nicht ausführen, aber Sie können einen Ausdruck erstellen, die funktioniert:
$tracklist=preg_replace('/[^a-z]+/i', '[^[=a=]]+', $_REQUEST['did']);
$q = mysqli_query($id,"SELECT * FROM `mixes` WHERE `tracklist` REGEXP '$tracklist'");
das Beispiel verwenden $_REQUEST['did']
von ‚johnny hey Johnnny‘, die resultierende Abfrage * FROM Mixes „SELECT wird WO tracklist
REGEXP 'John [^ [= a =]] + hey [^ [= a =]] + Johnnny' ". Das obige ignoriert nicht alphabetische Zeichen. Wenn Sie möchten, nicht-alphanumerische Zeichen ignorieren, versuchen Sie eine der folgenden (die zweite nicht ignorieren ‚_‘):
$tracklist=preg_replace('/[^a-z0-9]+/i', '[^[:alnum:]]+', $_REQUEST['did']);
$tracklist=preg_replace('/\W+/', '[^[:alnum:]_]+', $_REQUEST['did']);
Umstrukturieren die Tabellen und Verarbeitungslogik. Dies ist die meiste Arbeit, wird aber die konzeptionell sauberste Implementierung hervorbringen. Ich nehme an, dass tracklist
eine $ delim (zB Komma, Semikolon, ...) getrennte Liste von Titelnamen ist. Wenn ja, mixes
ist nicht einmal . Erstellen Sie eine neue tracklist
Tabelle:
CREATE TABLE `tracklist` (
mix INTEGER REFERENCES mixes (id),
position INTEGER NOT NULL,
track INTEGER REFERENCES tracks (id),
PRIMARY KEY (mix, position),
KEY (mix, track),
KEY (track)
) ENGINE=InnoDB;
Um die Mischung für eine bestimmte Spur zu finden, führen Sie einen Join:
SELECT mixes.* FROM mixes
JOIN tracklist
ON mixes.id = tracklist.mix
WHERE tracklist.track=$trackid
Durch die Verwendung von Indizes, die obige Abfrage wird schneller sein als die beiden anderen Optionen . Der Hauptnachteil dieses Ansatzes besteht darin, dass Sie mehr Abfragen durchführen müssen, um die Trackliste für einen Mix zu erhalten. Ein Vorteil ist, dass die Bearbeitung der Trackliste verbessert werden kann. Bei entsprechend definierten Indizes kann diese Option immer noch schneller sein als Ihr aktuelles DB-Design. Zum Beispiel
SELECT t2.mix, t2.position, tracks.*
FROM tracklist AS t1
JOIN tracklist AS t2
ON t1.mix = t2.mix
JOIN tracks
ON t2.track = tracks.id
WHERE t1.track=:trackid
wird sehr effizient sein, wenn es Indizes auf tracklist.tracks
, tracklist.mix
und tracks.id
, die eine sehr vernünftige Annahme ist, angesichts der obigen Definition von tracklist
und dass track.id
ist höchstwahrscheinlich eine Primärschlüsselspalte. MySQL muss nur (number of mixes containing track :trackid) + (total number of tracks in all mixes that contain :trackid) * 2 rows
untersuchen. Wenn es zwei Mischungen gibt, die "Johnny, Hey (johnnny)" mit 8 bzw. 10 Spuren enthalten, untersucht MySQL 38 Zeilen insgesamt (20 von tracklist
und 18 von tracks
). Die Optionen 1 und 2 müssen (number of mixes)
Zeilen untersuchen. Solange die Anzahl der Mixe viel größer als die durchschnittliche Mix-Größe ist und die gesuchte Spur in vielen Mischungen nicht angezeigt wird, ist diese Option schneller als die anderen beiden.
Nicht sicher, dass ich folge. Bitte klären Sie? Wo formatierst du die Zeichenfolge (wie oben in der dritten Zeile deines Posts erwähnt) und woher bekommst du die Eingabe? –
Sie versuchen also, eine Spalte abzufragen, die Fremdzeichen enthalten kann oder nicht, und möchten die Tabelle ohne diese überflüssigen (d. H. Nicht alphabetischen) Zeichen durchsuchen? –
Die Zeichenfolge kommt aus einer anderen MySQL Tabelle, aber es wird gestreift von seinem - und(), ich muss die Zeile mit John - Hey (johnnny) ziehen, aber ohne die - und die() wenn das möglich ist –