2

ID(主キー、ID)、A、およびBの3つの列を持つTable1があるとします。

ここで、列ごとに共通点がないと仮定して、3つのメソッドがあるとします。

方法1:C、D、E

方法2:F、G、H、I

方法3:J

ID、A、B、C、D、E、F、G、H、I、J、Mの1つのテーブルを作成できます

ここで、Mはメソッド(またはメソッドID)の名前です。

ただし、方法3が90%の時間使用される場合、多くのnull値が存在します。
これは問題ですか?もしそうなら、これを設定するためのより良い方法はありますか?

各メソッドを独自のテーブルエンティティにした場合、各IDに一致するメソッドが1つだけあることを確認するにはどうすればよいですか?

1つのテーブルとして保持する場合、Mが1の場合、C、D、Eのみが入力され、FからJまでがNULLになるようにするにはどうすればよいですか?


OK、抽象的に考えるのが難しい人もいるようですので、上記を適用してランダムな具体例を作成します。

運動をしている人の記録があったとしましょう。
各レコードには、常にID(イベントを一意に識別するため)、TIME_STARTED、およびTIME_ENDEDがあります。

ただし、どの演習を行ったかに応じて、必要な属性は異なります。演習が3つしかなかったとします。

楕円形:傾斜、レベル、速度

クランチ:User_Weight、Reps、Delay、Extra_Weight

デッドリフト:Weight_Lifted

IDごとに、「メソッド」は1つしか存在できません。これを適用するには、上記の質問を参照してください。

4

2 に答える 2

3

ここにスーパータイプ/サブタイプの状況があるようです。この場合、Table1はスーパータイプを保持し、各サブタイプを保持するために異なるテーブルを作成する必要があります。これらのサブタイプテーブルのPKは、スーパータイプテーブルのFKにもなります。したがって、次のようなものになります。

Supertype_table
|    ID(PK)   |  A  |  B  |

Subtype1_table
|  ID(PK&FK)  |  C  |  D  |  E  |

Subtype2_table
|  ID(PK&FK)  |  F  |  G  |  H  |  I  |

Subtype3_table
|  ID(PK&FK)  |  J  |

このスキーマのポイントは、ほとんどがnullである行の束がないことを確認することです。メソッドごとに、適切なテーブルを挿入/更新する個別のクエリを作成する必要があります。SQL Serverを使用すると、これらすべてのテーブルを組み合わせて、結合を抽象化するビューを作成できます。

CREATE VIEW MyView
SELECT Super.ID, Super.A, Super.B, 
Sub1.C, Sub1.D, Sub1.E, 
Sub2.F, Sub2.G, Sub2.H, Sub2.I, 
Sub3.J
FROM Supertype_table as Super
LEFT OUTER JOIN Subtype1_table as Sub1 on Super.ID = Sub1.ID
LEFT OUTER JOIN Subtype2_table as Sub2 on Super.ID = Sub2.ID
LEFT OUTER JOIN Subtype3_table as Sub3 on Super.ID = Sub3.ID

したがって、次のように書くことができます。

SELECT ID, A, B, J
FROM MyView
WHERE J is not null

編集:OPのコメントのために

各IDが1つだけのテーブルにあることを確認するには、スーパータイプテーブルにある種の識別子が必要です。したがって、TypeIDという列がある場合は、次の関数を作成します。

CREATE FUNCTION [dbo].[SubtypeofSuperID](@ID int)
RETURNS int
AS
BEGIN
  DECLARE @TypeID int;

    SELECT @TypeID = TypeID 
    FROM Supertype_table
    WHERE ID = @ID

  RETURN @TypeID 
END

次に、それを使用して、各サブタイプテーブルにチェックを作成できます。

ALTER TABLE Subtype1_table CONSTRAINT [CK_CorrectSubtype1]
CHECK ( [dbo].[SubtypeofSuperID]([ID]) = 1 )
ALTER TABLE Subtype2_table CONSTRAINT [CK_CorrectSubtype2]
CHECK ( [dbo].[SubtypeofSuperID]([ID]) = 2 )
ALTER TABLE Subtype3_table CONSTRAINT [CK_CorrectSubtype3]
CHECK ( [dbo].[SubtypeofSuperID]([ID]) = 3 )
于 2012-06-15T19:04:12.100 に答える
1

いくつかの方法...

まず第一に、ジェイソンの答えはそのうちの1つに当てはまります。つまり、デザインを複数のテーブルに分割します。これは、ほとんどの場合にかなり良いアプローチになる可能性があります。(別名、より「正規化された」アプローチ)

代替案...

1)最後のフィールドに名前と値のペアの文字列を含めることができます。例えば:

ID   Method   DateTimeStart   DateTimeEnd   ValueString
1    1        2012-01-01...   2012-01-01... C:value,D:value,E:value
2    2        2012-01-01...   2012-01-01... F:value,G:value,H:value,I:value

したがって、これは、事前に値型を計画できない場合に便利です。たとえば、メソッド1の「W」値の記録を開始するためにその場で決定できる必要があるかもしれません。より正規化された設計で行う必要があるような構造modを実行することは現実的ではありません。

これは、Eサインフォームの開発者が使用する一般的なアプローチです。誰かが承認のために電子的に記入してルーティングする「部門休暇申請」などのWebフォームを想像することができます。そして、記録する必要のあるさまざまなフィールドと値を持つ「発注書」Webフォームを作成することを希望するクライアントが登場します。このための新しいテーブルを作成する(または既存のテーブルに列を追加するなど)のではなく、名前と値のペアモデルを使用して、フォームに関係なく、すべてのフォームデータを同じテーブルに格納します。

2)単一の大きなテーブルで挿入を実行している人/プロセスを信頼しない場合は、テーブルトリガーを使用して整合性を強制できます。たとえば、更新前のトリガーでメソッド番号を確認し、不適切なデータ値を無効にすることで、ユーザーまたはプロセスが挿入しようとしたデータを変更できます。

FWIW

于 2012-06-15T19:36:16.897 に答える