5

データベースでは、可変型の値を変数テーブルの変数に代入できるようにしたいと考えています。では、値の型ごとに個別の値テーブルが必要ですか? もしそうなら、実際に値を正しいテーブルにリンクして、正しい値にリンクする方法がわかりません。どうすれば自分が求めているものを達成できますか?

Variables
    ID
    Name

VariableValuesLink
    ID
    IDVars
    IDVals

Values
    IDvals

ValuesValueLink
    ID
    IDvals
    IDval

ValuesInt
    IDval
    IntVal

ValuesFloat
    IDval
    FloatVal

ValuesDouble
    IDval
    DoubleVal

etc...
etc...
etc...
etc...

目的は、次のようなものを取得することです。

Variable: 
    ezas123
Values:
    1 (Int)
    2.0 (Float)
    3.0 (Double)

Variable:
    QuickFox
Values:
    The (TinyText)
    Quick (TinyText)
    Brown (TinyText)
    Fox (TinyText)
    Jumped (TinyText)
    Over (TinyText)
    The (TinyText)
    Lazy (TinyText)
    Dog (TinyText)

Variable:
    Pangrams
Values:
    The Quick Brown Fox Jumped Over The Lazy Dog (Text)
    How quickly daft jumping zebras vex (Text)

したがって、DB にクエリを実行すると、この一連の結果を取得できます (値はさまざまなタイプです)。

Variable    Value
ezas123     1
ezas123     2.0
ezas123     3.0
QuickFox    The
QuickFox    Quick
QuickFox    Brown
QuickFox    Fox
QuickFox    Jumped
QuickFox    Over
QuickFox    The
QuickFox    Lazy
QuickFox    Dog
Pangrams    The Quick Brown Fox Jumped Over The Lazy Dog
Pangrams    How quickly daft jumping zebras vex
4

2 に答える 2

7

この方法で設計を単純化できます。各値テーブルが変数テーブルを指すようにするだけです。リンクテーブルは必要ありません。私が考えることができるリンクテーブルの唯一の理由は、すべての変数タイプにわたってシーケンスを持つ「より簡単な」方法が必要な場合です。これが必要ない場合は、以下のデザインを使用してください。

Variable
    ID
    Name

ValuesInt
    IDvariable
    IntVal

ValuesFloat
    IDvariable
    FloatVal

ValuesDouble
    IDvariable
    DoubleVal

etc...
etc...
etc...

あなたのSQLはどのように簡単ですか:

select v.name as Variable,
       coalesce(cast(vi.IntVal as varchar(max)),
                cast(vf.FoatVal as varchar(max)),
                cast(vd.DoubleVal as varchar(max)),
                '') as Value
From Variable V
JOIN ValuesInt vi on V.ID = vi.IDvariable
JOIN ValuesFloat vf on V.ID = vf.IDvariable
JOIN ValuesDouble vd on V.ID = vd.IDvariable
于 2011-04-28T12:02:29.560 に答える
4

いくつかのポイント:

  • あなたの例では、変数 ezas123 には異なるデータ型の 3 つの値があります。つまり、変数自体には実際には定義されたデータ型がありません。これはおそらく下流で問題を引き起こし、データがかなり不十分に定義されていることを示している可能性があります。特定の変数のすべての値が同じデータ型でなければならないという制限を含めることを検討します。

  • Hogan の SQL クエリは、要求した方法で (つまり、異なるデータ型の変数間で) 値をリストするたびに、結果を varchar などにキャストして表示する必要があることを強調しています (値を持つことができないため)。同じ出力列に異なるデータ型があります)。それを念頭に置いて、本当にさまざまなデータ型が必要ですか、それとも、扱っているすべてのデータに対して varchar 型がうまく機能しますか?

さまざまな型が必要な場合は、さまざまな IntVal、FloatVal、DoubleVal などの列をすべて 1 つのテーブルに配置することを検討します。テーブル定義は次のようになります。

Variables
      ID          NOT NULL
     ,Name        NOT NULL
     ,DataType    NOT NULL CHECK (DataType IN ('INT','FLOAT','DOUBLE','TEXT'))  
   ,CONSTRAINT PK_Variables PRIMARY KEY (ID)
   ,CONSTRAINT UQ_Variables_1 UNIQUE (Name)
   ,CONSTRAINT UQ_Variables_2 UNIQUE  (ID,DataType)

    Values
      IDvals      NOT NULL
     ,ID          NOT NULL
     ,DataType    NOT NULL CHECK (DataType IN ('INT','FLOAT','DOUBLE','TEXT'))
     ,IntVal      NULL
     ,FloatVal    NULL
     ,DoubleVal   NULL
     ,TextVal     NULL
   ,CONSTRAINT PK_Values PRIMARY KEY (IDvals)
   ,CONSTRAINT FK_Values_Variable FOREIGN KEY (ID,DataType) REFERENCES Variables(ID,DataType)
   ,CONSTRAINT CH_Values CHECK ( NOT(DataType <> 'INT'    AND IntVal     IS NOT NULL)  AND
                                 NOT(DataType <> 'FLOAT'  AND FloatVal   IS NOT NULL)  AND
                                 NOT(DataType <> 'DOUBLE' AND DoubleVal  IS NOT NULL)  AND
                                 NOT(DataType <> 'TEXT'   AND TextVal    IS NOT NULL)
                                )
  • Variables(ID,DataType) の UNIQUE 制約は、FK のサブジェクトにするためにおそらく必要になります (DBMS?)。
  • CHECK 制約により、有効なデータ型のみが使用され、正しい値の列のみが入力されることが保証されます。
  • 変数だけでなく値にも DataType があるということは、トリガーやアプリケーション ロジックを使用するのではなく、FK と CHECK の組み合わせを使用して、特定の変数のすべての値が同じデータ型であることを確認できることを意味します。

テーブルに対するクエリは次のようになります。

SELECT v.name as Variable,
       COALESCE(cast(a.IntVal       as varchar(max)),
                cast(a.FloatVal     as varchar(max)),
                cast(a.DoubleVal    as varchar(max)),
                cast(a.TextVal      as varchar(max)),
                '') as Value
FROM 
Variables V
JOIN Values a on V.ID = a.ID AND v.DataType = a.DataType

これは、関連する列を選択するために使用される Variable.DataType に基づく CASE を使用して (おそらくより正確に) 記述することもできます。

1 つのテーブルにすべての値があるということは、データベース内のテーブル/制約/インデックスが少なくなることを意味し、新しいデータ型を保持するためにソリューションを拡張することは、新しいテーブルを追加するのではなく、値テーブルに新しい列を追加する (および制約を変更する) ことを意味するだけであることを意味します。

于 2011-05-02T17:33:15.113 に答える