我需要使用c#.net(3.5)从MsAccess / SQL Server(我面临类似问题的两个独立项目)中检索数据,最好是快速的,并且代码可以理解/可维护/简单。
我有以下表格列。对于每个,以粗体列的列是键(也是索引)。
最后一个表格表明(PNO1,description1)是(PNO,描述)的后继SKU。注意,(PNO1,description1)也可以具有后继者。
我需要检索并存储在内存中:
是否有人为此问题提供了良好的可维护解决方案?
最有希望的方法似乎是在数据库方面确定与SKU相关。问题是,相关性是归纳定义的。怎么做?
答案 0 :(得分:1)
举一个例子,你有A部分由B部分继承,部分B由部分C或D继承。然后说,D成功了部分E.这给你:
Part | All Successors A
---------------------- /
A | B, C, D, E B
B | C, D, E / \
C | - C D
D | E \
E | - E
因此,您需要在数据库中跟踪的是另一部分成功的 root 部分,而不仅仅是它的直接祖先。
如果您能够更改架构,我会在InterchangeAbility表中添加另外两个字段,跟踪RootPNO,RootDescription(索引在一起)。每当一个部分成功完成另一个部分时,你也需要记录所有祖先的继承。
然后,您可以从使用表中直接加入InterchangeAbility中的 Root 字段,以获取部件的所有可能的成功。
答案 1 :(得分:0)
您可以查看缓存数据。
例如,memcached(http://sourceforge.net/projects/memcacheddotnet/)。
基本上使用常设查询与您的基础数据同步,然后内存中始终可以使用该数据。
答案 2 :(得分:0)
试图弄清楚如何使用CTE解决找到相关可互换性的问题。很快就失控了。你或许可以从中得到一些东西。假设我的想法并非完全错误,它应该不会太低效,尽管它的大小。
CTE内的每个查询基本上都是您可以从CTE访问的临时视图。 Preferred,Roots和HasUsage位不依赖于任何其他CTE表,因此如果需要,它们实际上甚至可以是视图。
;WITH Preferred AS (
-- Find leaves (Any PNO which replaces a PNO but is never replaced.)
SELECT PNO1 FROM InterchangeAbility l
LEFT JOIN InterchangeAbility r ON l.PNO1 = r.PNO
WHERE r.PNO IS NULL
)
, Roots AS (
-- Find roots (Any PNO which gets replaced, but never replaces anything.)
SELECT PNO FROM InterchangeAbility l
LEFT JOIN InterchangeAbility R ON l.PNO = r.PNO1
WHERE r.PNO1 IS NULL
)
, HasUsage AS (
-- Count number of records in usage for each PNO in usage (including 0)
-- Ideally this step wouldn't be necessary, but a LEFT JOIN isn't allowed in
-- The recursive part of a CTE. There may be a more efficient way around this step.
SELECT SkuInfo.PNO, COUNT(Usage.PNO) AS num_records
FROM SkuInfo
LEFT JOIN Usage ON SkuInfo.PNO = SkuInfo.Usage
GROUP BY SkuInfo.PNO
)
, TreeHasUsage AS (
-- Traverse from root to leaf, used leaves will have nonzero usage
-- This is a recursive query, The usage of each root will be the base case.
SELECT p.PNO AS root, p.PNO AS curr, hu.num_records
FROM Roots p
INNER JOIN HasUsage hu ON p.PNO = hu.PNO
UNION ALL
-- This is the recursive part of the query, it finds the PNO which replaces
-- the root element (and so on) and does a running total of the usage associated
-- with this tree branch. By the time we get to a leaf any relevant preferred PNOs
-- will have a nonzero num_records.
SELECT tu.root, hu.PNO, tu.num_records + hu.num_records
FROM TreeHasUsage tu
INNER JOIN InterchangeAbility i ON tu.curr = i.PNO1
INNER JOIN HasUsage hu ON i.PNO = hu.PNO
)
, RelevantRoots AS (
-- Important tree nodes are the ones which have a non zero
-- num_records on one or more leaves. Select the roots of those trees.
SELECT DISTINCT hu.root FROM Preferred p
INNER JOIN TreeHasUsage hu WHERE p.PNO1 = hu.curr
WHERE hu.num_records > 0
)
-- Select every record in InterchangeAbility which belongs to one of the
-- just determined relevant roots.
SELECT * FROM InterchangeAbility i
INNER JOIN RelevantRoots rr ON i.PNO = rr.root