我需要分析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/
我想做一些问题,例如:
e.g。对于上面的上一个查询,数据的深度2将返回:
2: /ocp/security/
1: /ocp/
1: /ocp/food/
1: /weyland-yutani/products/
我认为理想的方法可能是使用列DB并对URL进行标记,以便URL中的每个元素都有一列。但是,如果可能的话,我真的想找到一种方法来使用开源应用程序。 HBase是一种可能性,但查询性能似乎太慢而无法用于实时查询(另外,我真的不想进行重新实现SQL的业务)
我知道有这种类型的分析有商业应用程序,但出于各种原因我想自己实现。
答案 0 :(得分:13)
在投入大量时间在关系数据库之上设计分层数据结构之前,请考虑阅读Bill Karwin在优秀演示文稿 SQL Anti-Patterns Strike Back 中的"Naive Trees" section (starting at slide 48)。 Bill概述了以下开发层次结构的方法:
答案 1 :(得分:3)
树在数据库中通常效率不高。我的意思是:如果你设计的树真的是递归的,项目指向他们的父母,你会得到很多查询来找到所有的子节点。
但您可以根据需要优化树。
将网址的任何部分放入列都不是一个坏主意。您需要将深度限制为一定数量的子节点。你可以在任何列上都有索引,这使得它非常快。
对这种结构的查询非常简单:
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
您也可以按原样存储网址并使用正则表达式进行过滤。这更灵活,但速度更慢,因为您没有索引。您只需要限制网址的整个长度,而不是子节点的数量。
我认为你可以用任何足以存储大量数据的数据库来做到这一点。例如MySql。
答案 2 :(得分:2)
Stephane Faroult的书The Art of Sql有一个非常出色的章节(7 - 处理分层数据),它解释和比较了使用关系数据库存储和查询树的3种方法。
如果你正在进行严肃的,工业化的实施,那么研究这一章将花费时间。
答案 3 :(得分:1)
我认为存储此类数据的最有效方法是在零件爆炸(或层次结构)表中。
零件爆炸表由三列组成:标识,父级和描述。对于示例数据,表格如下所示:
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
我相信你可以从这两个表开始回答你的所有问题。
答案 4 :(得分:0)
您可能希望签出SQL Server 2008中的HIERARCHYID数据类型或Oracle中的等效数据类型。