哪些DB设计更好?

时间:2013-09-20 10:47:56

标签: sql database

我正在尝试理解数据库设计的一些概念。

我有三张桌子:

Movies (id,title)
1 - The godfather
2 - Matrix


Attribute (id,name)
1 - Country
2 - Type

Attribute Value(attribute_id,id,value)

1,1,USA
1,2,Japan
2,1,Thriller
2,2,Comedy

我希望将电影与一个属性和一个属性值以及一个属性值

相关联

IE:教父,国家:美国,类型:犯罪

我正在尝试找出下一个是将属性链接到电影的最佳解决方案。我可以看到4种不同的选择:

架构A

Schema A!

问题我看到的是我不能为电影限制相同属性的多个attribute_values。 I.E(“教父”,“美国”,“日本”)是一个有效的声明 限制应由应用程序控制

架构B

Schema B

它与Schema A几乎相同,但使属性值成为弱实体。我认为这对数据库级别没有影响,但是由于您需要属性键,因此获取属性值会更加困难。这个模式允许重复使用相同的类别,具有不同的值,多​​次,所以我认为这也不是一个好的选择。与选项A一样,限制应由应用程序控制

(“教父”,“国家:美国”,“国家:日本”)是有效的陈述

架构C

Schema C

我认为这是正确的,因为现在我们不能为电影添加多于1个相同类型的属性 “教父”,“美国”,“日本”不是有效的插入!

但我无法判断将attribute_value设为弱实体是否正确,无论是好还是坏:S

架构D

Schema D

正如我所说,与C相同,但在attribute_value中使用复合键。 我不确定这是否打破了一些数据库规范化规则。如果没有问题,应该从movie_attribute_value为哪个字段attribute_id引用哪个表?属性表中的属性ID或AttributeValue表中的AttributeID?可以使用复合foreing键并且只使用PK中的一部分键吗?

你能解释一下选项是否更好?为什么?

提前致谢!

修改

我理解像这样的设计的问题,EAV架构是什么以及避免这种类型的架构所需要的,除非在属性表中有很多变化的情况下。不幸的是,这是我的场景,电影的属性是由用户定义的,所以我无法知道将使用哪些属性。我必须阅读它们并显示给其他用户以填充它们。我认为Schema C是正确的,但想知道使用模式A和B的问题是什么,让开发人员控制代码中的限制(每个电影一个相同的类型属性)

如果有人可以解释使用Schema D(复合K)而不是Schema C的好处和缺陷,并且如果只有一些外键字段(attribute_value_id,attribute_id)可以作为PK(movie_id),那么也是很好的,attribute_id)

2 个答案:

答案 0 :(得分:4)

正如Marc_s评论的那样,EAV设计有许多缺点。在电影收藏的情况下,你知道架构,它不太可能随机改变,当它发生变化时(例如你需要添加“4K中可用的标志”),这可能是一个大问题。

问问自己如何检索特定类型的所有电影,或美国和日本的所有电影,或美国但不是日本的所有电影 - 你很快就能看到EAV的极限。 / p>

要回答你的问题 - 你的设计都不适合我 - 有太多桌子无法保留。如果你真的必须去EAV,我建议:

MOVIES
---------
MovieID
.....


ATTRIBUTES
--------------
AttributeID
AttributeName

MOVIE_ATTRIBUTES
------------
MovieID
AttributeID
Value

如果要提供有效值列表,最简单的方法是查询“电影属性”表并检索电影和属性组合的先前条目 - 保持模式简单将使生活更轻松。

如果您确实希望将值放在单独的表中,则架构D显示正确。

架构C说:

  • 对于每部电影,我有0或更多movie_attibute_value记录
  • 对于每个movie_attribute_value_record,我有0个或更多个attribute_value记录
  • 对于每个attribute_value记录,我有零个或多个属性/值组合。

我认为最后一句话不正确。

答案 1 :(得分:1)

一种方法是将一个表中的所有属性与定义的属性类型混为一谈。因此:

Movies
------
MovieId


AttributeTypes
---------------
AttributeTypeId
Description


Attributes
---------
AttributeId
AttributeTypeId
Description


MovieAttributes
---------------
MovieId
AttributeId

它可能会导致查询尴尬,但这实际上取决于存储数据的使用方式。

(换句话说,是的,我同意之前的帖子,并建议避免使用EAV结构。)