2011-09-09 27 views
0

我需要使用c#.net(3.5)從MsAccess/SQL Server(我面臨類似問題的兩個單獨項目)中檢索數據,最好速度快且代碼可理解/維護/簡單。在MsAccess/SQL Server中確定歸納定義的數據

我有以下列表。對於每一個,(粗體)列也是關鍵(也編入索引)。

  • SKU信息(〜1000 10000條記錄):PNO,說明,交貨期,價格,等等
  • 使用信息(〜20萬點的記錄):OrderNO,PNO,描述,日期,數量,計量單位,等等
  • 互換性(〜100個000記錄):PNO,描述(PNO1,內容描述,等等)

最後表秈稻證明(PNO1,description1)是(PNO,description)的後繼SKU。請注意(PNO1,description1)也可能具有後繼者。

我需要檢索和存儲在內存中:

  1. 所有使用
  2. SKU信息與其中存在的使用(約20000份)
  3. 所有相關互換性記錄的任何部分,其中提到了某些零件的使用情況或零件,這些零件是使用零件等的後續變體。
  4. SKU信息任何相關的優先部分(大約2000份)

是否有人有這個問題的好維護的解決方案?

最有希望的方法似乎是在數據庫方面確定SKU是相關的。問題是,相關性是歸納定義的。這個怎麼做?

+0

我不能想出一個更好的標題,如果有人有一個建議? – willem

+0

你如何確定零件是首選的變體? –

+0

我在原始問題中使用了首選變體,這是本意是成爲繼任變體的同義詞。我已經編輯了這個問題來清除問題 – willem

回答

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 
+0

我在處理SQL邏輯時遇到了一些麻煩。你會更詳細地解釋一下嗎? – willem

+0

CTE是使用層次結構的好方法,但在MS Access中不可用 –

+0

確實@George,我不確定MS Access的用途,有時它只是用作前端。如果有幫助,我會在SQL中發佈更多評論。 –

0

您可以查看緩存數據。

例如,memcached(http://sourceforge.net/projects/memcacheddotnet/)。

使用常規查詢基本與底層數據同步,然後該數據在內存中始終可用。

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 

因此,也許你需要在你的數據庫中跟蹤的是另一部分成功的部分,而不僅僅是它的直接祖先的根部

如果您能夠更改模式,我會在您的InterchangeAbility表中添加另外兩個字段,該表跟蹤RootPNO,RootDescription(索引在一起)。每當一個部分成功完成另一個部分時,您也需要爲所有祖先記錄該繼承。

然後,您可以從您的使用表直接加入到InterchangeAbility中的字段中,以獲取零件的所有可能成品。

+0

或者,您可以查看Common Table Expressions(CTE),它*我認爲*允許您在SQL Server 2005中執行分層查詢+ http://stackoverflow.com/questions/ 235515/hierarchical-queries-in-sql-server-2005 – mrcrowl

+0

我無法控制數據庫方案 – willem