Database design 存储和查询树的最有效方法是什么?
我需要分析1 TB+的web访问日志,特别是我需要分析与请求的URL和URL子集(子分支)相关的统计数据。如果可能的话,我希望查询能够在数据的小子集上快速进行(例如,1000万个请求) 例如,给定一个访问日志,其中请求了以下URL:Database design 存储和查询树的最有效方法是什么?,database-design,Database Design,我需要分析1 TB+的web访问日志,特别是我需要分析与请求的URL和URL子集(子分支)相关的统计数据。如果可能的话,我希望查询能够在数据的小子集上快速进行(例如,1000万个请求) 例如,给定一个访问日志,其中请求了以下URL: /ocp/about_us.html /ocp/security/ed-209/patches/urgent.html /ocp/security/rc/ /ocp/food/ /weyland-yutani/products/ 我想进行如下查询: 计算所有“低
/ocp/about_us.html
/ocp/security/ed-209/patches/urgent.html
/ocp/security/rc/
/ocp/food/
/weyland-yutani/products/
我想进行如下查询:
- 计算所有“低于”的请求数/ocp李>
- 同上,但仅统计/ocp/security下的子节点请求
- 返回请求频率最高的前5个URL
- 同上,除按任意深度分组外
2: /ocp/security/
1: /ocp/
1: /ocp/food/
1: /weyland-yutani/products/
我认为理想的方法可能是使用列DB并标记URL,这样URL中的每个元素都有一列。然而,如果可能的话,我真的很想找到一种用开源应用程序实现这一点的方法。HBase是一种可能性,但查询性能似乎太慢,无法用于实时查询(另外,我也不想从事重新实现SQL的业务)
我知道有商业应用程序可以进行这种类型的分析,但出于各种原因,我希望自己实现它。您可能希望在SQL Server 2008中签出HIERARCHYID数据类型,或在Oracle中签出其等效数据类型。在投入太多时间在关系数据库之上设计分层数据结构之前,考虑在Bill Karwin演示的优秀反SQL反模式中阅读。比尔概述了以下开发层次结构的方法:
树在数据库中通常不是很有效。我的意思是:如果你把树设计成真正的递归树,让项目指向它们的父节点,你会得到很多查询来查找所有的子节点 但是您可以根据需要优化树 将url的任何部分放入列中都不是一个坏主意。您需要将深度限制为一定数量的子节点。任何列上都可以有索引,这使得它非常快 对这种结构的查询非常简单:
Select count(*) From Hits where node1 = 'ocp' AND node2 = 'security';
进行访问统计:
SELECT node1, node2, count(*) as "number of hits"
FROM hits
GROUP BY node1, node2
ORDER BY count(*) DESC
你会得到
node1 node2 number of hits
'ocp' 23345
'ocp' 'security' 1020
'ocp' 'food' 234
'weyland-yutani' 'products' 22
您还可以按原样存储url,并使用正则表达式进行筛选。这更灵活,但速度较慢,因为您没有索引。您只需要限制url的整个长度,而不需要限制子节点的数量
我认为你可以用任何足够好的数据库来存储大量数据。例如MySql。斯蒂芬·法鲁特的书中有一个非常优秀的章节(第7章-处理分层数据),其中解释并比较了使用关系数据库存储和查询树的3种方法
如果您正在执行一个严肃的、具有行业实力的实施,那么学习本章将是一个很好的时间。我认为存储此类数据的最有效方法是在零件分解(或层次结构)表中 零件分解表由三列组成:标识、父级和描述。对于示例数据,该表如下所示:
Identity Parent Description
0 Null ocp
1 0 about_us.html
2 0 security
3 2 ed-209
4 3 patches
5 4 urgent.html
6 2 rc
7 0 food
8 Null weyland-yutani
9 8 products
在填充URL(爆炸)表时,填充一个记录每个URL叶的表。根据示例数据:
Leaf ID
-------
1
5
6
7
9
我相信您可以从这两个表开始回答所有问题。要将树存储到数据库中,您可能需要研究嵌套集模型。因此,基本上,如果您不介意有一个额外的表-
Closure table
是迄今为止最好的解决方案。这似乎是一本很棒的书,但从我看到的情况来看,完全忽略了闭包表
模式。