0

私のサイトには、さまざまな主題に関するリンクのコレクションが表示されます。これらのリンクは、Web と画像の 2 つのタイプに分けられます。私のデータベースには、これらのレコードが数百万 (おそらく 1,000 万以上) 含まれます。ページが読み込まれるときに、そのページの特定の主題に関する Web リンクと画像リンクをユーザーに表示する必要があります。最初の質問は次のとおりです。

  1. Web リンクと画像リンク用にそれぞれ 1 つずつ、2 つの別個の小さなテーブルを作成し、それぞれに対してクエリを作成するか、または両方に対して 1 つの巨大なテーブル (正しいインデックスを使用) を作成し、1 つのクエリを作成しますか。どこでより良いパフォーマンスを得ることができますか? 1 つのテーブルと 1 つのクエリがより効率的である場合、次の質問は次のとおりです。

  2. プレゼンテーションのために 2 つのタイプを細分化する最も効率的な方法は何でしょうか? group by結果配列を 2 つのタイプに分割するには、 を使用する必要がありますか、それとも php を使用する必要がありますか?

ティア!

4

4 に答える 4

3

すべてのオブジェクトのテーブル、またはリンクやWebサイトのテーブルを使用して同様のパフォーマンスを得ることができます。2つの別々のテーブルがある場合、結果のUNIONを実行すると、必要なすべての結果が返されます。

結果を分割する主な理由は、結果が本当に異なるかどうかです(アプリケーションの観点から)。つまり、次のような多くのクエリを使用することになります。

select * from objects where type='image';

次に、2つのテーブルを用意するのが理にかなっているかもしれません。

次に、group byを使用することは、さまざまな結果をグループ化する方法ではなく、それらを集約する方法です。

したがって、たとえば、

select type, count(*) from objects group by type

取得するため

| image |  100000 |
| web   | 2000000 |

ただし、分離されたオブジェクトは返されません。それらを「グループ化」するには、それぞれにクエリを使用するか、順序付けを使用して、結果を分割するロジックをアプリケーションに含めることができます。

于 2013-03-03T10:39:21.127 に答える
1

1 つのテーブルだけでわずかにパフォーマンスが向上する可能性がありますが、この決定は主に、データまたは制約の性質が異なるかどうかによって判断する必要があります。

もう 1 つ (パフォーマンスの観点からより重要な) 決定を下す必要があります: データをどのようにクラスター化しますか (すべてのInnoDB テーブルはクラスター化されます)?

特定のページのすべてのリンクを取得する優れたパフォーマンスが必要な場合は、識別関係を使用して、リンク テーブルに自然なキーを生成します。

ここに画像の説明を入力

LINK テーブルは事実上、ページ PK 1がその前縁にある単一の B ツリーであり、同じページに属する行を物理的にグループ化します。次のクエリは、単純なインデックス レンジ スキャンと最小限の I/O で満たすことができます。

SELECT URL
FROM LINK
WHERE PAGE_ID = <whatever>

別々のテーブルを使用した場合は、2 つの異なるクエリを使用できます。多くのクライアント API は、1 回のデータベース ラウンドトリップでの 2 つのクエリの実行をサポートしています。PHP がそうでない場合は、2 つのクエリを UNION して、1 つのデータベース ラウンドトリップを節約できます。

SELECT *
FROM (
    SELECT 1 LINK_TYPE, URL
    FROM IMAGE_LINK
    WHERE PAGE_ID = <whatever>
    UNION ALL
    SELECT 2, URL
    FROM WEB_LINK
    WHERE PAGE_ID = <whatever>
)
ORDER BY LINK_TYPE

上記のクエリはあなたに...

LINK_TYPE  URL
1          http://somesite.com/foo.jpeg
1          http://somesite.com/bar.jpeg
1          http://somesite.com/baz.jpeg
...
2          http://somesite.com/foo.html
2          http://somesite.com/bar.html
2          http://somesite.com/baz.html
...

...これは、クライアント レベルで簡単に分離できます。

個別のテーブルを使用しなかった場合は、クライアント レベルで拡張子によって URL を分離するか、LINK PK に追加のフィールド {PAGE_ID, LINK_TYPE, URL} を導入することができます。これにより、次のクエリが非常に効率的になります。

SELECT LINK_TYPE, URL
FROM LINK
WHERE PAGE_ID = <whatever>
ORDER BY LINK_TYPE

PK 内のフィールドの順序は重要であるため、LINK_TYPE を最後に配置すると、DBMSがインデックス範囲スキャンを実行できなくなることに注意してください。


1それが何であれ; PAGE_IDを例として使用しただけです。

于 2013-03-03T14:03:27.903 に答える
1

Web データが img データにどのように近いかによって異なります。データが基本的にリンクで構成されている場合、ウェブとデータを区別するための列を持つ 1 つのテーブルがより適切に適合します (そして、css、js などの後で他のものも可能です)。

Links: (id, link, type)

タイプまたはタイプ リンクにインデックスを追加すると、(タイプによる) グループ化と、(タイプ、リンク) による一致検索に役立ちます。

ただし、web と img のデータが異なるため、リンゴとオレンジを混ぜたくない場合は、次のようにします。

Web: (wid, wlink, rating, ...)
Img: (iid, ilink, width, height, mbsize, camera, datetaken, hasexif...)

この場合、リンクを除けば、両方のテーブルに共通点はあまりありません。画像リンクと Web リンクは異なるため、両方の種類のデータに同じリンクを使用しても「利益」はありません。もう 1 つの利点 (これは 1 つのテーブルでも可能ですが、ここではより理にかなっています) は、別のテーブルで両方の種類のデータをリンクできることです。

 Relations: (wid,iid)

画像は複数の Web サイトで使用される可能性があり、Web サイトは複数の画像を使用するため、Web サイトと画像の間の関係を維持することができます。にインデックスを付けwidますiid

私の好みは 2 つのテーブル (オプションの関係リンク付き) です。

PHP からのクエリに関してUNIONは、1 つのクエリで 2 つのテーブルからデータを取得することができます。

于 2013-03-03T10:57:49.637 に答える
0

2つの別々の小さなテーブルを作成しますか、それとも1つの大きなテーブルを作成しますか?

1つのテーブルに行きます。

プレゼンテーションのために2つのタイプを細分化する最も効率的な方法は何でしょうか?

特定の検索条件 によって異なります。

于 2013-03-03T10:27:24.227 に答える