然后,您应该有一个表来存储 all 之间所有可能的父子关系BudgetItems,可能称为BudgetItemHierarchy(或您认为合适的任何更好的名称)。它将有两列,BudgetItemParentId和,都是对您的表BudgetItemChildId的外键引用。BudgetItems还会有一BudgetAmount列对应于 BudgetItemChildId.
拥有这两个表将允许您存储任意数量的预算对象和预算对象类型,而不会有许多冗余表。然后在大多数现代关系数据库管理系统中,您可以使用递归,例如递归 CTE(注意此资源是 Microsoft SQL Server 特定的,但通常在其他数据库系统中可用)来计算BudgetItems任何子集或完整集的任何列表他们的层次结构与每个级别的所有个人BudgetAmounts,甚至是任何数量或所有级别的汇总总和。
老实说,这看起来像是一个经典的分层问题,通常可以通过每个唯一项目的单个表和一个包含每个父子关系的单独的自引用表来解决。这是制造业中的一个常见问题,但即使在预算用例中也明显适用。
因此,您有一系列项目,它们在对象定义上都相似,但层次结构不同,a
Program
,Activity
,Sub-Activity
。而不是为每个定义单独的表,您应该有一个可能称为 的表BudgetItems
,它将存储这些对象的每个实例的唯一列表。该表可以有一个单独的字段来标识它的对象类型BudgetItemType
。(它也会有它的Id
和Name
列。)然后,您应该有一个表来存储 all 之间所有可能的父子关系
BudgetItems
,可能称为BudgetItemHierarchy
(或您认为合适的任何更好的名称)。它将有两列,BudgetItemParentId
和,都是对您的表BudgetItemChildId
的外键引用。BudgetItems
还会有一BudgetAmount
列对应于BudgetItemChildId
.拥有这两个表将允许您存储任意数量的预算对象和预算对象类型,而不会有许多冗余表。然后在大多数现代关系数据库管理系统中,您可以使用递归,例如递归 CTE(注意此资源是 Microsoft SQL Server 特定的,但通常在其他数据库系统中可用)来计算
BudgetItems
任何子集或完整集的任何列表他们的层次结构与每个级别的所有个人BudgetAmounts
,甚至是任何数量或所有级别的汇总总和。