Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL is-a/has-a/is-a结构和验证_Sql_Postgresql - Fatal编程技术网

SQL is-a/has-a/is-a结构和验证

SQL is-a/has-a/is-a结构和验证,sql,postgresql,Sql,Postgresql,考虑下面的例子。当我写“is-a”时,我指的是一个列,它既是表的主键,也是另一个表的外键,以形成一对一的关系。当我写“has-a”时,我指的是一个常规的外键列,以形成一对多的关系 果篮桌 一张applebasket桌子,“是一个”果篮 一张橘子饼桌,“是一个”果篮 一张水果桌,“有一个”果篮 一张苹果桌,“是一种”水果 一张橙色的桌子,是一种水果 目前,假设applebasket、orangebasket、apple和orange中存在上下文特定的列,足以保证该表的存在,而不是用可为空的列或

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

  • 果篮桌
  • 一张applebasket桌子,“是一个”果篮
  • 一张橘子饼桌,“是一个”果篮
  • 一张水果桌,“有一个”果篮
  • 一张苹果桌,“是一种”水果
  • 一张橙色的桌子,是一种水果
目前,假设applebasket、orangebasket、apple和orange中存在上下文特定的列,足以保证该表的存在,而不是用可为空的列或类型枚举来扰乱父表

问题:

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

谢谢……

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

例如,假设我们有两个应用程序。一种是提取数据并对其进行操作,然后对行为进行建模。第二种方法提取数据,将其视为静态数据,并派生信息。就像你自己一样,如果LSP允许你说“一个正方形就是一个矩形。”在第一种情况下,不是。在第二种情况下,是的。在第一种情况下,您可能希望使用has-a“矩形区域”,在第二种情况下,“is-a矩形”完全有效

这就引出了我的第二点。如果您考虑的是这种复杂的关系,那么如何进行映射可能取决于您对数据所做的操作。一般来说,最好基于定义元素而不是行为元素来约束数据。因此,在本例中,您可以在任何需要的地方使用映射。然后,我将提出以下建议:

  • 水果(储存苹果、梨、橘子等)
  • 您需要的任何补充表格
  • 果篮
  • 许多映射表显示了果篮中的水果种类
  • 这让我特别想到你的问题:

    将水果和果篮联系起来是更好的做法,还是将苹果和苹果饼+橙子和橙子饼联系起来

    两者都有。同时,。见上文

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

    声明性引用完整性将带您一路到达目的地。不要害怕使用双向外键,其中一侧设置为DEFERRABLE Initial DEFERRED