web-dev-qa-db-ja.com

何百万ものユーザーを管理する方法は?

私は本当に大きなものを立ち上げようとしています。サーバーとデータベースを準備する必要があります。

100,000人のユーザーの各セットを別々のユーザーテーブルにグループ化したいのですが、適切なユーザーテーブルにログインしようとしている1人のユーザーを関連付ける方法がわかりません。

たとえば、そのユーザー[email protected]はユーザーテーブル#36に関連していますか?

1つのユーザーテーブルに1,000万人のユーザーがいるのと同じですか、それとも100,000人のうち100人ですか。

Facebookはどうですか? 9億5000万エントリのグローバルユーザーテーブルが1つあるとは思えません。

18
Chris

明日は10億人のユーザーがいることはなく、MySQLは何百万行も問題なく処理できます。私はユーザーテーブルに500万人のユーザーがいて、私を信頼しています。心配することについては私のレーダーにもありません。

必要になるまでシャーディングについて心配する必要はありません。あなたは、存在するかもしれないか存在しないかもしれない問題に対して時期尚早に最適化しようとしています、そしてその過程で、あなたは革新できる率をひどく損ないます。立ち上げを早め、問題が発生したらすぐに見つけます。スケーリングの課題を事前に予測することはできません。

この規模に達すると、この種の問題に対処するためにかなりの資金とリソースが必要になります。

31
Aaron Brown

非常に大規模なデータセットを処理する必要があり、最初から開始する必要がある場合、外部コンサルタントが会社のより良いサポートになるかどうかはわかりません。誤解しないでください。ただし、プロジェクトが非常に多くの顧客と混同されると、PRが会社に影響を及ぼします。

1つのテーブルの10Mタプルに関して、適切なインデックス付けがあれば問題ありません。ここでは、1つのテーブルに複数の100Mタプル(販売アイテム)を格納する必要があります。これは、大規模なOracle 11gで正常に機能します。

以下は、Facebookのデザインのマップを含む2010年からの投稿です: Facebookデータベースのデザイン

次のようなパーティションタイプに関するmysqlのドキュメントを読むことをお勧めします。 MySQLのドキュメント:パーティショニング

MySQLは次のタイプをサポートしています。

[〜#〜]範囲[〜#〜]パーティショニング。このタイプのパーティション化では、指定された範囲内の列の値に基づいて行をパーティションに割り当てます。セクション18.2.1「RANGEパーティショニング」を参照してください。

[〜#〜] list [〜#〜]パーティショニング。 RANGEによるパーティショニングに似ていますが、離散値のセットの1つと一致する列に基づいてパーティションが選択される点が異なります。セクション18.2.2「LISTパーティショニング」を参照してください。

[〜#〜]ハッシュ[〜#〜]パーティショニング。このタイプのパーティション化では、テーブルに挿入される行の列値を操作するユーザー定義式によって返される値に基づいてパーティションが選択されます。関数は、MySQLで有効な任意の式で構成され、負でない整数値を生成します。このタイプの拡張であるLINEAR HASHも使用できます。セクション18.2.3「HASHパーティショニング」を参照してください。

[〜#〜] key [〜#〜]パーティショニング。このタイプのパーティショニングはHASHによるパーティショニングに似ていますが、評価される1つ以上のカラムのみが提供され、MySQLサーバーは独自のハッシュ関数を提供します。 MySQLが提供するハッシュ関数は、列のデータ型に関係なく整数の結果を保証するため、これらの列には整数値以外を含めることができます。このタイプの拡張であるLINEAR KEYも使用できます。セクション18.2.4「KEYパーティショニング」を参照してください。

16
user10519

まず第一に、ユーザーを別々のテーブルに分けないでください。それは物事を複雑で無意味なものにします。 MySQLやその他のデータベースは、同じテーブル内の何百万ものレコードのデータベースで問題なく動作します(正しいPRIMARY KEYSが設定されている)。データベースのAUTO_INCREMENT AND PRIMARY(各メインユーザーテーブルの)ユーザーごとに一意のキーフィールドを使用して、すべてのレコードが一意(UID)になるようにします。次に、その一意のIDを使用して参照している他のテーブルで。次に、すべてのテーブルでPRIMARY KEYとして設定していることを確認します。これにより、データベースサーバー内の情報の処理が高速化されます。 Drupal CMSがユーザー情報を保存する方法をCMSから学ぶことができます。何百万ものユーザーと非常に大規模な企業(大規模なメディア企業、政府、さらには最大の銀行によって使用されています)によって10年以上テストされていますwww.drupal.orgでは、同じテーブルに160万を超えるページ(ノード)が保存されており、毎月100万を超えるユニークユーザーがいて、Webサイトは問題なく機能しています。適切な最適化と構成。

1000万件のレコードの後、パフォーマンスに満足できない場合(適切な最適化とdb構成の変更後)、ユーザーを異なるテーブルで本当に分離するかどうかを決定できます。したがって、ユーザーレコードが保存されている場所に関する情報を含む新しいテーブルを追加することで、機能を実際に拡張できます:UIDとtable_name。次に、他のテーブルのいずれかがこれらの情報を要求すると、このテーブルは適切なテーブルを探します。しかし、1000万〜1億件を超えるレコードがない限り、ユーザーには1つの大きなテーブルを用意することをお勧めします。ただし、パフォーマンスはそれほど向上しません(データベースは巨大なデータを処理するように設計されています)。情報はシンプルに保つことをお勧めします。通常、企業は別のデータベースサーバー(マスターとスレーブ)を決定し、別のデータベースサーバーを決定すると、負荷分散機能と連携して動作します。 1,000万人のユーザーがいる場合は、別のdbサーバーに料金を支払うことができますよね?

ser.install ファイルのuserテーブルスキーマの例を参照してください。

7
kenorb

他の回答が示唆するように、ユーザーを複数のテーブルに分割することは良い考えではありません。ユーザーIDにインデックスを持つデータベースのほとんどは、100万行を処理できます。ただし、インデックス内のエントリの総数によっては、クエリごとのレイテンシが増加する可能性があります。データセットが小さい限り、通常のデータベースの単一テーブルで管理できます。

100万件を超えるレコードを大幅に増やした場合は、今後の検討のために別のアイデアも取り入れます。このような多数の顧客では、ダウンタイムなどは必要ありません。そのため、確認したい場合があるnosqlデータベースがたくさんあります。アプリケーションからシャーディングを自分で管理する代わりに、シャーディングを行います。また、データの冗長性を提供するため、稼働時間が長くなります。 Facebookなどはすべて、キャッシュにmemcacheなどを頻繁に使用しています。しかし、私は彼らが彼らの永久的な店のために何を使うかわかりません。

注意すべき重要な点の1つは、nosqlデータベースでは結合などを実行できないことです。したがって、ユースケースを計画して決定します。結合とマルチレコードトランザクションが必要な場合、nosqlデータベースは必要ありません。

3
sunil