sql >> データベース >  >> RDS >> Mysql

2つのテーブル列間でmysqlと比較するパターン

    2つの質問-説明は標準ですか(説明は変更されません)、それともユーザーが入力しますか?標準の場合は、整数の列を追加して、この列を比較します。

    ユーザーが入力した場合、よりあいまいな検索であるものを探しているため、作業はより複雑になります。バイグラム検索アルゴリズムを使用して2つの文字列間の類似性をランク付けしましたが、これをmySQLで直接実行することはできません。

    あいまい検索の代わりにLIKEを使用することもできますが、検索語の先頭に「%」を付けると、効率はテーブルスキャンの実行に制限されます。また、選択した部分文字列部分で一致する可能性があることを意味します。つまり、事前に部分文字列を知っておく必要があります。

    あなたが何をしようとしているのかがわかったら、もう少し詳しく説明したいと思います。

    編集1:わかりました、あなたの詳細を考えると、私が述べたようにファジースタイルの検索を行う必要があります。私はバイグラム方式を使用しています。この方式では、ユーザーが作成した各エントリを取得し、2文字または3文字のチャンクに分割します。次に、これらの各チャンクを別のテーブルに保存し、各エントリを実際の説明にキーバックします。

    例:

    説明1:「早送り」説明2:「早送り」

    それぞれを2文字のチャンクに分割すると-'A'、'f'、'fa'、'as'、'st' .....

    次に、両方の文字列に一致する2文字のチャンクの数を比較して、2つの間の正確性または類似性を示す「スコア」を取得できます。

    使用している開発言語がわからないため、実装は省略しますが、これはmySQLで明示的に実行する必要がないものです。

    または、怠惰な代替手段は、Amazonのようなクラウド検索サービスを使用して、指定した用語に基づいて検索を提供することです...ただし、検討する新しい説明を継続的に追加できるかどうかはわかりませんが、アプリケーションによっては、少しコストがかかる可能性があります(IMHO)。

    R

    バイグラムの実装に関する別のSO投稿については、このSOバイグラム/あいまい検索<を参照してください。 / a>

    ---質問者ごとの詳細を更新---

    まず、私が提供したリンクの理論を読んでいると仮定します。次に、mySQLを必要としないため、DBにとらわれないようにします(私はそれを使用していますが、それ以上に機能します)罰金)

    わかりました。したがって、バイグラムメソッドは、一致する可能性が比較的小さい場合にのみ、メモリ内配列の作成/比較で問題なく機能します。そうでない場合は、インデックスのないmysqlテーブルのようなテーブルスキャンパフォーマンスがかなり速く低下します。したがって、データベースの長所を使用して、インデックス作成を支援します。

    必要なのは、比較しようとしているユーザーが入力した「用語」またはテキストを保持するための1つのテーブルです。最も単純な形式は、2つの列を持つテーブルです。1つはインデックス付けされる一意の自動インクリメント整数です。以下でhd_idと呼びます。2つ目は、文字列がかなり短い場合はvarchar(255)、可能な場合はTEXTです。長くなる-これには好きな名前を付けることができます。

    次に、少なくとも3つの列を持つ別のテーブルを作成する必要があります。1つは他のテーブルの自動インクリメント列に戻る参照列用であり(以下ではこのhd_idと呼びます)、2番目はvarchar()になります。以下で「bigram」と呼ぶ最大5文字(これはバイグラムチャンクを保持します)と言い、3番目は以下のb_idと呼ばれる自動インクリメント列です。このテーブルには、各ユーザーのエントリのすべてのバイグラムが保持され、エントリ全体に関連付けられます。 varchar列に単独で(または複合インデックスで最初に)インデックスを付ける必要があります。

    これで、ユーザーが検索する用語を入力するたびに、最初のテーブルにその用語を入力し、次にその用語をバイグラムに分解し、の全体的な用語への参照を使用して各チャンクを2番目のテーブルに入力する必要があります。関係を完了するための最初のテーブル。このように、PHPで分析を行っていますが、mySQLまたはその他のデータベースにインデックスの最適化を行わせています。バイグラムフェーズでは、計算フェーズで表1に作成されたバイグラムの数を保存すると役立つ場合があります。以下は、バイグラムの作成方法に関するアイデアを提供するPHPのコードです。

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

    文字列内のスペースについて心配する必要はありません。あいまい検索について考える場合、実際にはスペースが非常に役立ちます。

    それで、あなたはバイグラムを手に入れ、それらをテーブルに入力し、テーブル1のテキスト全体にリンクされ、インデックス付きの列を介して...今何ですか?

    これで、「検索するのが好きな用語」などの用語を検索するときはいつでも、php関数を使用してそれをバイグラムの配列に変換できます。次に、これを使用して、バイグラムテーブル(2)にSQLステートメントのIN(..)部分を作成します。以下に例を示します:

    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
    

    $ sqlstrをPHP文字列参照として残しました。これは、implodeなどを使用してbigram関数からコンマ区切りのリストとして作成するか、get_bigramsから返された配列にあるものを使用するか、必要に応じてパラメーター化することができます。

    正しく実行された場合、上記のクエリは、選択したバイグラムの長さに応じて、最も一致するあいまい検索用語を返します。選択した長さは、検索文字列全体の予想される長さに基づいた相対的な効果があります。

    最後に-上記のクエリは、あい​​まい一致ランクを与えるだけです。一致だけでなく、一致と全体的なバイグラム数を比較することで、遊んで強化することができます。これにより、短い文字列と比較して長い検索文字列のバイアスを取り除くことができます。この時点でアプリケーション固有になるため、ここで停止しました。

    これがお役に立てば幸いです!

    R




    1. 致命的:ユーザーpostgresのパスワード認証に失敗しました(pgAdmin4を使用したpostgresql11)

    2. SQLite-テーブルを変更する

    3. 2つのテーブル間の1対多の関係に対するOracleSELECTQUERY

    4. mysqli_real_escape_stringと二重引用符の問題