如何有效地修剪数据

时间:2012-08-09 23:17:05

标签: c# sql-server database sql-server-2008

我目前正在处理一个工作问题,我需要根据用户定义的限制获取数据并修剪生成的方案。我尝试了很多东西,但似乎无法像我想的那样有效地运行。我可能不得不在DB之外运行,所以我可以扩展运行,但我想如果可能的话我应该尝试在DB内部执行。例如,如果我有3个实体:

Transportation Type:
Car
Boat
Plane

Color:
Blue
Green
Red
Purple
White

Accessories:
Trailer
Wheels
Propeller
Parachute

用户可以输入限制:

Transportation_Type=Boat, Accessories= Wheels

因此,任何有船和车轮的场景的组合都会受到限制。

Example Valid Scenario with restriction: Boat/Red/Trailer

所以这变得复杂的是,你可以想象如果我为3个实体构建所有可能的场景,即使用户定义的限制也是如此。但是,如果有22个实体(实体基本上是具有值的级别),该怎么办?你可以想象这可能会变得很大并且难以应用限制。特别是当它是一组水平/值(如船和车轮)构成限制时。

有人有任何想法吗?

通过构建动态类似的语句,我可以通过大约14到16级来让它真正具有高性能,我可以检查派生的场景。但在那之后,处理时间会爆炸(如果级别中有更多的值,它可以在较低的级别)。

2 个答案:

答案 0 :(得分:1)

您的问题看起来像是“物料清单”问题(BOM)。 每种可能的有效场景都可以表示为分层系统。

            Transportation
                   |
                  Type
                   |
               Accessories
                   |
      Trailer Wheels Propeller Parachute

阅读您的问题,Color不是约束,因此不需要将其集成到约束树中。

SQL Server 2008提供了一种非常紧凑且快速的类型来编码这些层次结构: HierarchyId类型

使用带有HierarchyId的查找表,您可以轻松定义约束,回答场景有效性问题并提取相应的场景结果。

可以在MSDN Magazine, september 2008上读取使用HierarchyId进行BOM解析的一个很好的示例

答案 1 :(得分:1)

如果我不正确,我们的目标是生成符合特定条件的方案。场景将由属性组合生成。

假设每个实体都在一个单独的表中,您可以将查询作为:

select *
from TransportationType tt cross join
     Color c cross join
     Accessories a
where tt.val in (<accepted transportation types>) and
      c.val in (<accepted colors>) and
      a.val in (<accepted accessories>)

如果我的理解是正确的,随着实体数量的增加,这将产生许多场景。如果您有一个允许的场景表(实体组合),那么这将有助于过滤掉事物。

我已经为每个实体显示了单独的表,但您可以用子查询替换它们:

from (select *
      from table t
      where t.type = 'TransportationType'
     ) TransportationType cross join
     ...
相关问题