gpt4 book ai didi

mysql - 我应该使用哪种分层模型?邻接、嵌套还是枚举?

转载 作者:可可西里 更新时间:2023-11-01 06:32:57 28 4
gpt4 key购买 nike

我有一张表,其中包含世界上所有地理位置及其关系的位置。

这是一个显示层次结构的示例。你会看到数据实际上存储为所有三个

  • 枚举路径
  • 邻接表
  • 嵌套集

数据显然也不会改变。下面是英格兰布莱顿位置的直系祖先示例,其 woeid 为 13911。

表:geoplanet_places(有 560 万行) Ancestors大图:http://tinyurl.com/68q4ndx

然后我有另一个名为 entities 的表。该表存储我想映射到地理位置的项目。我存储了一些基本信息,但最重要的是我存储了 woeid,它是来自 geoplanet_places 的外键。 enter image description here

entities 表最终将包含数千个实体。我想要一种能够返回包含实体的所有节点的完整树的方法。

我计划创建一些东西来促进根据实体的地理位置过滤和搜索实体,并能够发现在该特定节点上可以找到多少实体。

所以如果我的 entities 表中只有一个实体,我可能会有这样的东西

`Earth (1)

United Kingdom (1)

England (1)

East Sussex (1)

Brighton and Hove City (1)

Brighton (1)`

假设我有另一个位于德文郡的实体,那么它会显示如下内容:

Earth (2)

United Kingom (2)

England (2)

Devon (1)

East Sussex (1) ... etc

表示每个地理位置“内部”有多少实体的 (Counts) 不需要是实时的。我可以忍受每小时生成我的对象并缓存它。

目标是能够创建一个界面,该界面可能开始时仅显示具有实体的国家..

很喜欢

阿根廷 (1021)智利 (291)...美国 (32,103) , 英国 (12,338)

然后用户将单击一个位置,例如英国,然后将获得所有直接子节点,这些子节点是英国的后代并且其中有一个实体。

如果英国有 32 个县,但当您向下钻取时最终只有 23 个县存储了实体,那么我不想显示其他 9 个县。它只是位置。

这个站点恰本地展示了我希望实现的功能: http://www.homeaway.com/vacation-rentals/europe/r5 enter image description here

你建议我如何管理这样的数据结构?

我正在使用的东西。

  • PHP
  • MySQL
  • 太阳能

我计划让下钻尽可能快。我想创建一个无缝搜索的 AJAX 界面。

我也很想知道您建议在哪些列上建立索引。

最佳答案

通常,层次结构中存在三种会导致问题的查询:

  1. 返回所有祖先
  2. 返回所有后代
  3. 返回所有 child (直系后代)。

这是一张小表,显示了 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

children 中,poor/excellent 表示答案取决于您是否将方法与邻接表混合使用,即。 e.在每条记录中存储 parentID

对于您的任务,您需要所有三个查询:

  1. 向所有祖先展示地球/英国/德文郡的事情
  2. 所有 child 展示“Destinations in Europe”(元素)
  3. 所有后代显示“欧洲的目的地”(计数)

我会选择物化路径,因为这种等级制度很少改变(仅在 war 、叛乱等情况下)。

创建一个名为 path 的 varchar 列,对其进行索引并用如下值填充它:

1:234:6345:45454:

其中数字是适当 parent 的主键,顺序正确(欧洲为 1,英国为 234 等)

您还需要一个名为 levels 的表来保存从 120(或任何您想要的最大嵌套级别)的数字。

选择所有祖先:

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

要选择所有子项和其中的位置数:

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

关于mysql - 我应该使用哪种分层模型?邻接、嵌套还是枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4831154/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com