2012-05-03 78 views
4

我對存儲依賴關係的數據庫技術有疑問。我知道他們中有很多人,但我不能輕易將他們放在我需要的方案中。 我已經創建了簡單的圖片:技巧依賴關係的Mysql技術

Skills example

正如你可以看到我需要的是創造的技能樹(如遊戲),它依賴於對方。所以例如,如果有人去,想要有技能8我可以告訴他,他需要先掌握技能1,2和5.

這可能適用於數據庫中的僱傭數據,但我無法弄清楚是如何動態地做這個模型的。我遇到的問題是,這些技能會一直添加到樹中所有可能的位置。沒完沒了。可以在任何級別添加技能。

現在,在第一個問題之後,還有一個更復雜的問題。我需要技能也有水平。舉例來說,技能1可以有10個等級。並且只有在達到技能1級5後才能達到技能2.

對於玩類似「魔獸世界」的遊戲的玩家應該是可以理解的。

還有一點需要注意,技能可以隨時添加,但添加後無法更改。在正常的基礎上。以防萬一某些技能會非常糟糕或者類似的情況,那麼它將被刪除,但這種情況很少發生。

感謝您的建議,鏈接或任何其他材料!

+0

如果沒有某種形式的存儲處理循環和遞歸地嘗試添加所有合格的過程,它不能在單個查詢a中完成你已經注意到,你永遠不知道數據會進入多少層次。 – DRapp

+0

它不必在單個查詢中完成,我只需要一些技巧如何實現這個 – Tom

+0

MySQL是一個需求?這對於支持CTE和窗口功能的數據庫來說很簡單http://stackoverflow.com/a/10395130 http://stackoverflow.com/a/10401572實時測試:http://www.sqlfiddle.com/#!1/db290/85 –

回答

1

玩這個,我挑戰不足以解決問題,但我沒有足夠的挑戰,解決它在MySQL。考慮到這一點,這裏是你的問題的PostgreSQL的版本:

with recursive 
skill_list(skill_id) as 
(
    select distinct skill_id from skill_req 
    where req is not null 
    union 
    select distinct req from skill_req 
    where req is not null 
) 
,skill_tree(skill_group, depend_on) as 
(
    select skill_id, skill_id -- seeds 
    from skill_list   
    union  
    select st.skill_group, sr.req 
    from skill_req sr 
    join skill_tree st 
    on sr.skill_id = st.depend_on 
) 
,skills_required as 
(
    select skill_group, depend_on 
    from skill_tree 
    where skill_group <> depend_on -- remove seeds 
) 
select 
    sl.skill_id, 
    array_agg(sr.depend_on order by depend_on) as array_version, 
    array_to_string(array_agg(sr.depend_on order by depend_on), ',') 
     as group_concat_version  
from skill_list sl 
left join skills_required sr on sr.skill_group = sl.skill_id 
group by sl.skill_id 

數據:

CREATE TABLE skill_req 
    (skill_id int, req int); 

INSERT INTO skill_req 
    (skill_id, req) 
VALUES 
    (2, 1), 

    (4, 3), 

    (5, 1), 

    (6, 4), 
    (6, 2), 

    (7, 6), 
    (7, 9), 

    (8, 2), 
    (8, 5), 

    (9, 3), 

    (10, 4), 
    (10, 5), 
    (10, 9); 

輸出:

skill_id | array_version | group_concat_version 
----------+---------------+---------------------- 
     1 | {NULL}  | 
     2 | {1}   | 1 
     3 | {NULL}  | 
     4 | {3}   | 3 
     5 | {1}   | 1 
     6 | {1,2,3,4}  | 1,2,3,4 
     7 | {1,2,3,4,6,9} | 1,2,3,4,6,9 
     8 | {1,2,5}  | 1,2,5 
     9 | {3}   | 3 
     10 | {1,3,4,5,9} | 1,3,4,5,9 
(10 rows) 

現場測試:http://www.sqlfiddle.com/#!1/77894/1

+0

撇開疑問,其中相關性是有爭議的,特別是它不會在MySQL上工作。設計就在那裏,那怎麼可能無關緊要? :-)如果我要創建一個技能圖,那將是我的數據庫設計,只有兩個領域,以保持簡單的概念模型。與技能有關的其他輔助信息將保存在單獨的表格中。 –

1

正如你所看到的,我需要的是建立一個技能樹(如在 遊戲),它依賴於對方。

我需要的技能也有水平。因此,例如技能1可以 有10個級別。

這意味着您將需要一個表來存儲的技巧和技能的最高水平,基本上是:

create table skills(
    skill_id integer, 
    skill_name varchar(500) not null, 
    skill_max_level integer not null, 
    primary key(skill_id)); 

而且你將需要設置的關係是不具有需要選購的級別:

create table skills_depend 
(skill_id integer 
, skill_depend integer 
, level_depend integer 
, primary key(skill_id, skill_depend) 
, foreign key (skill_id) 
    references skills (skill_id) 
, foreign key (skill_depend) 
    references skills (skill_id)); 

該查詢將取決於你想要檢查的內容(例如,如果用戶有先決條件來徵求技能)。

將此與用戶級別和他已有的技能相結合,我認爲這是一個起點。

還有一點需要注意,技能可以隨時添加,但添加後不能更改 。在正常的基礎上。以防萬一某些技能會非常糟糕或者類似的情況,那麼它將被刪除,但是 會發生很少。

這個需求你需要控制你的應用程序級別(讓用戶只添加或刪除技能)。


您可以在SQLFiddle

+0

你可以告訴我示例查詢來獲得像我在圖片上的技能樹嗎?讓我們說技巧7,謝謝 – Tom

+0

http://sqlfiddle.com/#!2/7c30b/13是我做的,但如何獲得完整的樹? – Tom

+0

那麼,MySQL不支持遞歸查詢。你將需要使用PHP來做到這一點。 –