1

再構築しようとしているメンバーシップデータベースがあります。すべてのメンバーには、メインメンバーテーブルに1つの行があります。そこから、JOINを使用して他のテーブルの情報を参照します。私の質問は、次のパフォーマンスにとって何が良いかということです。

データ型とデータを指定する1つのデータテーブル。例:

data_id | member_id | data_type | データ
1| 1 | メール| test@domain.com
2 | 1 | 電話| 1234567890
3 | 2 | メール| test@domain2.com

または

すべての電子メールアドレスのテーブルを作成し、次にすべての電話番号のテーブルなどを作成してから、複数の結合を持つselectステートメントを使用する方がよいでしょうか。

このデータベースはメンバーテーブルの75000行以上で始まり、実際には電話、電子メール、ファックス、姓名、会社名、住所、市の州の郵便番号が含まれることに注意してください(つまり、各メンバーには少なくとも1つの行があります)それらのうち、複数(通常はメンバーごとに1〜3)にすることができるため、75000を超える電話番号、電子メールアドレスなど)

したがって、基本的に、750,000行を超える1つのテーブルを結合するか、75,000行を超える7〜10のテーブルを結合します。

編集:このデータベースのパフォーマンスは、データベース内の既存のデータと一致させる必要がある販売データを挿入するときに問題になるため、1万行の販売および連絡先データのCSVファイルを取得し、データベースにクエリを実行してどのメンバーを見つけようとしますCSVのどの販売行に属性がありますか?そうそう、これはローカルマシンではなく、Webサーバー上で行われます(私の選択ではありません)

4

4 に答える 4

1

これを構造化する明白な方法は、追跡する必要のあるデータ項目(電子メール、電話など)ごとに1つの列を持つ1つのテーブルを持つことです。特定のデータ項目がメンバーごとに複数回発生する可能性がある場合、その項目とメンバー間の関係の正確な性質によって異なります。項目が自然に可変回数発生する可能性がある場合は、これらを入力するのが理にかなっています。メンバーテーブルへの外部キーを持つ別のテーブル。ただし、データ項目が限られた固定の役割のセット(たとえば、自宅の電話番号と携帯電話番号)で複数回発生する可能性がある場合は、それぞれのメンバーテーブルに個別の列を作成する方が理にかなっています。

この設計でパフォーマンスの問題が発生した場合(個人的には、75000はそれほど多くないと思います。クエリを適切にサポートするインデックスがあれば、問題は発生しないはずです)、データを分割できます。Mysqlはネイティブパーティショニング(http://dev.mysql.com/doc/refman/5.1/en/partitioning.html)をサポートします。これは、基本的に、1つの論理コンパートメント(テーブル)を維持しながら、行のコレクションを個別の物理コンパートメント(パーティション)に分散します。 )。ここでの明らかな利点は、論理テーブルのクエリを続行でき、複数の場所からデータを手動でまとめる必要がないことです。

それでもこれがオプションであると思わない場合は、垂直分割を検討できます。つまり、列のグループまたは単一の列を作成して、それらを独自のテーブルに配置します。これは、常に1つの特定の列のセットを必要とするクエリや、別の列のセットを使用する傾向がある他のクエリがある場合に意味があります。その場合にのみ、この垂直分割を適用することが理にかなっています。これは、結合自体がパフォーマンスを犠牲にするためです。

(実際に数十億に達している場合は、シャーディングを検討できます。つまり、個別のデータベースサーバーを使用して行のパーティションを保持します。これは、クエリする必要のあるシャードの数をすばやく制限できる場合にのみ意味があります。特定のメンバー行を見つけるため、またはすべてのシャードを並行して効率的にクエリできる場合。個人的には、これが必要になるとは思われません。)

単一の「データ」テーブルを作成しないことを強くお勧めします。これは基本的に、列から行へと自然に存在する各ものを分散させます。これには大量の結合が必要であり、そうでなければ非常に単純なクエリになるものの記述が複雑になります。それだけでなく、データに対して適切で効率的なインデックスを作成することも事実上不可能になります。さらに、データに制約を適用することは非常に困難です(データ型やデータ項目のタイプに応じた長さの強制など)。

そのような設計が理にかなっているいくつかのコーナーケースがありますが、パフォーマンスの向上はそれらの1つではありません。(参照:エンティティ属性値のアンチパターンhttp://karwin.blogspot.com/2009/05/eav-fail.html

于 2012-04-12T00:00:22.283 に答える
0

75kはDBにとって実際には何もありません。その数のインデックスの利点に気付かないかもしれません(とにかくインデックス:))。

重要なのは、「スケールアウト」システムに注意する必要がありますが、MySQLを含むほとんどのDBは、パーティショニングを通じてこれに対処できるため、データアクセスコードを、アドレス指定/クエリするオブジェクトに関して、プログラムと比較して真に宣言型にすることができます。シャーディングとパーティショニングに注意することは重要ですが、正直なところ、5桁以上ではなく、9桁以上のカウントに近づくレコードを超え始めたときの会話です。

于 2012-04-12T00:22:13.783 に答える
0

scaling outデータベースに関しては、調査する必要がありscaling upます。前述の調査に加えて、大量のデータを期待しない場合は、この場合は1つのテーブルを使用することをお勧めします。もしそうならdimensions、データベース設計を調べてください。

于 2012-04-11T23:50:46.167 に答える
0

最初のオプションの変形が正しいアプローチですが、どちらも使用しないでください。データ型(メール、電話など)の値を格納する「ルックアップ」テーブルを作成します。次に、「データ」テーブルのルックアップテーブルのIDを使用します。そうすれば、実際には2つではなく3つのテーブルがあります。このような古典的な多対多の関係のためのベストプラクティス

于 2013-06-03T01:51:05.053 に答える