2010-07-02 68 views
1

我有一个数据库中的两个表,一个列表包和一个列出了相关:查找软件包的依赖

packages 

id | name 
--------- 
0 | xorg 
1 | gnome-session 
2 | gnome-panel 
3 | gnome-mixer-applet 
4 | gnome-media 

depends 

package | depends 
----------------- 
     1 | 0 
     2 | 1 
     3 | 2 
     4 | 2 

很显然,如果我想找出一个包要看,我可以这样做:

SELECT * 
    FROM packages 
INNER JOIN depends 
    ON packages.id = depends.package 
WHERE packages.id = @somenumber 

问题是,这只给了我一个级别的依赖(4取决于2,但它也取决于包1和0)。有没有办法在没有在循环中运行类似的SELECT的情况下获得所有的依赖关系?我宁愿它在SQLite中工作,但如果需要的话,我会使用一个不同的数据库(只要它在Linux上是免费的和可用的)。

回答

1

PostgreSQL是唯一支持recursive queries的开源RDBMS。例如,你可以运行这个命令:

WITH RECURSIVE package_deps(id) AS (
    SELECT d.package FROM depends d WHERE d.package = @startingnumber 
    UNION ALL 
    SELECT d.package FROM depends d JOIN package_deps pd ON d.depends = pd.id 
) 
SELECT p.* FROM package_deps pd JOIN packages p USING (id); 

SQLite的对递归查询的支持,但也有更简单的SQL管理分层数据的其他几种解决方案。请参阅我的演示文稿Models for Hierarchical Data with SQL and PHP

+0

非常有趣。我将不得不尝试你的演示文稿中的一些模式。 – 2010-07-02 19:06:52

+0

我还在我的新书* SQL Antipatterns *中介绍了树型数据和许多其他主题:http://www.pragprog.com/titles/bksqla/sql-antipatterns – 2010-07-02 20:03:22