现在有一个问题我们通常使用这种技术来维护父子关系,即我们将所有实体存储在一个表中,其中 parent_id 列,并且所有最顶层父项都 0 < / strong>在parent_id列中,这是一个很好的规范化技术,我同意但也有一个缺点,它是缓慢而低效的。这主要是由每个父级的递归引起的,我们必须一次又一次地运行查询来创建一个树
SELECT id FROM `table` WHERE parent_id=something
我已经查看了一些可能尝试使用任何编程语言执行此操作的解决方案,通过一次又一次地运行查询,这会在服务器上进行加载,有些提供了存储过程,但也涉及递归。
所以我的问题是我们可以用树的一个数据库查询(连接或子查询)来做吗?
如果不可能那么为什么这种技术如此着名,虽然它有缺陷或我们有另一种解决方案呢?
我添加了sql小提琴,但它只有架构
答案 0 :(得分:3)
我不知道MYSQL是否可行,我在职业生涯中一直主要使用SQL Server。在SQL Server中,可以使用WITH
语句仅使用1个查询来执行此操作。
这演示了如何在所有级别获取对象的所有子级(id = 3)
With pa as (
select pa1.*
From prarent as pa1
Where id = 3
union all
select pa2.*
from pa join prarent as pa2 on pa.id = pa2.parent_id
)
select * from pa where pa.id != 3
另一个让对象的所有父母(id = 7)达到最高
的例子With pa as (
select pa1.*
From prarent as pa1
Where id = 7
union all
select pa2.*
from pa join prarent as pa2 on pa.parent_id = pa2.id
)
select * from pa where pa.id != 7
另一个只获得最顶层父级的例子
With pa as (
select pa1.*
From prarent as pa1
Where id = 7
union all
select pa2.*
from pa join prarent as pa2 on pa.parent_id = pa2.id
)
select top 1 *
from pa
where pa.id != 7
order by id asc
在这个例子中,我假设id是递增的,我使用一种简单的方法(仅用于演示目的)来使用order by
获得最顶层。您可以根据数据库设计使用其他技术。
使用这种类似的技巧,你可以做更多的事情,比如获得最底层的孩子......
答案 1 :(得分:1)
如果您有很多级别或大量数据,这将是不切实际的。
否则,您可以尝试模拟递归函数的功能。即使你没有获得相同的表现,如果你没有太多的数据,也没有太多的水平,这就不重要了。
一般程序如下:
它看起来像这样:(see the Fiddle here)
select *
from prarent P0
where id = 3
union
select *
from prarent P1
where parent_id = 3
union
select *
from prarent P2
where parent_id in
( select distinct id
from prarent P1
where p1.parent_id = 3
)
union
select *
from prarent P3
where parent_id in
( select distinct id
from prarent P2
where parent_id in
( select distinct id
from prarent P1
where p1.parent_id = 3
)
)