5

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

我有三张桌子:

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

架构 A!

我看到的问题是我不能限制电影的同一属性的多个属性值。IE ("godfather","USA","JAPAN") 是一个有效的声明限制应该由应用程序控制

模式 B

模式 B

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

("godfather","Country:USA","Country:JAPAN") 是一个有效的声明

模式 C

模式 C

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

但是我不知道让attribute_value成为一个弱实体是否正确,更好或更坏:S

模式 D

模式 D

正如我所说,与 C 相同,但在属性值中具有复合键。我不确定这是否会破坏某些数据库规范化规则。如果没问题,应该从movie_attribute_value 中为字段attribute_id 引用哪个表?来自 Attribute 表的 Attribute ID 还是来自 AttributeValue 表的 AttributeID?可以使用复合外键并仅使用 PK 中的一部分键吗?

您能否解释一下选项更好,为什么?

提前致谢!

编辑

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

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

4

2 回答 2

4

正如 Marc_s 评论的那样,EAV 设计有很多缺点。在电影收藏的情况下,您知道架构,并且它不太可能随机更改,并且当它确实发生更改时(例如,您需要添加一个“4K 可用”标志),这可能是一件大事。

问问自己,您将如何检索给定类型的所有电影,或在美国和日本都可用的所有电影,或在美国但不是日本可用的所有喜剧——您将很快看到 EAV 的限制。

为了回答你的问题——你的设计都不适合我——有太多的桌子没有得到他们的保留。如果你真的必须去 EAV,我建议:

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


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

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

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

如果您真的想将值放在单独的表中,那么模式 D 似乎是正确的。

模式 C 说:

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

我认为最后的说法是不正确的。

于 2013-09-20T10:57:28.230 回答
1

一种方法是将所有属性与定义的属性类型一起集中在一个表中。因此:

Movies
------
MovieId


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


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


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

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

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

于 2013-09-20T13:44:14.300 回答