これに対する私の貢献は次のとおりです。
metadefinition
メタデータの名前を実装する必要があるため、テーブルを追加します。
meta_definition (metadefinition_ID(PK), name (varchar), datatype)
次に、meta_user
テーブルを変更します
meta_user (meta_ID (PK), user_ID(FK), metadefinition_ID(FK))
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_user
3 つの列を保持するように縮小します (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
利点: 新しいデータ型が導入された場合でも、クエリを変更する必要はありません。