Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Mustervergleich mit mysql zwischen zwei Tabellenspalten

Zwei Fragen – sind die Beschreibungen Standard (Beschreibungen ändern sich nicht) oder werden sie von einem Benutzer eingegeben? Wenn sie Standard sind, fügen Sie eine Spalte hinzu, die eine Ganzzahl ist, und vergleichen Sie diese Spalte.

Wenn es vom Benutzer eingegeben wird, ist Ihre Arbeit komplizierter, weil Sie nach etwas suchen, das eine unscharfere Suche ist. Ich habe einen Bi-Gramm-Suchalgorithmus verwendet, um die Ähnlichkeit zwischen zwei Zeichenfolgen einzustufen, aber dies kann nicht direkt in mySQL erfolgen.

Anstelle einer Fuzzy-Suche könnten Sie LIKE verwenden, aber die Effizienz beschränkt sich auf die Durchführung von Tabellenscans, wenn Sie am Ende das '%' am Anfang des Suchbegriffs setzen. Außerdem bedeutet dies, dass Sie eine Übereinstimmung für den von Ihnen gewählten Teilstring erhalten können, was bedeutet, dass Sie den Teilstring im Voraus kennen müssen.

Ich erläutere gerne mehr, sobald ich weiß, was Sie zu tun versuchen.

EDIT1:Ok, angesichts Ihrer Ausarbeitung müssen Sie, wie ich erwähnt habe, eine Suche im Fuzzy-Stil durchführen. Ich verwende eine Bi-Gramm-Methode, bei der jeder vom Benutzer vorgenommene Eintrag in Blöcke von 2 oder 3 Zeichen aufgeteilt wird. Ich speichere dann jeden dieser Chunks in einer anderen Tabelle, wobei jeder Eintrag auf die eigentliche Beschreibung zurückgeführt wird.

Beispiel:

Beschreibung1:"Ein schneller Lauf nach vorne"Beschreibung2:"Ein kurzer Lauf nach vorne"

Wenn Sie jedes in 2 Zeichenblöcke aufteilen - 'A', 'f', 'fa', 'as', 'st'.....

Dann können Sie die Anzahl der 2-Zeichen-Blöcke vergleichen, die mit beiden Zeichenfolgen übereinstimmen, und eine "Punktzahl" erhalten, die Genauigkeit oder Ähnlichkeit zwischen den beiden andeutet.

Da ich nicht weiß, welche Entwicklungssprache Sie verwenden, lasse ich die Implementierung weg, aber das ist etwas, das nicht explizit in mySQL gemacht werden muss.

Oder die faule Alternative wäre die Verwendung eines Cloud-Suchdienstes wie Amazon, der eine Suche basierend auf den von Ihnen angegebenen Begriffen bereitstellt kann ein bisschen teuer sein (IMHO).

R

Für einen weiteren SO-Beitrag zur Bigramm-Implementierung - siehe diesen SO-Bigramm/Fuzzy-Suche

--- Aktualisierung pro Ausarbeitung des Fragestellers ---

Erstens gehe ich davon aus, dass Sie die Theorie zu den von mir bereitgestellten Links gelesen haben gut)

Ok, also funktioniert die Bigramm-Methode beim Erstellen/Vergleichen von In-Memory-Arrays nur, wenn die möglichen Übereinstimmungen relativ klein sind, andernfalls leidet sie ziemlich schnell unter einer Table-Scan-Leistung wie eine MySQL-Tabelle ohne Indizes. Sie werden also die Stärken der Datenbank nutzen, um die Indizierung für Sie zu erledigen.

Was Sie brauchen, ist eine Tabelle, die die vom Benutzer eingegebenen "Begriffe" oder den Text enthält, den Sie vergleichen möchten. Die einfachste Form ist eine Tabelle mit zwei Spalten, eine ist eine eindeutige Autoinkrement-Ganzzahl, die indiziert wird, wir nennen unten hd_id, die zweite ist ein varchar(255), wenn die Zeichenfolgen ziemlich kurz sind, oder TEXT, wenn sie können lang werden - Sie können dies benennen, was Sie wollen.

