我正在尝试理解数据库设计的一些概念。
我有三张桌子:
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
问题我看到的是我不能为电影限制相同属性的多个attribute_values。 I.E(“教父”,“美国”,“日本”)是一个有效的声明 限制应由应用程序控制
架构B
它与Schema A几乎相同,但使属性值成为弱实体。我认为这对数据库级别没有影响,但是由于您需要属性键,因此获取属性值会更加困难。这个模式允许重复使用相同的类别,具有不同的值,多次,所以我认为这也不是一个好的选择。与选项A一样,限制应由应用程序控制
(“教父”,“国家:美国”,“国家:日本”)是有效的陈述
架构C
我认为这是正确的,因为现在我们不能为电影添加多于1个相同类型的属性 “教父”,“美国”,“日本”不是有效的插入!
但我无法判断将attribute_value设为弱实体是否正确,无论是好还是坏:S
架构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)
答案 0 :(得分:4)
正如Marc_s评论的那样,EAV设计有许多缺点。在电影收藏的情况下,你知道架构,它不太可能随机改变,当它发生变化时(例如你需要添加“4K中可用的标志”),这可能是一个大问题。
问问自己如何检索特定类型的所有电影,或美国和日本的所有电影,或美国但不是日本的所有电影 - 你很快就能看到EAV的极限。 / p>
要回答你的问题 - 你的设计都不适合我 - 有太多桌子无法保留。如果你真的必须去EAV,我建议:
MOVIES
---------
MovieID
.....
ATTRIBUTES
--------------
AttributeID
AttributeName
MOVIE_ATTRIBUTES
------------
MovieID
AttributeID
Value
如果要提供有效值列表,最简单的方法是查询“电影属性”表并检索电影和属性组合的先前条目 - 保持模式简单将使生活更轻松。
如果您确实希望将值放在单独的表中,则架构D显示正确。
架构C说:
我认为最后一句话不正确。
答案 1 :(得分:1)
一种方法是将一个表中的所有属性与定义的属性类型混为一谈。因此:
Movies
------
MovieId
AttributeTypes
---------------
AttributeTypeId
Description
Attributes
---------
AttributeId
AttributeTypeId
Description
MovieAttributes
---------------
MovieId
AttributeId
它可能会导致查询尴尬,但这实际上取决于存储数据的使用方式。
(换句话说,是的,我同意之前的帖子,并建议避免使用EAV结构。)