2

ユーザーのユーザーメタデータ設定を保存したい。ただし、メタデータ値は複数のデータ型であり、整数、文字列、日付、またはブール値にすることができます。

だから私は私自身の解決策を持ってきました

user(user_id(PK), ...)

meta(
   meta_id (PK)
 , user_id (FK)
 , data_type
 , meta_name
 , ...)

meta_user(
   user_id(FK)
 , meta_id(FK)
 , number_value
 , decimal_value
 , string_value
 , date_value
 , time_value
 , boolean_value)

しかし、それが複数のデータ型を格納する正しい方法かどうかはわかりません。ここで誰かが解決策を共有するのを手伝ってくれることを願っています.

更新:
ユーザーは多くのメタデータを持っている可能性があり、ユーザーは最初にメタデータを登録する必要があります。

4

2 に答える 2

3

これに対する私の貢献は次のとおりです。

  1. metadefinitionメタデータの名前を実装する必要があるため、テーブルを追加します。

    meta_definition (metadefinition_ID(PK), name (varchar), datatype)
    
  2. 次に、meta_userテーブルを変更します

    meta_user (meta_ID (PK), user_ID(FK), metadefinition_ID(FK))
    
  3. 3 つの選択肢 (A、B、C) またはそれ以上...

バリアント A: 考えられるすべてのデータ型の値を 1 つの行に格納する設計を維持して、スパース テーブルを作成します。

これは実装が最も簡単ですが、「クリーンなデザイン」という点では最も醜いです (私の意見)。

バリエーション B: データ型ごとに個別の値テーブルを使用する: 1 つのスパース テーブルmeta_userを使用する代わりに、6 つのテーブルを使用できますmeta_number, meta_decimal, meta_string. 各テーブルの形式は次のとおりです。

meta_XXXX (metadata_ID(PK), meta_ID(FK), value)

私見ですが、これは最もクリーンなデザインです (ただし、操作が少し複雑です)。

バリアント C: meta_user3 つの列を保持するように縮小します (meta_valuesユーザーではなく値を保持するため、名前を に変更しました)。

meta_values (metavalue_ID(PK), meta_ID(FK), value (varchar))

すべての値を string/varchar としてフォーマットし、それらをvalue列に詰め込みます。「実際の」値を使用するには、高価で複雑なキャストを行う必要があるため、SQL 内で値を使用する場合、これは適切に設計されておらず、悪い考えです。

これは最もコンパクトなデザインです。

特定のユーザーのすべてのメタデータを一覧表示するには、次を使用できます。

select u.name, 
       md.name as 'AttributeName',
       md.DataType
  from user u 
       join meta_user mu on u.user_ID = mu.userID
       join meta_definition md on md.metadefinition_ID = mu. metadefinition_ID

特定のユーザーの値を選択すると、バリアント A: select u.name, md.name as 'AttributeName', mv.* -- ユーザーからのすべての異なるデータ型が表示されます u join meta_user mu on u.user_ID = mu.userID join md.metadefinition_ID = mu の meta_definition md。metadefinition_ID は mv.meta_ID = mu.metaID で meta_value mv に参加します

欠点: 新しいデータ型が利用可能になった場合、列を追加し、クエリを再コンパイルし、ソフトウェアも変更する必要があります。

select u.name, 
       md.name as 'AttributeName',
       mnum.value as NumericValue,
       mdec.value as DecimalValue
...
  from user u 
       join meta_user mu on u.user_ID = mu.userID
       join meta_definition md on md.metadefinition_ID = mu. metadefinition_ID
       left join meta_numeric mnum on mnum.meta_ID = mu.metaID
       left join meta_decimal mdec on mdec.meta_ID = mu.metaID
...

短所: 多くのユーザーと属性が保存されている場合は遅くなります。新しいデータ型が導入されると、新しいテーブルが必要になります。

バリアント C:

select u.name, 
       md.name as 'AttributeName',
       md.DataType -- client needs this to convert to original datatype
       mv.value    -- appears formatted as string
  from user u 
       join meta_user mu on u.user_ID = mu.userID
       join meta_definition md on md.metadefinition_ID = mu. metadefinition_ID
       join meta_value mv on mv.meta_ID = mu.metaID

利点: 新しいデータ型が導入された場合でも、クエリを変更する必要はありません。

于 2012-12-27T09:24:20.297 に答える