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

php / mysqlにSOと同様のタグ付けシステムを実装するにはどうすればよいですか?

    時期尚早の最適化に入る前に モードの場合、次のクエリテンプレートを調べると便利な場合があります。他に何もなければ、これは可能な最適化の有効性を測定できるベースラインとして使用できます。

    SELECT T.Tagid, TagInfo.TagName,  COUNT(*)
    FROM Items I
    JOIN Tags TagInfo ON TagInfo.TagId = T.TagId
    JOIN ItemTagMap T  ON I.ItemId = T.ItemId 
    --JOIN ItemTagMap T1 ON I.ItemId = T1.ItemId
    WHERE I.ItemId IN
      (
          SELECT ItemId 
          FROM Items
          WHERE   -- Some typical initial search criteria
             Title LIKE 'Bug Report%'   -- Or some fulltext filter instead...
             AND  ItemDate > '02/22/2008'
             AND  Status = 'C'
      )
    --AND T1.TagId = 'MySql'
    GROUP BY T.TagId, TagInfo.TagName
    ORDER BY COUNT(*) DESC
    

    サブクエリは「駆動クエリ」、つまりエンドユーザーの初期基準に対応するクエリです。 (このクエリの詳細については、最適化されたフロー全体に複数回必要となる可能性があります)コメントされているのはT1(および、複数のタグが選択されている場合はT2、T3)のJOINであり、WHERE句を使用すると、基準。これらは、最初の検索の一部として、または絞り込みによって、ユーザーが特定のタグを選択するときに必要になります。 (これらの結合とwhere句をサブクエリ内に配置する方が効率的かもしれません。これらについては以下で詳しく説明します)

    ディスカッション... 「運転クエリ」またはそのバリエーションは、2つの異なる目的のために必要です。

    • 1は完全なを提供します 関連するすべてのタグを列挙するために必要なItemIdのリスト。

    • 2は、アイテムテーブルでアイテムの詳細情報を検索するために、最初のN個のItemId値(Nは表示ページサイズ)を提供します。

    完全なリストを並べ替える必要はないことに注意してください(または別の順序で並べ替えると便利な場合があります)。そのため、2番目のリストは、ユーザーの選択に基づいて並べ替える必要があります(たとえば、日付、降順、またはタイトル、アルファベット順)。 )。また、ソート順が必要な場合、クエリのコストは完全なリストを処理することを意味することに注意してください(SQL自体による奇妙な最適化や非正規化の恥ずかしがり屋、SQLはそのリストの最後のレコードを「見る」必要があります、それらがトップに属する場合は、ソートごとに)。

    この後者の事実は、両方の目的でまったく同じクエリを使用することを支持しており、対応するリストを一時テーブルに格納できます。一般的なフローは、上位N個のアイテムレコードとその詳細をすばやく検索し、これを一度にアプリケーションに返すことです。その後、アプリケーションはajax-fashionに改良用のタグのリストを取得できます。このリストは、上記のようなクエリで作成され、サブクエリは「select*fromtemporaryTable」に置き換えられます。 SQLオプティマイザがこのリストを(場合によっては)並べ替えることを決定する可能性は高く、2番目に推測して明示的に並べ替えるのではなく、そうさせましょう。

    考慮すべきもう1つのポイントは、上記のようにではなく、ItemTagMapテーブルの結合を「駆動クエリ」内に持ってくることです。パフォーマンスと、2番目の目的(アイテムのページの表示)に適したリストが生成されるため、これを行うのがおそらく最善です。

    上記のクエリ/フローは、比較的控えめなハードウェアでも、かなり適切に拡張できる可能性があります。暫定的に20万以上のアイテムに分類され、ユーザーの検索が持続する場合は、1秒あたり最大10回になる可能性があります。重要な要素の1つは、最初の検索条件の選択性です。

    最適化のアイデア

    • [一般的な検索ケースとデータ統計に応じて]Itemsのフィールドの一部をItemTagMapテーブルに移動(実際に複製)することで非正規化することが理にかなっている場合があります。特に短いフィールドは「ようこそ」かもしれません。
    • データが数百万以上のアイテムで増加するにつれて、さまざまなトリックを使用して、一部のタグの通常の強い相関関係を悪用する可能性があります(例:SOでは、PHPにはMySqlが付属していることがよくありますが、理由はありません...)。たとえば、「マルチタグ」TagIdを導入すると、入力ロジックが少し複雑になる可能性がありますが、マップサイズを大幅に縮小する可能性もあります。


    -'大体言った! -
    実際の要件と効果的なデータ統計プロファイルを考慮して、適切なアーキテクチャと最適化を選択する必要があります...



    1. エラーコード1005、SQL状態HY000:テーブルを作成できませんerrno:150

    2. ActiveRecordエラー:SAVEPOINTactive_record_1が存在しません

    3. DBMS_OUTPUT.PUT_LINEの出力をファイルにリダイレクトするにはどうすればよいですか?

    4. データベースプロバイダータイプごとに許可されるパラメーターの最大数はいくつですか?