ここでの問題はサブタイピングです 。サブタイプを処理するには、3つの基本的なアプローチがあります。
- 各レコードタイプを完全に別個のテーブルに配置します。
- レコードを親テーブルに配置してから、サブタイプテーブルにレコードを配置します。および
- すべてのレコードを1つのテーブルに配置し、「オプションの」データ(つまり、そのタイプに適用されないもの)のnull許容列を作成します。
それぞれの戦略にはメリットがあります。
たとえば、(3)は、異なるサブタイプ間にほとんどまたはまったく違いがない場合に特に当てはまります。あなたの場合、特定のタイプの場合、異なるログレコードに余分な列がありますか?そうでない場合、またはすべてを1つのテーブルにまとめる場合がほとんどない場合は、完全に理にかなっています。
(2)は、パーティテーブルに一般的に使用されます。これは、PersonおよびOrganizationのサブタイプを持つ親Partyオブジェクトを含むCRMの一般的なモデルです(Organizationには、Company、Associationなどのサブタイプも含まれる場合があります)。 PersonとOrganizationには異なるプロパティ(たとえば、Personの敬礼、名前、生年月日など)があるため、null許容列を使用するのではなく、これを分割するのが理にかなっています。
(2)スペース効率が高くなる可能性があります(ただし、最新のDBMSではNULL列のオーバーヘッドは非常に低くなっています)。より大きな問題は、(2)が開発者にとってより混乱する可能性があることです。誰かが余分なフィールドをどこかに保存する必要があり、DBAが列を追加するための承認を得るよりも簡単であるという理由だけで、そのタイプの空の列にそれを打ち込むという状況が発生します(いいえ、冗談ではありません) 。
(1)は、私の経験ではおそらく3つの中で最も使用頻度の低いスキームです。
最後に、スケーラビリティを考慮する必要があり、おそらく(1)の最良のケースです。ある時点で、JOINは効果的にスケーリングせず、テーブルサイズを縮小するために何らかのパーティションスキームを使用する必要があります。 (1)はそれを行う1つの方法です(ただし、大雑把な方法です)。
でもそれについてはあまり心配しません。それが問題になる前に、通常、数億または数十億のレコードを取得する必要があります(レコードが本当に大きい場合を除き、その場合はより早く発生します)。