如何处理结构化的海量数据集?

时间:2014-07-10 20:35:47

标签: python mysql r bigdata

我的问题是我通常没有那么大的数据。方法我已经成功地使用了一些小数据集阻塞这个数据集,也许我的ram还不够。我需要处理MYSQL中的大型数据集。下表包含大到10GB的数据。我需要对它做一些具体的分析。

我有两个表,table1如下,id是主键,table2_id是外键

id date                 aid table2_id message
1  2014-03-19 16:21:02  121   1       login from xxxx
2  2014-03-20 14:00:32  123   2       decrease budget
3  2014-03-20 18:00:32  121   2       increase budget
4  2014-03-21 16:21:02  121   3       login from xxxx
5  2014-03-21 16:21:02  121   3       login from xxxx
6  2014-03-22 10:21:02  121   2       increase budget

table2是一个类型表

id type
1  login
2  change_budget
3  search

我需要分析活动change_budget和其他活动之间的关系。到目前为止,我已经尝试过了:

我尝试在每次一次援助change_budget时编写SQL,在此前的24小时内计算此辅助工具的所有其他操作。如果一个援助在2014-03-14 16:21:02有一个change_budget,我需要从2014-03-13 16:21:02到2014-03-14 16:21:02对此援助执行的所有操作。然后,按动作分组并计算我想要的结果应该如下所示。

aid login search change_budget
121 1     0      1
123 0     0      -1
121 0     2      1 

-1表示change_budget减少,1表示增加。 其他数字是在援助改变发生之前的一天内,这种援助的行动发生了多少次。

我的问题是我通常没有那么大的数据。如果我以与小数据相同的方式处理它,我的ram还不够。所以我需要一个大数据解决方案。有什么建议吗?

注意:我已编辑此问题以尝试更好地解释此问题,但仍需要原始作者进行审核以验证其是否正确说明问题

3 个答案:

答案 0 :(得分:1)

好的,所以关于这个问题的一些事情只是没有意义......但是你给我的工作就是我的工作。

第一次:你想要的结果是完全错误的......你说你想要它发生的那一天,但发布一个完全不同的理想结果。我出去了,并假设你想要它,因为这是被要求所以,记住这就是你想要的。

+-------------+---------+-----------+-----------+-----------+
|day occurred | aid     | logins    | searches  | budget    |
+-------------+---------+-----------+-----------+-----------+
|'2014-03-19' | 121     |   1       |   0       |   0       |
|'2014-03-20' | 123     |   0       |   0       |   -1      |
|'2014-03-20' | 121     |   0       |   0       |   1       |
|'2014-03-21' | 121     |   0       |   2       |   0       |
|'2014-03-22' | 121     |   0       |   0       |   1       |
+-------------+---------+-----------+-----------+-----------+

这来自您提供的数据......而且每个AID每天都会发生这种情况。

<强> SECOND: 考虑到这一点,您可以通过几种方式实现此查询。其中最好的是制作临时表来进行设置,然后进行简单的查询。

<强> SETUP:

CREATE TABLE logs
    (`id` int, `date` datetime, `aid` int, `t2_id` int, `message` varchar(55))
;

INSERT INTO logs
    (`id`, `date`, `aid`, `t2_id`, `message`)
VALUES
(1,  '2014-03-19 16:21:02',  121,   1,       'login from xxxx'),
(2,  '2014-03-20 14:00:32',  123,   2,       'decrease budget'),
(3,  '2014-03-20 18:00:32',  121,   2,       'increase budget'),
(4,  '2014-03-21 16:21:02',  121,   3,       'login from xxxx'),
(5,  '2014-03-21 16:21:02',  121,   3,       'login from xxxx'),
(6,  '2014-03-22 10:21:02',  121,   2,       'increase budget')
;


CREATE TABLE log_type
    (`id` int, `type` varchar(55))
;

INSERT INTO log_type
    (`id`, `type`)
VALUES
(1,  'login'),
(2,  'change_budget'),
(3,  'search');

我调用了表logslog_type,因为这里似乎正在发生这种情况。表是记录交互。

