web-dev-qa-db-ja.com

リレーショナルデータベースでNULL値の可能性がある別のテーブルを作成する方が良いですか?

で使用するリレーショナルデータベースを設計しています MySQL。次の状況があります。1つのテーブルに、ほとんどの状況でNULLであるフィールドがあります。フィールドは次のようになります。

Table name: tabla

Fields:
  idtabla not null,
  text (varchar(n)) not null,
  image (mediumblob) {this can be null}

疑問:別のテーブルを作成し、イメージを使用する必要がある場合は、新しいテーブルにクエリを実行する方がよいでしょうか。なぜあなたのソリューションはデザインに優れているのですか? MySQLの時間応答、クエリ作成のしやすさなど。

4
andreshg112

ここではほとんど哲学的な論点に触れています:リレーショナルデータベースの派生元である「クローズドワールド」の想定に違反しているため、NULL可能値を許可する必要があります(関連するセクション http://en.wikipediaを参照)。 .org/wiki/Null_(SQL) と他の多くの質問 なぜNULLを許可しないのか などの注意事項について)不明な値(またはすべての状況で単に適用されない可能性がある)を独自の関係(テーブル)に分割して不明な値を回避し、不明な値がないようにしますが、値が不明な場合は存在しません。これは理論を満たしますが、それをあまり望ましくない実際的な影響があります。

  • JOIN操作はほとんどのRDBMSで無料ではありません。追加のテーブルでプロパティを検索すると、クエリを満たすためにエンジンが実行する必要のある作業が増加します。
  • プロパティの存在が相互依存していない場合(つまり、他のプロパティに関係なく各プロパティが不明である可能性がある場合)、この実装を結論に導くには、各プロパティのテーブルが必要になることがあります。
  • 追加の結合によりクエリが複雑になり、保守性が低下する可能性があります。
  • 更新は場所によっても直感的になりません。プロパティを空白にするとDELETE操作になり、更新はINSERTまたはUPDATEのいずれかになります。

もちろん、最初のポイントが逆になり、特性を壊すと効率が向上する状況があります。

  • ほとんどのRBDMSはページベースのストレージを使用し、オプションの情報をコアデータから分離することで、特定のページにより多くのコアデータ行を収めることができます。データサイズ、RAM、ストレージインフラストラクチャによっては、一部の大規模なクエリに必要なIOの量を減らすのに重要な場合があります(多くの場合そうではありません)。この点、少なくとも状況が悪化していないことを確認するための適切なベンチマークを実行していない場合)。
    これはもちろん、クエリが必要なものだけを取得するようにクエリが設計され、エンジンが追加情報の描画を気にする必要がないと想定していることを前提としています。
  • 同様に、INSERTまたはUPDATEのコア情報のみを更新する場合は、書き込みが少なく、これらの追加のプロパティに制約またはトリガーがある場合、行の変更ごとにこの処理が回避される可能性があります。 。

あなたの例は、画像(またはblob型の列に少なくとも大きなデータのビット)を格納しているように見えます。ここでは、さらに2つの考慮事項があります。

  • とにかく、ほとんどのデータベースエンジンは大きなデータを「ページ外」に格納するため、SELECT *とにかく、ページあたりの行数ボーナスを「無料」で獲得できます。
  • それらを別の場所に移動すると、同じblobを複数回保存するのではなく、複数のエンティティ間で大きなデータを共有できますか、または情報(存在する場合)は特定の行に固有ですか?

tl; dr:だから、難しい答えはありません。私のアドバイスは、データの概念モデルに最も適したものを実行することです。そのため、維持するための考慮事項が少なくて済みます。これは、常にではありませんが、通常、個別のテーブルではなくNULL可能列を使用することを意味します。データが本当に大規模でない限り、パフォーマンスの違いは無視できます。

3
David Spillett

画像用の個別のテーブルが役立つかどうかは、画像と元のテーブルの残りの属性との関係のカーディナリティによって異なります。

別の画像テーブルは、次のいずれかの場合に正当化できます。

  • 複数の行に同じ画像が含まれる可能性があります:画像を元のテーブルに複数回保存するのではなく、画像テーブルに1回だけ保存する必要があるため、正規化が強化されます
  • 画像は残りの属性なしで存在できます。例えば行の画像が交換/削除された場合、これにより履歴を保持できる可能性があります

画像が行ごとに一意である場合、別の画像テーブルを使用する場合にnull外部キーがあるため、nullフィールドについて心配する必要はありません。

画像を元のテーブルに保持することにした場合は、必要な場合にのみ画像を取得することをお勧めします(データの場合と同様に、必要な場合を除いてSELECT *を使用しないでくださいall利用可能なデータ)。

1
Marco Borchert