【问题标题】:Chained inheritance in sqlsql中的链式继承
【发布时间】:2017-08-14 20:11:06
【问题描述】:

我正在尝试在我的应用程序架构中创建链式继承情况。我想要有各种位置分组,从大到一个国家到小到一个地址,国家>地区>州>城市>地址,以及像“蓝色组”和“贵宾位置”这样的任意分组。

您可以看到我刚刚创建的一个示例表,用于表示可能的实体

因此,美国东北部纽约市纽约市的 Broadway Ave 一直沿用美国曾祖父母位置的“#8b0000”颜色,但会使用它自己的“macys.png”封面照片。不列颠哥伦比亚省将从其加拿大的父位置获得它的颜色和照片。等等。

一般来说我的目标是:

  • 每个位置都可以有自己的数据或空值。
  • 继承特征(例如,如果巴黎没有自己的颜色,则可以从法国继承它的颜色)
  • 用户可以创建任意分组(“蓝色组”、“表现不佳者”)

这只是我的第一次通过方法。

SQL 是否适合这种继承?例如,以这种链式继承方式,我似乎不太可能很容易地用 sql 从同一张表中的祖先中select 数据。

有什么更好的方法来解决这个问题?

【问题讨论】:

  • 我想为此目的推荐 ORM,请参阅一个好的 ORM “doctrine orm”。对于关系和继承,我更喜欢 ORM。因为你已经标记了 PHP 这就是为什么。如果是 SQL 应用程序,那么 stackoverflow.com/questions/3579079/…
  • 你可以在 sql 中做你想做的事,但在我看来,好像你希望有人免费为你解决它......我并不惊讶没有人回答。
  • 我还想补充一点,解决方案可能最终无法通过隐藏在幕后但尚未在您的问题中指定的标准。比如你要支持多少行,几百万,几亿,几千等等。您可以提出一个通用/动态模型,它可以支持任何属性,但性能可能会受到影响,并且从中查询可能会更加困难(并非不可能)。一般来说,我个人喜欢为不同的实体使用不同的表。这些实体是否具有在设计时已知的属性?
  • 对我的第一条评论的一个更正:“没有人回答到目前为止”。
  • 不,只是想降低走死胡同的风险。

标签: php sql mysqli database-design architecture


【解决方案1】:

看起来我们拥有的是分层数据。最好用树表示的数据。

最适合此类数据的是 XML 或 JSON。但是,在 SQL 中也有很多方法可以表示这种类型的数据。 DB Architect Bill Karwin - 作者 SQL Antipatterns - 详细讨论了它们here。选择最适合您的。

您当前的表格设计是adjacency list。它可以使用,但有一些警告。首先,它不能处理任意数量的级别。这意味着您必须提前知道您将支持的最高级别。从您的示例来看,这看起来像五个。美国位居榜首。百老汇大道。在底部。

查询一个五层邻接列表将是 5X 自连接,就像这样。

SELECT 
    t1.name AS Lev1Name, 
    t2.name as Lev2Name, 
    t3.name as Lev3Name, 
    t4.name as Lev4Name, 
    t5.name as Lev5Name,
    COALESCE(t5.name,t4.name,t3.name,t2.name,t1.name) AS InheritedName,
    COALESCE(t5.color,t4.color,t3.color,t2.color,t1.color) AS InheritedColor
FROM MyTable AS t1
LEFT JOIN MyTable AS t2 ON t2.parent_location_id = t1.id
LEFT JOIN MyTable AS t3 ON t3.parent_location_id = t2.id
LEFT JOIN MyTable AS t4 ON t4.parent_location_id = t3.id
LEFT JOIN MyTable AS t5 ON t5.parent_location_id = t4.id
WHERE t1.name = 'USA'

这行得通,但是哎呀。这不是最优雅的。它仍然可以满足您的需求。 更新:添加了一些 COALESCE 列,以便您可以查看“继承”值。根据用户的需要,您可能希望将该表从邻接列表重新设计为其他选项之一。查看 Mike Hillyer 的精彩文章 here,了解如何将邻接列表转换为嵌套集。

祝你的设计好运!

【讨论】:

  • 当前 OP 的表设计可以使用递归 CTE(通用表表达式)轻松处理任意数量的级别。据我所知,它一直在 Standard since 1999 中,并且在 2017 年得到了 many DBMSs 的支持,只是没有得到 MySQL 的支持。
  • OP 正在使用 MySQL。所以递归 - 不幸的是 - 这里不是一个选项。但是,任意深度的好处并不总是邻接表模型的限制。
  • 嵌套集方法实际上是我以前在第三方库中看到的东西,现在我知道-为什么-采用这种方法。所以我很可能会尝试使用它。但在此之前,我一定会查看您链接的资源。这是我需要的那种身体检查,谢谢。
猜你喜欢
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多