Lay*_*yke 8 mysql enumeration nested-sets adjacency-list
我有一张桌子,其中包含世界上所有地理位置的位置及其关系.
以下是显示层次结构的示例.您将看到数据实际存储为全部三个
数据显然也从未改变过.下面是英格兰布莱顿位置的直接祖先的例子,其中有一个13911的寂寞.
表:( geoplanet_places有560万行)
大图:http://tinyurl.com/68q4ndx
然后,我有一个名为的表entities.此表存储我想要映射到地理位置的项目.我存储了一些基本信息,但最重要的是我存储了woeid哪个是外键geoplanet_places.

最终该entities表将包含数千个实体.我想要一种能够返回包含实体的所有节点的完整树的方法.
我计划创建一些东西,以便根据实体的地理位置过滤和搜索实体,并能够发现在该特定节点上可以找到多少个实体.
所以如果我的表中只有一个实体entities,我可能会有这样的东西
`地球(1)
英国(1)
英格兰(1)
东萨塞克斯郡(1)
布莱顿 - 霍夫市(1)
布莱顿(1)`
让我们说我有另一个位于德文郡的实体,那么它会显示如下:
地球(2)
联合王国(2)
英格兰(2)
德文(1)
东萨塞克斯(1)......等
(计数)将说明每个地理位置"内部"有多少实体不需要是活的.我可以忍受每小时生成我的对象并缓存它.
目标是,能够创建一个界面,可能开始只显示有实体的国家.
所以喜欢
Argentina (1021),Chile (291),...,United States (32,103),United Kingdom (12,338)
然后,用户将点击某个位置,例如United Kindom,然后将获得作为英国后代的所有直接子节点,并且其中包含实体.
如果United Kindgdom中有32个县,但最终只有23个当你向下钻取时存储了实体,那么我不想显示其他9.它只是位置.
本网站恰如其分地表明,我希望实现的功能:
http://www.homeaway.com/vacation-rentals/europe/r5

您如何建议我管理这样的数据结构?
我正在使用的东西.
我计划尽可能快地完成钻孔.我想创建一个无缝的AJAX界面进行搜索.
我也有兴趣知道你建议索引哪些列.
通常,层次结构中有三种查询会导致麻烦:
这是一个小表,显示了不同方法的性能MySQL:
Ancestors Descendants Children Maintainability InnoDB
Adjacency list Good Decent Excellent Easy Yes
Nested sets (classic) Poor Excellent Poor/Excellent Very hard Yes
Nested sets (spatial) Excellent Very good Poor/Excellent Very hard No
Materialized path Excellent Very good Poor/Excellent Hard Yes
Run Code Online (Sandbox Code Playgroud)
In children,poor/excellent表示答案取决于您是否将方法与邻接列表混合,即存储parentID在每个记录中.
对于您的任务,您需要所有三个查询:
我会选择物化路径,因为这种层次结构很少发生变化(仅在战争,反抗等情况下).
创建一个名为varchar的列path,对其进行索引并使用如下值填充它:
1:234:6345:45454:
Run Code Online (Sandbox Code Playgroud)
数字是适当父母的主键,顺序正确(1欧洲,234英国等)
您还需要一个表levels来保持数字1到20(或任何您想要的最大嵌套级别).
要选择所有祖先:
SELECT pa.*
FROM places p
JOIN levels l
ON SUBSTRING_INDEX(p.path, ':', l.level) <> p.path
JOIN places pa
ON pa.path = CONCAT(SUBSTRING_INDEX(p.path, ':', l.level), ':')
WHERE p.id = @id_of_place_in_devon
Run Code Online (Sandbox Code Playgroud)
要选择所有孩子和其中的地点数:
SELECT pc.*, COUNT(pp.id)
FROM places p
JOIN places pc
ON pc.parentId = p.id
JOIN places pp
ON pp.path BETWEEN pc.path AND CONCAT(pc.path, ':')
AND pp.id NOT IN
(
SELECT parentId
FROM places
)
WHERE p.id = @id_of_europe
GROUP BY
pc.id
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2297 次 |
| 最近记录: |