我对此的贡献是:
当您应该为元数据实现名称时,请添加一个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:保持您将所有可能数据类型的值存储在一行中的设计,从而生成一个稀疏表。
这是最容易实现的,但就“干净设计”(我的观点)而言是最丑陋的。
变体 B:每种数据类型使用不同的值表:meta_user
您可以使用 6 个表meta_number
, meta_decimal
, . 而不是一个稀疏表meta_string
。每个表都具有以下形式:
meta_XXXX (metadata_ID(PK), meta_ID(FK), value)
恕我直言,这是最干净的设计(但使用起来有点复杂)。
变体 C:reducemeta_user
以保存三列(我将其重命名为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
为给定用户选择值将是 Variant A: select u.name, md.name as 'AttributeName', mv.* -- show all different data types from user u join meta_user mu on u.user_ID = mu.userID join md.metadefinition_ID = mu. 上的 meta_definition md。metadefinition_ID join meta_value mv on mv.meta_ID = mu.metaID
缺点:当有新的数据类型可用时,您必须添加一列,重新编译查询并更改您的软件。
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
优点:在引入新数据类型的情况下不必更改查询。