分层组的数据库模式

时间:2008-09-22 02:17:25

标签: sql-server database database-design

我正在为用作大型系统基础的组层次结构进行数据库设计。每个组可以包含其他组,也可以包含“设备”作为叶子对象(没有任何东西在设备下面)。

正在使用的数据库是MS SQL 2005.(尽管在MS SQL 2000中工作将是一个奖励;但遗憾的是,此时需要MS SQL 2008的解决方案不可行。)

有不同类型的组,这些组需要在运行时由用户动态定义。例如,组类型可以是“客户”,“帐户”,“城市”或“建筑物”,“楼层”,并且每种类型将具有可由用户定义的不同属性集。还将应用业务规则 - 例如,“楼层”只能包含在“建筑”组下面,并且这些可以在运行时定义。

许多应用程序功能来自基于这些组运行报告,因此需要一种相对快速的方法来获取某个组(以及所有子组)中包含的所有设备的列表。

使用modified pre-order tree traversal技术存储组具有快速的优势,但缺点是相当复杂和脆弱 - 如果外部用户/应用程序修改数据库,则存在完全破坏的可能性。我们还实现了一个ORM层,这个方法似乎在大多数ORM库中使用关系变得复杂。

使用common table expressions和“标准”id / parentid组关系似乎是避免运行多个递归查询的有效方法。这种方法有什么缺点吗?

就属性而言,存储它们的最佳方式是什么?一个长而窄的桌子,与群体有关?是否应该将一个公共属性(如“name”)存储在groups表中,而不是存储在属性表中(很多时候,名称将只显示所需的名称)?

使用这种方法是否会出现性能问题(让我们假设在一个合理的硬件上,平均每个平均有6个属性,平均有10个并发用户,例如四核Xeon 2 Ghz ,4GB内存,折扣任何其他进程)?

随意提出一个与我在此处概述的完全不同的架构。我只是想说明我关心的问题。

4 个答案:

答案 0 :(得分:3)

我建议您实际构建最容易维护的方式(“标准”父/子设置)并至少运行一些基本基准测试。

您会惊讶于数据库引擎可以使用正确的索引编制,特别是如果您的数据集可以适合内存。

假设每组6个属性,2000个组和30个字节/属性,你说的是360KB *预期项目/组 - 数字400KB。如果您希望有1000个项目/组,那么您只需要查看400MB的数据 - 这些数据在内存中没有问题,并且当所有数据都在时,数据库在连接时快速存储器中。

答案 1 :(得分:2)

公用表表达式将让您获得具有父子关系的组列表。 Here是使用CTE用于不同应用程序的sproc的示例。它的效率相当高,但要注意以下几点:

  1. 如果某个部件在层次结构中出现多次,则会在每个位置报告。您可能需要对结果进行后处理。
  2. CTE有点迟钝,并且在查询中过滤结果的范围有限 - CTE在select语句中可能不会出现多次。
  3. Oracle的CONNECT BY稍微灵活一些,因为它不像CTE那样对查询结构施加太多限制,但是如果你使用的是SQL Server,那么这将不是一个选择。

    如果您需要使用中间结果做任何聪明的事情,那么编写一个使用CTE的sproc将原始查询转换为临时表并从那里开始处理它。 SELECT INTO将最大限度地减少此过程中产生的流量。生成的表将位于缓存中,因此对它的操作将相当快。

    可能有所帮助的一些可能的物理优化:

    • 父母的聚集索引 为a获取子节点 父级使用较少的I / O.
    • 大量的RAM和(取决于BOM表的大小)64位 具有更多RAM的服务器,以便主BOM表 可以缓存在核心。在32位O / S上,/ 3G启动交换机是您的朋友,对数据库服务器没有实际缺点
    • DBCC PINTABLE可以帮助强制数据库管理器将表保存在缓存中。

    父属性类型 - 属性编码表不能很好地与CTE一起使用,因为如果包含属性表,最终会在行计数中出现组合爆炸。这将排除查询中过滤属性的任何业务逻辑。 将属性直接存储在BOM表条目上会更好。

答案 2 :(得分:1)

预订树遍历非常方便。您可以通过使用触发器保持遍历数字最新来使其变得健壮。

我使用的类似技术是保留一个单独的(ancestor_id,descendant_id)表,列出所有祖先和后代。这几乎与预订遍历数一样好。

使用单独的表非常方便,因为即使它引入了额外的连接,它也会将复杂性移到单独的表中。

答案 3 :(得分:1)

修改后的预订本质上是Joe Celko的嵌套集方法。他的书“树和层次结构......”涵盖了邻接列表和NS,并描述了每个的优点和缺点。通过适当的索引,邻接列表的CTE获得最平衡的性能。如果你主要是阅读,那么NS会更快。

您似乎在描述的是物料清单处理器。虽然不是M $,但Graeme Birchall有一本免费的DB2书,其中有一章使用CTE进行层次结构处理(语法实际上是相同的,IIRC,因为ANSI语法采用了DB2,然后是M $):http://mysite.verizon.net/Graeme_Birchall/cookbook/DB2V95CK.PDF