技能依赖的Mysql技术

时间:2012-05-03 01:45:42

标签: php mysql database

我对存储依赖项的数据库技术有疑问。我知道其中有很多,但我不能轻易将它们放在我需要的方案中。 我创建了简单的图像:

Skills example

正如你所知,我需要的是创造一种技能树(如游戏中),它们相互依赖。因此,例如,如果某人去并希望拥有技能8,我可以告诉他,他需要首先掌握技能1,2和5.

这对于数据库中的雇佣数据可能没问题,但我无法弄清楚的是如何动态地执行此模型。我遇到的问题是,技能将一直添加到树中所有可能的位置。没完没了。可以在任何级别添加技能。

现在在第一个问题之后还有一个问题。我需要技能才能达到水平。因此,例如技能1可以具有10个级别。只有达到技能1等级5后才能达到技能2。

对于像魔兽世界这样玩游戏的人应该是可以理解的。

还有一个注意事项,可以随时添加技能,但添加后无法更改。在正常的基础上。为了防止某些技能非常糟糕或类似的东西,它会被删除,但这种情况很少发生。

感谢您提供建议,链接或任何其他材料!

2 个答案:

答案 0 :(得分: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

上玩这个

答案 1 :(得分:1)

我有足够的挑战来解决这个问题,但我没有足够的挑战来解决它。考虑到这一点,这是您的问题的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