web-dev-qa-db-ja.com

データベース設計で1対1の関係を使用するのはなぜですか?

データベース設計で1対1の関係をいつ使用するか、またはそれが必要かどうかを判断するのに苦労しています。

クエリで必要な列のみを選択できる場合は、テーブルを1対1の関係に分割する必要があります。大きなテーブルを更新すると、小さなテーブルよりもパフォーマンスに大きな影響があると思います。特定の操作(読み取り/書き込み)でテーブルがどの程度使用されているかによって異なります。

では、データベーススキーマを設計するとき、1対1の関係をどのように考慮しますか?必要かどうかを判断するためにどのような基準を使用しますか。また、使用しないことのメリットは何ですか。

22
chobo

論理的な観点から、1:1の関係は常に単一のテーブルにマージする必要があります。

一方、そのような "垂直分割" または "行分割"については、物理的の考慮事項がある場合があります。たとえば、いくつかの列に頻繁に、または他の列とは異なるパターンでアクセスすることを知っています。

  • cluster または partition 1:1関係の2つの「エンドポイント」テーブルを異なる方法で使用することをお勧めします。
  • DBMSで許可されている場合は、それらを別の物理ディスクに配置することをお勧めします(たとえば、SSDではパフォーマンスが重要で、安価なHDDではもう1つ)。
  • キャッシュへの影響を測定し、「コールド」列が「汚染」することなく、「ホット」列がキャッシュに保持されていることを確認したいとします。
  • 行全体よりも「狭い」同時実行動作(ロックなど)が必要です。これはDBMS固有のものです。
  • 列ごとに異なるセキュリティが必要ですが、DBMSは列レベルの権限をサポートしていません。
  • 通常、トリガーはテーブル固有です。理論的にはテーブルを1つだけにして、トリガーに行の「間違った半分」を無視させることができますが、データベースによっては、トリガーが実行できることと実行できないことに対して追加の制限を課す場合があります。たとえば、Oracleでは、行レベルのトリガーからいわゆる「変更」テーブルを変更することはできません。個別のテーブルを使用することで、一方のみが変更される可能性があるため、トリガーからもう一方を変更できます(ただし、 他の方法 回避策)。

データベースはデータの操作に非常に優れているため、更新のパフォーマンスのためだけにテーブルを分割することはしません代表者に対して実際のベンチマークを実行した場合を除きますデータの量と結論として、パフォーマンスの違いは実際に存在し、十分に重要です(たとえば、JOINの必要性の増加を相殺するため)。


一方、「1:0または1」(真の1:1ではない)について話している場合、これはまったく別の質問であり、別の答えに値します...

38

職務の分離とデータベーステーブルの抽象化。

ユーザーがいて、各ユーザーが住所を持つようにシステムを設計した後、システムを変更した場合、新しいテーブルを追加してデータを移行するのではなく、アドレステーブルに新しいレコードを追加するだけです。 。

編集

現在、個人レコードが必要で、各個人が1つの住所レコードを持っている場合は、個人テーブルと住所テーブルの間に1対1の関係を設定することも、個人テーブルを作成することもできます。アドレスの列。

将来的には、人が複数の住所を持つことを許可することを決定したかもしれません。 1対1の関係シナリオでは、データベース構造を変更する必要はありません。返されるデータの処理方法を変更するだけで済みます。ただし、単一のテーブル構造では、ベストプラクティスの1対多の関係データベース構造を作成するために、新しいテーブルを作成し、住所データを新しいテーブルに移行する必要があります。

8
bdparrish

まあ、紙の上では、正規化されたフォームが最良のように見えます。現実の世界では、通常、それはトレードオフです。私が知っているほとんどの大規模システムはトレードオフを行い、完全に正規化しようとはしていません。

例を挙げてみましょう。 1000万の通帳口座を持つ銀行のアプリケーションを使用している場合、通常のトランザクションは特定の口座の最新の残高のクエリにすぎません。これらの情報(口座番号、口座残高、口座名義人名)のみを格納するテーブルAがあります。

