【问题标题】:Best Practices for Overlapping Object/Data Entity Types重叠对象/数据实体类型的最佳实践
【发布时间】:2016-01-23 00:10:19
【问题描述】:

有时我会遇到以下所有条件都适用于两个高度相似但不完全相同的实体或对象的情况。这让我很难决定如何对它们进行建模,无论是在数据库端还是在对象建模方面。我将尝试详细说明问题和我的问题,因为我发现它是一个非常难以定义的建模问题。我正在尝试对这些实体进行数据和对象建模,因此我将稍微松散地使用这两个学科的术语。

1) 两个实体共享许多相同的属性,但有一些在另一个中没有的独特属性。

2) 一个不是另一个的超类型或子类型。

3) 重叠不是由于对象继承。

4) 对象在同一域中用于不同目的,但在任何工作流程中通常都非常接近。这经常导致那些具有中等领域知识的人混淆实体。另一方面,这种精细的目的分离导致关联对象的方法之间的差异大于它们的属性。

5) 在某些情况下,可以在数据库端创建桥接表来表达实体之间的 M2M 关系。然而,它们有很多共同的属性(或数据库端的列),因此将它们存储在同一个表中可能是有意义的。

我遇到的一些案例包括: 1) “产品与项目的混淆”——尤其是在软件营销中,产品和项目共享许多相同的属性。通常一个产品会有多个与之关联的项目,但一个项目用于多个产品也是不寻常但可以想象的。

2) 软件开发中特性和组件之间的细微差别。从客户的角度来看,功能是以开发人员为中心的一种提供利益的方式,而组件是在开发人员方面实现功能的一种方式。这是一个非常微妙的区别,但仍然很重要。如需进一步讨论,请参阅 Rod Maupin 的帖子http://www.installationdeveloper.com/347/features-and-components-101/

3) 许多不同问题领域中的模板与类型。例如,当通过 TypeID 列识别吉他的类型时,它所引用的 TypeTable 可能具有与颜色、琴弦大小、琴体形状等对应的列。另一方面,模板是您要构建吉他的东西from,因此它的方法与类型不同,可能链接到“应用模板”或“从模板制作项目”菜单命令。然而,它会有许多与类型相同的列或属性,例如颜色、形状、字符串大小等。这种区别在许多问题领域的数千种不同的对象类型和模板中引起了人们的注意,而不仅仅是这个狭窄的例子。更复杂的是,在某些情况下,将多个模板与特定类型相关联可能会有所帮助,反之亦然。

我并没有经常遇到实体重叠的问题,但是一旦发生,它就会成为真正的瓶颈,并导致大量浪费时间重构数据和对象模型。我已经阅读了有关这两个主题的书籍,并对有关该问题的数据/对象建模网页进行了很多搜索,但尚未看到对其进行讨论。我可以在 StackOverflow 上找到的“重叠”和“数据模型”的唯一匹配是区分一个表或实体中的相似列,而不是跨表或实体。我的问题是:

1) 这个问题有正式名称吗?

2) 是否有一种简单的捷径或交易技巧可以在建模过程开始时识别此类重叠实体,而不是在后期识别导致重构成为问题时更进一步?

3) 应该如何处理这种重叠的实体?我假设就 OOP 而言,它们应该有单独的对象,因为它们的方法往往不同。但是,从另一个继承一个会很尴尬。一个更困难的问题是在数据库端使用单独的表是否有意义。当它们没有共同的属性/列被保留为空时,组合它们可能需要一系列复杂的视图以及浪费的存储空间。但是,如果公共属性可以存储在单个列中,那么将它们存储在单独的表中也可能是一种浪费。

这是一个很难识别的问题,更不用说处理了。我在数据/对象建模方面只有少量经验,因此真正知道自己在做什么的人的输入会有所帮助。谢谢:)

【问题讨论】:

  • 另一个重叠的例子是数据建模与软件工程。我更喜欢使用 OOP 进行系统建模,使用关系模型进行领域建模,保持学科正交。

标签: oop orm entity data-modeling database-normalization


【解决方案1】:

您的问题涉及数据库建模方面和面向对象(编程)建模方面。让我们从抽象的角度开始。

你说:

1) 两个实体共享许多相同的属性,但有一些在另一个中没有的独特属性。

2) 一个不是另一个的超类型或子类型。

和:

3) 重叠不是由于对象继承。

但请注意,inheritance 不应与 subtyping 混淆,即使它们很多时候都捆绑在一起!例如,参见 Wikipedia 中的 Inheritance (object-oriented programming),该声明得到了两个引用 [1,2] 的支持。

也就是说,即使A不是B的子类型,B也不是A的子类型,你也可以找到A和B都继承属性的C。

所以,你可以认为这个 C 是 A 和 B 的“抽象超类型”;但无论如何,至少从数据库的角度来看,将其视为共同祖先是方便的,以便将共同属性分解为“超级表”。

然后,从面向对象编程的角度来看,您可以将 A 或 B 视为 C 的子类型,或者简单地视为两种不同的事物,这取决于您的对象关系映射工具的特性、手头的问题等。

当然,这种建模方式并不禁止 A 和 B 除了从 C 继承之外,还具有一种或多种关系,如您所做的示例 Products-Projects。

所以,这是我对你最后四个问题的回答:

1) 是的,这叫继承。

2) 您可以检查两个实体是否有大量的共同属性。

3) 您可以在数据库中使用一个公共表对它们进行建模,该表可能具有一些公共属性,如完整性约束,以及两个具有外键的表。当然,这条规则不能盲目应用,但可以像所有人类规则一样有例外。另一方面,从编程的角度来看,您可以决定是否使用超类型对它们进行建模。这取决于许多因素,应根据具体情况决定。

【讨论】:

  • 感谢您的反馈,我还有 2 个问题。我没有使用继承的原因之一是在我看到的示例中,两个实体都不是明显占主导地位的。如果我使用超类型,我可以从那里继承两者吗?我也没有使用超类型,因为没有包含模板和类型、产品和项目或功能和组件的真实世界对象。为虚拟超类型创建基表并为基表使用一些通用名称(如 TemplateTypeTable、ProductProjectTable 或 FeatureComponentTable)是否明智?谢谢! :)
  • P.S.我打算赞成你的答案,但必须等到我得到足够的代表点。 :)
  • 1) 是的,您可以从同一个超类型继承两者。 2)我认为这是合理的,特别是如果你有许多共同的属性。有时我发现,在定义了一个通用的超类型之后,我还发现了一些有用的操作。附言即使您不能投票,您也可以通过点击标记来接受答案,但只有在您对答案满意时才这样做 :)
  • 完成 :) 我认为我的问题中只有一个小问题没有得到解答:在数据或对象建模术语中是否有这个重叠实体问题的正式/非正式名称?这部分没什么大不了的,只是为了方便。
  • 谢谢。正如我所说,您可以将其称为继承,因为这就是发生的情况:一个类型从另一个类型继承属性(即使它不是子类型)。
猜你喜欢
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多