sql >> Database teknologi >  >> RDS >> Mysql

Mønster sammenligner med mysql mellem to tabeller kolonne

To spørgsmål - er beskrivelserne standard (beskrivelserne ændres ikke) eller er de indtastet af en bruger? Hvis de er standard, tilføj en kolonne, der er et heltal, og lav sammenligning på denne kolonne.

Hvis det indtastes af brugeren, er dit arbejde mere kompliceret, fordi du leder efter noget, der er mere fuzzy søgning. Jeg brugte en bi-gram søgealgoritme til at rangordne ligheder mellem to strenge, men dette kan ikke gøres direkte i mySQL.

I stedet for en fuzzy søgning kan du bruge LIKE, men dets effektivitet er begrænset til at lave tabelscanninger, hvis du ender med at sætte '%' i begyndelsen af ​​søgeordet. Det indebærer også, at du kan få et match på den delstreng, du vælger, hvilket betyder, at du skal kende understrengen på forhånd.

Jeg vil med glæde uddybe mere, når jeg ved, hvad du prøver at gøre.

EDIT1:Ok, givet din uddybning, bliver du nødt til at lave en fuzzy stilsøgning, som jeg nævnte. Jeg bruger en bi-gram metode, som involverer at tage hver indtastning lavet af brugeren og opdele den i bidder af 2 eller 3 tegn. Jeg gemmer derefter hver af disse bidder i en anden tabel med hver indtastning tastet tilbage til den faktiske beskrivelse.

Eksempel:

Beskrivelse1:"Et hurtigt løb fremad"Beskrivelse2:"Et kort løb fremad"

Hvis du deler hver op i 2 char-bidder - 'A', 'f', 'fa', 'as', 'st'.....

Derefter kan du sammenligne antallet af 2 char chunks, der matcher begge strenge og få en "score", som vil konnotere nøjagtighed eller lighed mellem de to.

Da jeg ikke ved hvilket udviklingssprog du bruger, vil jeg udelade implementeringen, men dette er noget, der skal gøres ikke eksplicit i mySQL.

Eller det dovne alternativ ville være at bruge en cloud-søgetjeneste, som Amazon har, der vil give søgning baseret på termer, du giver den ... ikke sikker på, om de giver dig mulighed for løbende at tilføje nye beskrivelser, du skal overveje, og afhængigt af din applikation, kan være lidt dyrt (IMHO).

R

For endnu et SO-indlæg om bigram-implementeringen - se denne SO bigram / fuzzy søgning

--- Opdatering pr. spørger uddybning---

For det første går jeg ud fra, at du læser teorien på de links, jeg har givet.. for det andet vil jeg prøve at holde det så DB-agnostisk som muligt, da det ikke har brug for mySQL (selvom jeg bruger det, og det virker mere end fint)

Ok, så bigram-metoden fungerer kun ok med at lave/sammenligne arrays i hukommelsen, hvis de mulige matches er relativt små, ellers lider den ret hurtigt under en tabelscanningsydelse som en mysql-tabel uden indekser. Så du kommer til at bruge databasestyrkerne til at hjælpe med at lave indekseringen for dig.

Det, du har brug for, er en tabel til at holde brugeren indtastede "vilkår" eller tekst, som du ønsker at sammenligne. Den enkleste form er en tabel med to kolonner, den ene er et unikt automatisk inkrement heltal, som vil blive indekseret, vi kalder hd_id nedenfor, den anden er en varchar(255), hvis strengene er ret korte, eller TEXT, hvis de kan bliv lang - du kan navngive dette, hvad du vil.

Derefter skal du lave en anden tabel, der har mindst TRE kolonner - en for referencekolonnen tilbage til den anden tabels auto-inkrementerede kolonne (vi kalder denne hd_id nedenfor), den anden ville være en varchar() af sige højst 5 tegn (dette vil holde dine bigram bidder), som vi kalder "bigram" nedenfor, og den tredje en auto-inkrementerende kolonne kaldet b_id nedenfor. Denne tabel vil indeholde alle bigrammer for hver brugers post og binde tilbage til den overordnede post. Du ønsker at indeksere varchar-kolonnen alene (eller først i rækkefølge i et sammensat indeks).

Nu, hver gang en bruger indtaster en term, du vil søge, skal du indtaste termen i den første tabel, derefter dissekere termen den i bigrammer og indtaste hver del i den anden tabel ved at bruge referencen tilbage til den overordnede term i første tabel for at fuldføre forholdet. På denne måde laver du dissektionen i PHP, men lader mySQL eller hvilken som helst database gøre indeksoptimeringen for dig. Det kan hjælpe i bigramfasen at gemme antallet af bigram lavet i tabel 1 til beregningsfasen. Nedenfor er noget kode i PHP for at give dig en idé om, hvordan du opretter bigrammerne:

// 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;
}    

Du skal ikke bekymre dig om mellemrum i strengene - de er faktisk virkelig nyttige, hvis du tænker på fuzzy søgning.

Så du får bigrammerne, indtast dem i en tabel, linket til den overordnede tekst i tabel 1 via og indekseret kolonne...hvad nu?

Når du nu søger efter et udtryk som "Mit yndlingsudtryk at søge efter" - kan du bruge php-funktionen til at omdanne det til en række bigrammer. Du bruger så dette til at oprette IN (..) delen af ​​en SQL-sætning på din bigram-tabel(2). Nedenfor er et eksempel:

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

Jeg har efterladt $sqlstr som en PHP-strengreference - du kan selv konstruere denne som en kommasepareret liste fra bigram-funktionen ved at bruge implode eller hvad som helst på arrayet, der returneres fra get_bigrams eller parameterisere, hvis du også vil.

Hvis det udføres korrekt, returnerer forespørgslen ovenfor de mest matchede fuzzy søgetermer afhængigt af længden af ​​det bigram, du valgte. Den længde, du vælger, har en relativ effektivitet baseret på din forventede længde af de overordnede søgestrenge.

Til sidst - forespørgslen ovenfor giver bare en fuzzy match rank. Du kan lege med og forbedre ved at sammenligne ikke kun matches, men matches vs. det samlede antal bigram, hvilket vil hjælpe med at fjerne skævvridning af lange søgestrenge sammenlignet med korte strenge. Jeg er stoppet her, fordi det på dette tidspunkt bliver meget mere applikationsspecifikt.

Håber dette hjælper!

R




  1. Hvordan får man optælling af personer baseret på aldersgrupper ved hjælp af SQL-forespørgsel i Oracle-databasen?

  2. Mysql ændre UNSIGNED attribut til specifik kolonne

  3. Brug SQL-stil forespørgsel i Excel ved hjælp af VBA

  4. Brug af My SQL joins