0

最終的に何百万人ものユーザーを持つシステムを開発しています。システムの各ユーザーは、システム内のさまざまな「タブ」にアクセスできます。usertabs というテーブルでこれを追跡しています。これを処理するには 2 つの方法があります。

方法 1: ユーザー ID と tab1-tab10 を int 列として含む各ユーザーの単一行。

このシステムの利点は、ユーザー ID で単一の行を取得するクエリが非常に高速であることですが、欠点は「空の」列がスペースを占有することです。別の欠点は、新しいタブを追加する必要があるときに、テーブル全体を再編成する必要があることです。これは、何百万ものレコードがある場合、面倒な作業になる可能性があります。しかし、これはあまり頻繁には起こりません。

方法 2: 1 つの行に userid と tabid が含まれているだけです。ユーザーごとに最大 10 行あります。

このシステムの利点は、最適化されたストレージと無駄なスペースがないための簡単なシャーディングまたはその他のメカニズムです。行は必要な場合にのみ存在します。欠点は、レコードにアクセスするたびに最大 10 行を読み取る必要があることです。これらの行が散らばっている場合、保存方法によっては、アクセスが遅くなったり、速くなったりする可能性がありますか?

私のプログラマー側は方法 1 に傾いていますが、ビッグデータ側は方法 2 に傾いています。

あなたならどちらを選びますか?なんで?

4

2 に答える 2

2

時期尚早の最適化、およびそのすべて...

オプション 1 の方が「簡単」に見えるかもしれませんが、主な欠点は既に認識しています。拡張性は大きな苦痛です。

また、オプション 2 よりも高速になるとは思えません。データベースは、関連するデータのビットを見つけるように特別に設計されており、1 レコードではなく 10 レコードを見つけても、測定できる違いはほぼ確実にありません。

「分散した」レコードは実際には問題ではありません。データベースはインデックスを使用して、物理的な場所に関係なく、データを非常に迅速に取得できるようにします。

もちろん、これは @Barmar コメントのように、外部キーにインデックスを使用することに依存します。

于 2012-11-01T17:07:34.990 に答える
1

これらの行が散らばっている場合、保存方法によっては、アクセスが遅くなったり、速くなったりする可能性がありますか?

クラスタリングを正しく使用すれば、分散する必要はありません。

InnoDB テーブルは常にクラスター化され、子テーブルの PK 1が次のように見える場合: {user_id, tab_id}2、これにより、同じユーザーに属するタブが物理的に近くに自動的に保存され、「特定のユーザーのタブ」のクエリ中の I/O が最小限に抑えられます。

OTOH、子 PK が: の{tab_id, user_id}場合、これは同じタブに接続されているユーザーを物理的に近くに保存し、「指定されたタブに接続しているすべてのユーザーを表示してください」などのクエリを非常に高速に作成します。

残念ながら、MySQL は最先端のインデックス圧縮 (オラクルのような) をサポートしていないため、子テーブルでこれらすべてのuser_ids (または2 番目のケースでは s) を繰り返すためのストレージ (およびキャッシュ) の料金を支払う必要がありますが、tab_idそれにもかかわらず、柔軟性と(おそらく)クエリの容易さのために、解決策(2)を引き続き使用します。


1 InnoDB がクラスタリング キーとして自動的に使用するもの。

2つまり、ユーザーの PK は、子テーブルの PK の先頭にあります。

于 2012-11-02T01:04:19.737 に答える