アカウントには、顧客の住所、税番号、表Bにある他のシステムにマッピングするためのIDなど、さらに40の属性があります。

AとBには1対1のマッピングがあります。

口座残高をすばやく取得できるようにするために、口座残高と口座名義人の名前を持つ小さなテーブルに異なるインデックス戦略(ハッシュインデックスなど)を採用することをお勧めします。

他の40個の属性を含むテーブルは、異なるテーブルスペースまたはストレージに存在し、異なるタイプのインデックスを使用する場合があります。たとえば、名前、アカウント番号、ブランチIDなどで並べ替える場合などです。システムは、これらの取得が遅いことを許容できます。 40の属性、アカウント番号によるアカウント残高クエリの高速取得が必要です。

43個の属性すべてを1つのテーブルに含めるのは自然なことのようであり、おそらく「自然に遅い」ため、単一の口座残高を取得するだけでは受け入れられません。

4
Daniel Baktiar

実世界のエンティティをモデル化するために1-1の関係を使用することは理にかなっています。そうすれば、より多くのエンティティが「世界」に追加されたときに、それらは関連するデータにのみ関連する必要があります(それ以上は関係しません)。

それが本当に重要です。データ(各テーブル)には、それが表す実際のことを説明するのに十分なデータのみが含まれている必要があり、それ以上は含まれていません。その「もの」に関してはすべて意味があるので、冗長なフィールドがあってはなりません。これは、システム全体で繰り返されるデータが少なくなり(更新の問題が発生するため)、個々のデータを個別に取得できることを意味します(たとえば、文字列を分割/解析する必要はありません)。

これを行う方法を理解するには、「データベースの正規化」(または正規化)、「正規形」、および「第1、第2、第3の正規形」を調べる必要があります。これは、データを分解する方法を説明しています。例のあるバージョンは常に役に立ちます。おそらくこれを試してください チュートリアル

2
wmorrison365

多くの場合、人々は1:0..1の関係について話し、それを1:1と呼びます。実際には、一般的なRDBMSは、どのような場合でも文字通りの1:1の関係をサポートできません。

そのため、技術的には1:0..1の関係が必要であり、1:1の文字通りの概念ではありませんが、ここでサブクラス化に取り組むのは公正だと思います。

1:0..1は、複数のエンティティ/テーブル間でまったく同じフィールドがある場合に非常に役立ちます。たとえば、住所、電話番号、電子メールなど、従業員とクライアントの両方に共通する可能性のある連絡先情報フィールドを、連絡先情報専用に作成されたエンティティに分割できます。

連絡先テーブルには、住所や電話番号などの一般的な情報が含まれます。

したがって、従業員テーブルには、従業員番号、雇用日などの従業員固有の情報が保持されます。また、従業員の連絡先情報の連絡先テーブルへの外部キー参照もあります。

クライアントテーブルには、電子メールアドレス、雇用主名などのクライアント情報、および性別や婚姻状況などの人口統計データが保持されます。クライアントは、連絡先情報の連絡先テーブルへの外部キー参照も持っています。

これを行う際に、すべての従業員に連絡先がありますが、すべての連絡先に従業員がいるわけではありません。同じ概念がクライアントにも当てはまります。

2
James Marks

過去のプロジェクトからのほんの数サンプル:

  • testRequestsテーブルには、一致するレポートを1つだけ含めることができます。ただし、リクエストの性質によっては、レポートのフィールドがまったく異なる場合があります。
  • 銀行プロジェクトでは、エンティティテーブルには、ファンド、RealEstateProperties、Companyなどのさまざまな種類のエンティティが含まれます。これらのエンティティのほとんどは同様のプロパティを持っていますが、ファンドには約120の追加フィールドが必要ですが、レコードの5%にすぎません。
1
Patrick Honorez