0

考虑以下示例。当我写“is-a”时,我的意思是一个列,它既是其表的主键,又是另一个表的外键,以形成一对一的关系。当我写“has-a”时,我的意思是一个常规的外键列,形成一对多的关系。

  • 水果篮桌。
  • 一个applebasket 桌子,“is-a”水果篮。
  • 橙色篮子桌,“is-a”水果篮。
  • 水果桌,“有”水果篮。
  • 一张苹果桌,“is-a”水果。
  • 橙色的桌子,“is-a”水果。

暂时假设在 applebasket、orangebasket、apple 和 orange 中有特定于上下文的列,足以保证该表的存在,而不是用可空列或类型枚举使父表混乱。

问题:

  • 将水果和水果篮关联起来,还是将苹果和苹果篮+橙子和橙子篮关联起来更好?前者似乎不那么多余,但可能具有无效的关系(例如,apple -> fruit -> fruitbasket -> orangebasket)。后者强制关系有效,但更冗余,并要求任何其他继承的水果表声明自己的篮子外键。
  • 特别是对于 PostgreSQL,给定第一选择(将水果与水果篮相关联),我检查关系有效性的最简单方法是什么?它必须执行三个连接。
  • 还有其他建议可以干净地实施吗?

谢谢...

4

1 回答 1

1

我认为您对此的看法有些错误。关系数据建模是关于数据的,而对象建模是关于行为的。 这些是不同的学科,就像我喜欢做的对象关系数据建模一样,has-a 和 is-a 不属于数据库。而是查看功能依赖关系并对其进行建模。否则,如果您有多个应用程序试图以不同的方式访问相同的数据,您最终可能会遇到问题。

例如,假设我们有两个应用程序。一个人提取数据并对其进行操作,并对行为进行建模。第二个提取数据,将其视为静态,并获取信息。如果 LSP 允许您说“正方形是矩形”,就像您自己一样。在第一种情况下,没有。在第二种情况下,是的。在第一种情况下,您可能想要使用 has-a “rectangular_area”,而在第二种情况下,“is-a rectangle”是完全有效的。

所以这让我想到了我的第二点。如果您正在查看这种复杂的关系,您如何进行映射可能取决于您对数据所做的工作。一般来说,最好根据定义元素而不是行为元素来约束您的数据。因此,在这种情况下,您可以在任何需要它们的地方进行映射。然后我会建议以下内容:

  1. 水果(储存苹果、梨、橙子等)。
  2. 您需要的任何补充表格。
  3. 水果篮
  4. 多对多映射表,显示水果篮中的水果种类。

这让我特别想到了你的问题:

将水果和水果篮关联起来,还是将苹果和苹果篮+橙子和橙子篮关联起来更好?

两个都。同时。往上看。

特别是对于 PostgreSQL,给定第一选择(将水果与水果篮相关联),我检查关系有效性的最简单方法是什么?

声明性参照完整性将带您一路走来。不要害怕使用一侧设置为 DEFERRABLE INITIALLY DEFERRED 的双向外键。

于 2012-09-17T06:46:10.647 回答