我是一名软件开发人员。我喜欢编码,但我讨厌数据库……目前,我正在创建一个网站,允许用户在该网站上将实体标记为 喜欢 (如在 FB 中)、 标记 它并 发表评论 。
我被困在处理这个功能的数据库表设计上。解决方案是微不足道的,如果我们只能对一种类型的事物(例如照片)执行此操作。但是我需要为 5 种不同的东西启用它(目前,但我也假设这个数字会随着整个服务的增长而增长)。
我在这里发现了一些类似的问题,但没有一个有令人满意的答案,所以我再次问这个问题。
问题是,如何正确、 高效 和 弹性 地设计数据库,以便它可以存储不同表格的评论 、 不同 表格 的 喜欢 和 标签 。一些设计模式作为答案将是最好的;)
详细描述 :我有一个包含一些用户数据的 表格,还有 3 个 表格 :有 照片 、有 文章 、有 地点 。我想让任何登录的用户能够:User Photo Articles Places
User
Photo
Articles
Places
评论这三个表中的任何一个
将其中任何一个标记为喜欢
用一些标签标记它们中的任何一个
我还想计算每个元素的喜欢次数以及使用特定标签的次数。
第 一种方法:
a) 对于 标签 ,我将创建一个 表 ,Tag [TagId, tagName, tagCounter]然后我将为:、、、 。创建 多对多 关系 表 。Photo_has_tags``Place_has_tag``Article_has_tag
Tag [TagId, tagName, tagCounter]
Photo_has_tags``Place_has_tag``Article_has_tag
b) 评论的数量相同。
c) 我将创建一个 表 LikedPhotos [idUser, idPhoto], LikedArticles[idUser, idArticle], LikedPlace [idUser, idPlace]。 喜欢 的数量将通过 查询 来计算(我认为这是不好的)。和…
LikedPhotos [idUser, idPhoto]
LikedArticles[idUser, idArticle]
LikedPlace [idUser, idPlace]
我真的不喜欢最后一部分的这种设计,它对我来说很难闻;)
第二种 方法: _
我将创建一个表格ElementType [idType, TypeName == some table name],由管理员(我)使用可以被 喜欢 、 评论 或 标记的 表格 名称填充。然后我将创建 表 :
ElementType [idType, TypeName == some table name]
a)LikedElement [idLike, idUser, idElementType, idLikedElement]对于评论和标签也是如此,每个都有适当的列。现在,当我想制作一张喜欢的照片时,我会插入:
LikedElement [idLike, idUser, idElementType, idLikedElement]
typeId = SELECT id FROM ElementType WHERE TypeName == 'Photo' INSERT (user id, typeId, photoId)
和地方:
typeId = SELECT id FROM ElementType WHERE TypeName == 'Place' INSERT (user id, typeId, placeId)
等等......我认为第二种方法更好,但我也觉得这个设计也缺少一些东西......
最后,我也想知道在哪个位置存储元素被喜欢多少次的计数器最好。我只能想到两种方法:
Photo/Article/Place
我希望我现在对这个问题的解释更彻底。
最可扩展的解决方案是只有一个“基本”表(连接到“喜欢”、标签和评论),并从中“继承”所有其他表。添加一种新的实体只需要添加一个新的“继承”表——然后它会自动插入到整个喜欢/标签/评论机制中。
实体关系术语是“类别”(参见 ERwin 方法指南,部分:“子类型关系”)。类别符号为:
假设用户可以喜欢多个实体,同一个标签可以用于多个实体,但评论是特定于实体的,您的模型可能如下所示:
顺便说一句,实现“ER 类别”的方法大致有 3 种:
除非您有非常严格的性能要求,否则第三种方法可能是最好的(即物理表与上图中的实体 1:1 匹配)。