MySQL嵌套集地理树

时间:2012-05-26 23:22:49

标签: mysql nested-sets

晚上,

我有一个嵌套的集合表,其中包含大约14,000个位置:

placeId        name        type        lft        rgt
1              England     Cty         1          22878
2              Bedfords.   Co          2          259
3              Ampthill    AP          3          4

我有三个国家(Cty),88个县(Co),每个县都有儿童安置(AP,EP,Ch和Unk)。 type列有效地告诉你深度。

Cty = 0

Co = 1

AP,EP,Ch或Unk = 2

但是,稍后我将添加更多具有不同深度的国家,例如:美国:

Cty = 0

St = 1

Co = 2

城镇/城市= 3

我想要的是一个查询,它会将所有兄弟节点和所有子节点拉出来,深度为1,具体取决于网站上正在查看的位置。

所以,如果我正在观看英格兰,我想得到:

England
**Bedfordshire
**Berkshire
**Buckinghamshire
***More Counties*
Scotland
Wales

如果选择贝德福德郡,我想得到:

England
**Bedfordshire
****Ampthill
****Arlesey
****Aspley Guise
*****More Towns*
**Berkshire
**Buckinghamshire
***More Counties*
Scotland
Wales

虽然我开始构建的查询花了30多秒而没有做我想做的所有事情,所以没有必要再继续了。

我可以通过在大约100毫秒内运行每个深度的查询来获得我想要的结果,但是如果可能的话,我更喜欢单个查询和最少的PHP使用。

有什么想法吗?

提前致谢。

这是我能想到的最好的:

(
SELECT parent.name, parent.lft, parent.rgt,
(
CASE
WHEN parent.type = 'Co' THEN 1
WHEN parent.type IN( 'AP', 'EP', 'Ch','Unk' ) THEN 2
END
) AS depth
FROM places AS node, places AS parent
WHERE ( parent.lft BETWEEN node.lft AND node.rgt AND ( node.placeId IN( 1, 7553) ) AND ( parent.lft BETWEEN node.lft AND node.rgt ) )
ORDER BY parent.name
)
UNION
(
SELECT name, lft, rgt, 0 AS depth FROM places WHERE type = 'Cty'
)
ORDER BY lft

唯一的问题是我无法按字母顺序排除,同时保持lft-rgt顺序。现在这些表格已按字母顺序排列,但当我添加其他地点时,表格会发生变化。

1 个答案:

答案 0 :(得分:1)

我认为嵌套集不可能。这还不够信息。也许你可以通过空间索引或四叉树获得更好的运气。如果您有一个四核,并且想要查询来自英格兰的所有县,您可以从左到右搜索四核中的所有缩放级别。因此,您只需查询2个缩放级别即可查询2个深度。但通常你会从分支机构获得所有级别。我不确定您是否可以对结果词典排序进行排序,但使用空间索引可以向索引添加4个方向。这是一个关于colision检测和四叉树的博客:lab.polygonal.de/?p=202。