クラスの問題に取り組んで、人に関連付けられたイベントのリストを格納する Web の mySQL 表現を設計しています。したがって、このテーブルには 2 つの列があり、そのうちの 1 つは人の名前で、もう 1 つはイベントです。ただし、通常、1 人は 30 ~ 1000 のイベントを持っているため、6000 人の学生の学部クラス全体で使用する予定のこのテーブルには、数百万のエントリがあります。これをより少ないスペースで mySQL に保存するより良い方法はありますが、個々のイベントとそれに参加した人のリストを 2 列のテーブルと同じくらい簡単に取得できますか?
3 に答える
はい、多対多と呼ばれる手法があり、基本的に1つのテーブルを3つに分割します。これは、モデル化されているエンティティが実際に3つあると考える場合に重要です(適切なサニティチェックとして)
- 人
- イベント
- 個人とイベントの関連付け
これを 3 つのテーブルとしてモデル化します。最初の 2 つのテーブルは基本的にそれぞれ 2 つの列を持ちます。1 つは一意のインデックス (「主キー」と呼ばれる) を持ち、2 つ目はセマンティック名 (人名、イベント名) です。ストレージを増やす要因を 1 つだけ使用して、これらに任意の数の列を追加することもできます (ほとんどの場合、最初に行うことは、イベント テーブルに日付列を追加することです)。
3 番目のテーブルは興味深いもので、それぞれが数値の 2 つの列のみを含み、どちらも他のテーブルへの参照です (各行は単純に (person_id, event_id))。これらを「外部キー」と呼びます。
この構造は、いくつかのことを意味します。
- 誰かがいくつのイベントに参加しても、その人は一度だけ代表されます。
- 出席者の数に関係なく、イベントと同じ
- 出席は「第一級」のエンティティであり、独自の属性 (つまり「役割」) を含むように成長する可能性があります。
この構造は、各人が多くのイベントに参加し、各イベントに多くの参加者がいる可能性があるため、多対多と呼ばれます。
設計の典型的な特徴は、ドメイン知識の単一部分が繰り返されるのではなく、現実世界のドメインをモデル化するために必要に応じて「キー」のみが繰り返されることです。(つまり、最初の例では、名前の変更を説明するには、不明な量の更新が必要であり、データベースの正規化の主な懸念事項であるデータの異常につながる可能性があります.
「スペース」は気にしないでください。これは 1970 年代ではなく、データを格納するパンチ カードの列が不足することはありません。適切で最も正規化されたデータ構造で要件を表現することに注意する必要があります。この量のデータではなく、適切なインデックス付けがあれば問題はないはずです。
句の一部として含めるものすべてにインデックスを定義する必要があることを覚えておいてください。また、と でWHERE
フェッチされた大きなリストには、追加のインデックスを追加する必要がある場合があります。ORDER BY
LIMIT
可能な限り、または実用的な場合は常に、文字列の代わりに整数の識別子を使用してください。これらは、少なくともバイト単位の文字列の長さに 1 を加えた可変長文字列と比較して、通常は 4 バイトという少数のバイトとして格納されます。
とにかく、適切に正規化されたデータベースは数値識別子を使用するため、この種のことは大きな問題ではありません。これに反対する、または意図的にデータを非正規化するのは、他の方法では簡単に解決できない正当なパフォーマンスの問題がある場合のみです。
いつものように、大量のダミー データを生成してスキーマをテストし、そのパフォーマンスを確認します。事前に要件を把握しているので、それらのレベルでいくつかのテストを行ってから、念のため、2 倍、5 倍、10 倍のデータを試して、設計の柔軟性を確認してください。どのような規模で経験するかを知っている限り、パフォーマンスの制限があっても問題ありません。
mySQL リレーショナル データベースは、この種の問題を処理するために特別に設計されました。何百万ものエントリを処理することは問題ではありません。複雑なクエリには数秒かかる場合がありますが、パフォーマンスは非常に優れています。
行ごとに 1 つのイベントを格納するのが最適な設計です。あなたが行っている方法は、最善の方法のように聞こえます。幸運を。