我正在设计一个使用 Oracle 的应用程序,我们需要在数据库中映射部门层次结构。有些事情看起来像这样(我很确定你们都知道我在说什么,但为了以防万一,我会包括一部分ERD):
因此,它将存储如下数据:
[1 | 0]
[2 | 1]
[3 | 2]
[4 | 2]
换句话说:
Department 1
|__Department 2
|___Department 3
|___Department 4
等等......
这将改善表格上所需的记录数量,并且可以使用 CONNECT BY 命令访问数据,每个部门只需1个记录。我们通常将这个树结构作为解决方案,但在这个新的应用程序中,性能是关键的,所以我想知道如果我有一个看起来像这样的扁平表。
[1 | 0]
[2 | 1]
[3 | 1]
[3 | 2]
[4 | 1]
[4 | 2]
这使您可以拥有非常明显的关系,而无需知道给定孩子的父部门知道他们的上层部门是谁。但这会增加所需的数据量,因为您需要一个部门所在的每个级别的记录,这意味着如果一个部门的级别低于最高级别,我们将需要15个记录。 该部门相当大,所以这可能最终成为一个巨大的表(约200万条记录)。
好的,所以在简介之后,这就是问题;有人真的试过这个可以告诉我这两个选项之间的DB更快/更便宜的东西,巨大的平台还是小树?
答案 0 :(得分:7)
我肯定会选择第一种选择(分层方法)。我认为正确建模数据比仅使用不良数据模型获得性能更好。由于您在此处对层次结构进行建模,因此将其存储在数据库中是有意义的。
如果您想要两全其美,我的建议是使用materialized view来“压扁”分层数据,然后您仍然可以正确存储数据,但您可以获得性能提升(如果有的话)使用物化视图。
几乎总有一种方法可以遵循良好的数据模型,并且仍然可以找到获得良好性能的方法。但是一个糟糕的数据模型将在未来几年花费你的成本,以后需要付出很大的努力。
然而,即使使用扁平化方法,您也必须考虑到显着增加记录数量,尤其是当您到达树中的叶节点时,所以如果有一个平面层次表,我会感到惊讶(因为还有更多的记录需要处理,所以你的第二种方法会提高性能。
答案 1 :(得分:2)
快速访问分层数据的替代方法是嵌套集数据模型:
它允许您对所有子节点进行单次访问, 无论深度如何,都可能需要离线维护, 取决于你的实施。
答案 2 :(得分:0)
如果您需要阅读效果,请尝试路径枚举。
[1 | 0]
[2 | 1]
[3 | 2]
[4 | 2]
变为
[1 | '0']
[2 | '0.1']
[3 | '0.1.2']
[4 | '0.1.2']
所以你可以通过
选择所有2个孩子SELECT * FROM dept WHERE path LIKE '0.1.2%'
当然,这是规范化与绩效之间的妥协。
答案 3 :(得分:0)
对于像Departments这样的东西,表中的记录不可能存在性能问题。甚至不用担心。
即使有一些其他类型的历史数据,可能会有很多记录表明性能可能受到影响,但总会有其他技术/方法来解决这些性能问题(当它们弹出时),以及实现这些数据的成本其他解决方案几乎总是低于尝试使用平面模式对系统进行编码时所产生的开发和维护工作量的增加。