2010-05-10 56 views
0

我在動態創建我們的ActiveMQ系統主題碰到了下面的問題進行無向圖的處理:如何從SQL數據

我有一個數量的進程(,...,M_n),其中n是不大,一般爲5-10。一些進程將通過消息隊列監聽其他進程的輸出;這些邊緣在XML文件中指定,例如,

<link from="M1" to="M3"</link> 
<link from="M2" to="M4"</link> 
<link from="M3" to="M4"</link> 

等邊緣很稀疏,所以不會有很多。我將解析這個XML並將這些信息存儲在一個SQL DB中,一個表用於節點,另一個表用於邊緣。

現在,我需要動態地創建,其中標籤順序生成形式

M1.exe --output_topic=T1 
M2.exe --output_topic=T2 
M3.exe --input_topic=T1 --output_topic=T3 
M4.exe --input_topic=T2 --input_topic=T3 

的字符串。什麼是最好的方式去查詢SQL來獲得這些關係?是否有任何工具或其他教程可以指向我?我從來沒有用SQL來做過任何事情。

使用SQL是必不可少的,因爲我們也將它用於其他的東西。

謝謝!

+0

您確定要按順序命名主題 - 這會不會令人困惑?如果主題名稱沒有意義,我會在發起過程後將其命名。這也會簡化你的查詢。 – mdma 2010-05-11 00:47:48

+0

不,他們可以用任何可能的方式命名。當然,他們需要是獨一無二的。 – recipriversexclusion 2010-05-11 01:11:28

回答

1

好的,這是我的問題。

這裏的節點和邊桌的草圖:

[nodes] 
node : varchar(xx) 

[edges] 
outputNode : varchar(xx) 
inputNode : varchar(xx) 

假設你的數據庫具有支持熱膨脹係數,然後構建這樣的查詢將彙集的關係和串聯的結果:

/* pair output nodes with a topic, assigned sequentially */ 
WITH OutputTopics(node, topicNumber) AS (
    SELECT outputNode, ROW_NUMBER() (ORDER BY outputNode) AS topicNumber 
    FROM 
    (SELECT DISTINCT outputNode FROM edges) AS outputNodes 
), 
/* pair input nodes to the topic of associated output nodes */ 
InputTopicNumbers(inputNode, topicNumber) AS (
    SELECT edges.inputNode, ot.topicNumber FROM edges INNER JOIN 
     OutputTopics AS ot ON ot.node=edges.outputNode 
), 
/* Recursive CTE to concat all topics together */ 
InputTopics(inputNode, topics, topicNumber) AS (
     /* The seed for the recursion - all input nodes */ 
     SELECT inputNode, CAST ('' AS nvarchar(max)), 0 /* max topic handled for node */ 
     FROM InputTopicNumbers 
     GROUP BY inputNode 
    UNION ALL /* Add topics that are greater than those processed */ 
     /* recursively concat topic numbers in ascending order */ 
     SELECT i.inputNode, CONCAT(c.topics, ' --input-topic=T',i.topicNumber), i.topicNumber 
     FROM InputTopics AS c 
     INNER JOIN InputTopicNumbers i ON i.inputNode=c.inputNode 
     WHERE i.topicNumber > c.topicNumber 
), 
/* Bring it all together - append each node with '.exe', 
    list the output topic, if present 
    Use the recursive CTE to concat all inputTopics */ 
NodeCommands(node, exe, input, output) AS (
    SELECT nodes.node, 
     CONCAT(nodes.node,'.exe'), 
     CONCAT(' --output_topic=T',ot.topicNumber), /* NULL if no output node */ 
     it.topics 
    FROM nodes 
    LEFT OUTER JOIN OutputTopics AS ot ON ot.node=nodes.node 
    LEFT OUTER JOIN InputTopics AS it ON it.inputNode=nodes.node 
) 
/* finally our top-level query concatenates the parts to 
    arrive at a single command line */ 
SELECT CONCAT(
    exe, 
    ISNULL(input, ''), 
    ISNULL(output, '')) 
FROM NodeCommands ORDER BY node 

我正在做這個蝙蝠,所以肯定有一些語法錯誤。我希望評論能夠解釋這個意圖。

+0

非常感謝mdma!我是SQL的新手,但一些谷歌搜索顯示,我們正在使用的MySQL不支持CTE(http://stackoverflow.com/questions/1382573/how-do-you-use-the -with子句,在MySQL的)。這種技術很容易被MySQL認爲的其他方法替代嗎?順便說一下,我們使用Hibernate控制MySQL。 – recipriversexclusion 2010-05-11 02:35:19

+0

皮蒂你在開始時沒有提到這些細節。你可能可以在沒有CTE的情況下重寫大部分內容,儘管我不確定你將如何執行遞歸級聯。如果你使用hibernate,更好的方法是讀取hibernate中的節點/邊,並編寫一些java邏輯來產生命令行。 – mdma 2010-05-11 06:58:37