TEMPORARY TABLES:

CREATE TEMPORARY TABLE t1
(
    SELECT
        l.aid,
        DATE(date) AS grouping_col,
        IF(
            lt.type = 'change_budget', 
                IF(l.message LIKE '%decrease%', -1, 1), 
                0
        ) AS changed_budget
    FROM logs l 
    JOIN log_type lt ON lt.id = l.t2_id
    GROUP BY grouping_col, changed_budget, aid
);

CREATE TEMPORARY TABLE t2
(   SELECT
        DATE(l.date) AS grouping_col,
        l.aid,
        IF(lt.type = 'login', COUNT(l.id), 0) AS logged_in
    FROM logs l 
    JOIN log_type lt ON lt.id = l.t2_id
    GROUP BY grouping_col,  aid
); 

CREATE TEMPORARY TABLE t3
 (
    SELECT
        DATE(l.date) AS grouping_col,
        l.aid,
        IF(lt.type = 'search', COUNT(l.id), 0) AS searched_for
    FROM logs l 
    JOIN log_type lt ON lt.id = l.t2_id
    GROUP BY grouping_col, aid
);

最终查询:

最后您需要做的就是查询这些临时表以获得所需的结果

SELECT 
    t1.grouping_col as day_occurred, 
    t1.aid, 
    logged_in, 
    searched_for, 
    changed_budget 
FROM t1
JOIN t2 on t2.grouping_col = t1.grouping_col AND t2.aid = t1.aid
JOIN t3 on t3.grouping_col = t1.grouping_col AND t3.aid = t1.aid
;

<强>结果:

我在我的localhost数据库上设置它并运行它,结果就是它应该是什么。 IMAGE

答案 1 :(得分:0)

看看dplyr。它明确地允许您使用数据库表,就像它们是数据帧(子集,逻辑操作等)一样,并允许您以SQL式方式一个接一个地构建语句。

答案 2 :(得分:0)

我理解这个问题的方法如下:

  1. 获取数据集的日期/时间字段,提取日期
  2. 根据提取的日期和帮助分组数据
  3. 在案例table2_id = 2
  4. 的情况下,分析文本列以查找“增加/减少”一词
  5. “旋转”结果,因此分组数据在列中而不是在行中
  6. 以下代码应该解决问题的一部分直到第4步(可能包含语法错误,因为我没有mysql arround,并且日期/时间函数在不同的DBMS中是不同的):

    select date("date"), aid, table2_id, count(message)
    from table1
    group by date("date"), aid, table2_id
    

    在MySQL中回显结果似乎在以下帖子中得到了解答: MySQL pivot table

    评论:

    • 10GB并不是很大。要计算此查询,DBMS需要(最有可能)分组(基本上对前三列执行排序,再对数据进行一次扫描以进行实际分组)。实际上假设(在这种情况下)记录占用50个字节,这意味着具有200M记录的表=&gt;分类成本是超过10GB的19次扫描(这将是一个相当悲观的估计),这意味着要扫描和写入190GB的数据。假设我们可以读/写50MB / s,整个查询应该花费3800秒(非常悲观估计)。实际上,我假设大约10GB÷50MB / s = 200秒执行时间

    • 查询似乎是一个相当简单的数据选择/聚合查询。我建议你阅读一本关于SQL的书来了解它。您可能只需要阅读前几十页来了解它

    • 对于这类问题,
    • https://dba.stackexchange.com/似乎是一个更有利的地方。但是,问题的简单性和答案并不是很多人可能会觉得有趣的是回答它:)

      

    我的问题是我通常没有那么大的数据。如果我对待它   和小数据一样,我的ram还不够。所以我需要一个   大数据解决方案。有什么建议吗?

    DBMS是智能系统。他们检查你有多少RAM,并寻找快速的查询解决方案。在您的情况下,如果RAM的数量为MM远低于10GB,则DBMS会将您的数据切换为N<M数据块,在RAM中对这些块进行排序,将其保存到磁盘,然后进行排序合并,从而产生更快的解决方案