Database design 如何在列上存储元数据
假设您正在收集即将上映的超级英雄电影的内幕信息,您的主电影表如下所示:Database design 如何在列上存储元数据,database-design,normalization,entity-attribute-value,Database Design,Normalization,Entity Attribute Value,假设您正在收集即将上映的超级英雄电影的内幕信息,您的主电影表如下所示: Movie DirectorSource DirectorJournalist LeadingMaleSource LeadingMaleJournalist ... --------------------------------------------------------------------------------------- The Tick Yahoo Cameron
Movie DirectorSource DirectorJournalist LeadingMaleSource LeadingMaleJournalist ...
---------------------------------------------------------------------------------------
The Tick Yahoo Cameron ... ...
表1
Title Director Leading Male Leading Female Villain
--------------------------------------------------------------------------
Green Lantern Kubrick Robert Redford Miley Cyrus Hugh Grant
The Tick Mel Gibson Kevin Sorbo Linda Hunt Anthony Hopkins
这在一般情况下应该工作得很好,并且允许非常简单的查询以及行之间的比较
但是,您希望跟踪每个数据事实的来源,以及发现事实的记者的姓名。这似乎是一张类似这样的桌子:
Movie DirectorSource DirectorJournalist LeadingMaleSource LeadingMaleJournalist ...
---------------------------------------------------------------------------------------
The Tick Yahoo Cameron ... ...
表2
Movie Attribute Value Source Journalist
----------------------------------------------------------------------------------
Green Lantern Director Kubrick CHUD Sarah
Green Lantern Leading Male Robert Redford CHUD James
Green Lantern Leading Female Miley Cyrus Dark Horizons James
Green Lantern Villain Hugh Grant CHUD Sarah
The Tick Director Mel Gibson Yahoo Cameron
...
虽然它很容易捕获我们想要的元数据,但这使得查询更加困难。简单地获得一部电影的所有基本数据需要更多的时间。更具体地说,您必须在这里处理四行,以获得关于绿灯的四个重要信息,而在表1中,它是一个单独的、封装良好的行
所以我的问题是,考虑到我刚才描述的复杂性,并且因为我知道通常要避免EAV表,所以EAV仍然是最好的解决方案吗?似乎这是表示这些数据的唯一合理方式。我看到的唯一其他选择是将表1与另一个仅包含以下元数据的表结合使用:
Movie DirectorSource DirectorJournalist LeadingMaleSource LeadingMaleJournalist ...
---------------------------------------------------------------------------------------
The Tick Yahoo Cameron ... ...
表3
Movie Attribute Source Journalist
----------------------------------------------------------------------------------
Green Lantern Director CHUD Sarah
Green Lantern Leading Male CHUD James
Green Lantern Leading Female Dark Horizons James
Green Lantern Villain CHUD Sarah
The Tick Director Yahoo Cameron
...
但这是非常危险的,因为如果有人将表1中的列名(如“Villain”更改为“Primary Villain”),表3中的行仍将简单地表示为“Villain”,因此相关数据将不幸地解耦。如果“attribute”列链接到另一个用作表1列枚举的表,则这可能会有所帮助。当然,DBA将负责维护该枚举表,以匹配表1的实际列。实际上,可以通过在SQLServer中使用包含表1中列名称的系统视图,而不是手动创建枚举表来进一步改进这一点。虽然我不确定您是否可以拥有涉及系统视图的关系
你有什么建议?EAV是唯一的出路吗
如果它只是一个元数据列(只有“源”而没有“记者”)——它仍然需要走EAV路线吗?你可以有“Director”、“Director\u Source”、“Leading Male”、“Leading Male\u Source”等栏目,但这很快就会变得难看。有没有更好的解决办法我没想到
如果我没有澄清任何一点,请发表评论,我会根据需要补充更多。哦,是的,我使用的电影数据是伪造的:)
编辑:为了简洁地重申我的主要问题,我希望有表1的简单性和真正的RDBMS设计,它确实很好地描述了电影条目,同时仍然以安全和可访问的方式存储属性上的元数据。这可能吗?还是EAV是唯一的方法
编辑2:在做了更多的web研究之后,我还没有找到一个关于EAV的讨论,它围绕着在列上存储元数据的愿望展开。实现EAV的主要原因几乎总是动态的和不可预测的列,在我的示例中并非如此。在我的例子中,总是有相同的四列:导演、男主角、女主角、反派。然而,我想为每一行存储关于每一列的某些事实(来源和记者)。EAV会促进这一点,但我希望避免使用它
更新
使用表2设计,除了将列“Movie”重命名为“Name”并调用整个表“Movie”,下面是SQL Server 2008中获取表1的透视操作:
SELECT Name, [Director], [Leading Male], [Leading Female], [Villain]
FROM (Select Name, Attribute, Value FROM Movie) as src
PIVOT
(
Max(Value)
FOR Attribute IN ([Director], [Leading Male], [Leading Female], [Villain])
) AS PivotTable
我的回答似乎有点过于哲学化。请容忍我 我认为“源”栏不是主题数据,而是元数据。这实际上是关于我们如何知道其他一些数据的数据。这使得它成为关于数据的数据,这就是元数据 EAV造成问题的原因之一是它将数据和元数据混合在一行中。有时候,我自己故意这么做,作为实现我想要的结果的中间步骤。但我从未尝试过在我的可交付成果中混用数据和元数据
我知道为什么我从来没有这样做过,但我不能简明扼要地解释它。因为没有其他人真正尝试过,所以我要回答我自己的问题。我敢肯定,像EAV这样的桌子确实是唯一的选择。要在每个列上存储元数据(在本例中是关于源和记者的),实际上是将每个列本身视为一个实体,这是EAV所允许的
您可以选择其他方法,比如为每个原始列添加第二列和第三列来存储数据,但这肯定会破坏一些基本的规范化规则,可能只会在以后给您带来痛苦。Hmm。。。。我没有使用过这个,所以我不是根据经验(也就是说,如果它不起作用,请不要怪我),但表面上看,您可以存储“公共”数据,您知道这些数据将始终存在,就像在普通表中一样,以及可能会更改为XML的“元数据”。接下来的问题是如何很好地查询它,我认为您可能能够像前面所描述的那样进行查询 有趣的场景。你可以通过将你的实体视为第一类对象来绕过EAV贫民区;让我们称之为事实。这有助于你在这种情况下非常正交,因为每部电影都有完全相同的四个事实。您的EAV表可以是原始/正确的表,然后您可以有一个外部进程来挖掘该表,并将数据复制到正确的规范化形式(即第一个表)。通过这种方式,您可以获得所需的数据及其元数据,并且可以方便地查询电影信息,精确到挖掘过程运行的频率 我认为您确实需要一些“数据库外”的肌肉来确保数据保持有效,因为似乎没有任何I
MovieID | Movie Name | Director | LeadingMale | LeadingFemale | PrimaryVillain | etc
Table Movie
========================
MovieID NUMBER, PrimaryKey
MovieName VARCHAR
Table MovieFact
========================
MovieID NUMBER, PrimaryKeyCol1
FactType VARCHAR, PrimaryKeyCol2
FactValue VARCHAR
FactSource VARCHAR
FactJournalist VARCHAR
Movie Table
====================================================================================
MovieID MovieName
====================================================================================
1 Green Lantern
2 The Tick
MovieFact Table
====================================================================================
MovieID FactType FactValue FactSource FactJournalist
====================================================================================
1 Director Kubrick CHUD Sarah
1 Leading Male Robert Redford CHUD James
1 Leading Female Miley Cyrus Dark Horizons James
1 Villain Hugh Grant CHUD Sarah
2 Director Mel Gibson Yahoo Cameron
2 Leading Male John Lambert Yahoo Erica
...