sql - 递归子目录SQL问题

标签 sql model recursion subdirectory

这是一种困扰我一段时间的心理练习。您会使用什么策略来解决此类问题?

让我们考虑以下简单的数据库结构。我们有目录,显然是一棵目录树。此外,我们还有内容项,它们始终驻留在某些目录中。

create table directory ( 
 directoryId integer generated always as identity primary key,
 parentId integer default null,
 directoryName varchar(100)
);

create table content (
 contentId integer generated always as identity primary key,
 directory integer references directory(directoryId),
 contentTitle varchar(100),
 contentText varchar(32000)
);

现在假设我们的目录树很大并且内容量很大。该解决方案必须具有良好的可扩展性。

主要问题:如何高效地检索从指定目录及其子目录中找到的所有内容项?

在我看来,SQL 不能用于轻松获取子选择的所有目录 ID。我对么?

可以通过简单的递归循环在应用程序端解决这个问题。但这实际上可能会变得非常繁重,并且需要棘手的缓存,尤其是为了保证合理的首次访问时间。

也许还可以构建一个具体化查询表并为其动态添加多维索引。可能,但实现困惑。太复杂了。

我最喜欢的解决方案可能是添加一个新表,例如

create table subdirectories (
 directoryId integer,
 subdirectoryId integer,
 constraint thekey primary key (directoryId,subdirectoryId)
)

并确保在移动/删除/创建目录时我总是手动更新它。因此,我始终可以使用 DirectoryId 进行选择并获取子目录的所有 Id,包括作为更复杂查询的子选择。我还喜欢 RDBMS 能够很好地优化查询这一事实。

大家觉得怎么样?

最佳答案

SQL Server 2005PostgreSQL 8.4Oracle 11g 中:

WITH    
        -- uncomment the next line in PostgreSQL
        -- RECURSIVE
        q AS
        (
        SELECT  directoryId
        FROM    directories
        WHERE   directoryId = 1
        UNION ALL
        SELECT  d.directoryId 
        FROM    q
        JOIN    directories
        WHERE   parentId = q.directoryId
        )
SELECT  c.*
FROM    q
JOIN    content c
ON      c.directory = q.directoryId

11g 之前的 Oracle 中:

SELECT  c.*
FROM    (
        SELECT  directoryId
        FROM    directories
        START WITH
                directoryId = 1
        CONNECT BY
                parent = PRIOR directoryID
        ) q
JOIN    content c
ON      c.directory = q.directoryId

对于 PostgreSQL 8.3 及以下版本,请参阅本文:

对于MySQL,请参阅这篇文章:

关于sql - 递归子目录SQL问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2352469/

相关文章:

c++ - 选择的回溯值

sql - NHibernate 应用程序中的相同 SQL 查询比 SQL Studio 慢?

php - 在 PDO 中使用 SHOW COLUMNS 和 LIKE 子句

php - 使用php在mysql中创建名称输入的数据表

ruby-on-rails - Rails/在 View 中使用模型

使用 CGridView、Yii 在 BELONGS_TO 模型列中搜索

c - 双尾递归需要解释

php - PDO-MySQL : Boolean values get converted to 1 or empty string on prepared statement binding

python - Django 仅序列化一个字段而不是相关字段中的整个模型(只读)

powershell - 无法从 Python 项目中递归删除 pyc 文件