Dann müssen Sie eine weitere Tabelle mit mindestens DREI Spalten erstellen – eine für die Referenzspalte zurück zur automatisch inkrementierten Spalte der anderen Tabelle (wir nennen diese unten hd_id), die zweite wäre eine varchar() von Sagen wir höchstens 5 Zeichen (dies wird Ihre Bigramm-Blöcke enthalten), die wir unten "Bigramm" nennen, und die dritte eine automatisch inkrementierende Spalte namens b_id unten. Diese Tabelle enthält alle Bigramme für den Eintrag jedes Benutzers und knüpft an den Gesamteintrag an. Sie sollten die varchar-Spalte allein indizieren (oder zuerst in der Reihenfolge in einem zusammengesetzten Index).

Jedes Mal, wenn ein Benutzer einen Begriff eingibt, den Sie suchen möchten, müssen Sie den Begriff in die erste Tabelle eingeben, dann den Begriff in Bigramme zerlegen und jeden Teil in die zweite Tabelle eingeben, indem Sie den Verweis auf den Gesamtbegriff in verwenden erste Tabelle, um die Beziehung zu vervollständigen. Auf diese Weise führen Sie die Dissektion in PHP durch, lassen aber mySQL oder eine andere Datenbank die Indexoptimierung für Sie erledigen. In der Bigrammphase kann es hilfreich sein, die Anzahl der in Tabelle 1 erstellten Bigramme für die Berechnungsphase zu speichern. Unten ist etwas Code in PHP, um Ihnen eine Vorstellung davon zu geben, wie man die Bigramme erstellt:

// split the string into len-character segments and store seperately in array slots
function get_bigrams($theString,$len)   
{
   $s=strtolower($theString);
   $v=array();
   $slength=strlen($s)-($len-1);     // we stop short of $len-1 so we don't make short chunks as we run out of characters

   for($m=0;$m<$slength;$m++)
   {
      $v[]=substr($s,$m,$len);
   }
   return $v;
}    

Machen Sie sich keine Gedanken über Leerzeichen in den Zeichenfolgen - sie sind tatsächlich sehr hilfreich, wenn Sie an Fuzzy-Suche denken.

Sie erhalten also die Bigramme, tragen sie in eine Tabelle ein, die über eine indizierte Spalte mit dem Gesamttext in Tabelle 1 verknüpft ist ... was nun?

Wann immer Sie jetzt nach einem Begriff wie "Mein Lieblingsbegriff zum Suchen" suchen, können Sie die PHP-Funktion verwenden, um ihn in ein Array von Bigrammen umzuwandeln. Sie verwenden dies dann, um den IN (..)-Teil einer SQL-Anweisung in Ihrer Bigrammtabelle zu erstellen(2). Unten ist ein Beispiel:

select count(b_id) as matches,a.hd_id,description, from table2 a
inner join table1 b on (a.hd_id=b.hd_id)
where bigram in (" . $sqlstr . ")
group by hd_id order by matches desc limit X

Ich habe $sqlstr als PHP-String-Referenz belassen - Sie könnten dies selbst als eine durch Kommas getrennte Liste aus der Bigram-Funktion erstellen, indem Sie implode oder was auch immer auf dem von get_bigrams zurückgegebenen Array verwenden oder parametrisieren, wenn Sie möchten.

Bei richtiger Ausführung gibt die obige Abfrage abhängig von der Länge des von Ihnen gewählten Bigramms die am ehesten übereinstimmenden Fuzzy-Suchbegriffe zurück. Die von Ihnen gewählte Länge hat eine relative Wirksamkeit basierend auf Ihrer erwarteten Länge der gesamten Suchzeichenfolgen.

Schließlich - die obige Abfrage gibt nur einen Fuzzy-Match-Rang an. Sie können damit herumspielen und verbessern, indem Sie nicht nur Übereinstimmungen vergleichen, sondern Übereinstimmungen mit der Gesamtzahl der Bigramme vergleichen, was dazu beiträgt, lange Suchzeichenfolgen im Vergleich zu kurzen Zeichenfolgen zu entzerren. Ich habe hier aufgehört, weil es an dieser Stelle viel anwendungsspezifischer wird.

Hoffe, das hilft!

R