我必须设计一个能够引用变量其他实体的通用实体。
在我的示例中,这将是Web应用程序中的commentary
实体。您可以将评论发布到users
,classifieds
,articles
,varieties
(植物),等等。
这样的实体就是这样的:
事实上,设计(种类)模式将是这样的:
这种模式的优点和缺点是什么?
我看到的是:
您可以轻松地聚合这些对象(例如,此用户在整个网站中的最后评论,可以在同一个帖子中轻松呈现);
这可以让你陷入丑陋的境地(你使用它非常丑陋,你的数据库和源代码很难看);
这种模式是否适合关系数据库?那我们怎么办?
先谢谢你。
答案 0 :(得分:2)
还有一个问题:
此方案依赖于这些值所引用的“实体”的值和名称之间的映射。想想你将解决问题的所有乐趣,在TEST系统中,ORDER实体的编号为734,但在生产中,它的编号为256.您可以使用实体名称本身作为entity_id内容的值,但是你会无论如何,永远无法避免在程序中(或者,在视图定义中)为它们编写硬编码值。从而击败了你认为可以获胜的任何优势。
这种方案是OO程序员主要遭受的疾病。他们看到的结构大致相似,他们有这种本能的反应“我必须找到一种方法来补充现有的东西”。忘记数据库设计不是程序设计。
修改
(如果不清楚,这意味着我对你的问题的答案“这种模式是否适用于关系数据库?”是原则性的“否”。)
答案 1 :(得分:1)
这是经典的Polymorphic Association反模式。有许多可能的解决方案:
1)专属弧,例如对于评论实体
Id
User_Id
Classified_Id
Article_Id
Variety_Id
User_Id,Classified_Id,Article_Id和Variety_Id可以为空,其中一个必须为空。
2)撤销关系,例如从评论实体中移除Target_Entity和Target_Entity_Id并创建四个新实体
User_Commentary
Commentary_Id
User_Id
Classified_Commentary
Commentary_Id
Classified_Id
Article_Commentary
Commentary_Id
Article_Id
Variety_Commentary
Commentary_Id
Variety_Id
其中Commentary_Id是唯一的并且与评论中的Id相关。
3)为User,Classified,Article和Variety创建一个超类型实体,让Commentary实体引用这个新实体的唯一属性。
您需要根据具体情况决定哪种方法最合适。