首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据提取功能

数据提取功能
EN

Code Review用户
提问于 2013-11-18 03:24:47
回答 2查看 134关注 0票数 4

第一个函数sqlPull()连接到本地MySQL数据库,每5秒从数据库中提取最后20行。输入的数据是元组的列表,其中MACRSSITimeStamp是每个元组中的3个元素。数据以可变的速度进入数据库,有时我会有大量的条目,有时我会有很少的条目。输入的数据包括一个MAC地址、一个RSSI和一个TimeStamp,用户的设备每次调用我们的硬件时都是这样。因此,我们将有唯一的MAC地址,将有改变的RSSIsTimeStamps在一段时间内。

因为我永远不知道在第一个函数运行的5秒内会添加多少数据库条目,第二个函数,所以使用dupCatch()来检测和消除重复项。

第三个函数,post(),只是向Google发送了一个POST请求,其中删除了重复的数据。

下面是我想要优化代码的方式:

此过程中的下一步是计算数据库中用户第一项和最后一项之间的时间长度。我们可以假设用户进入和退出之间的最长时间是2小时(在这段时间里,用户可能有10到15页不同的RSSIs和时间戳)。我一直在试图用当前的代码来解决这个问题,但是我所想到的每件事都是如此的难以处理。在我看来,可以重写/优化sqlPull()和/或dupCatch(),以便更好地满足计算进出时间的函数的目的。

您将如何提取以可变和不可预测的速度输入的数据?

代码语言:javascript
复制
import mysql.connector
import datetime
import requests
import time

run = True 

def sqlPull():
    connection = mysql.connector.connect(user='XXXXX', password='XXXXX', host='XXXXX', database='XXXXX')
    cursor = connection.cursor()
    cursor.execute("SELECT TimeStamp, MAC, RSSI FROM wifiscan ORDER BY TimeStamp DESC LIMIT 20;")
    data = cursor.fetchall()
    connection.close()
    time.sleep(5)
    return data

seen = set()
def dupCatch():
    data = sqlPull()
    new_data = []
    for (TimeStamp, MAC, RSSI) in data:
        if (TimeStamp, MAC, RSSI) not in seen:
            seen.add((TimeStamp, MAC, RSSI))
            new_data.append((TimeStamp, MAC, RSSI))  
    print new_data
    return new_data

def post():
    new_data = dupCatch()
    for ((TimeStamp, MAC, RSSI)) in new_data:
        payload = {'v':'1','tid':'XXXXXX','cid': '1','t':'event', 'ec': MAC, 'ea': 'InStore', 'el': RSSI}
        requests.post("http://www.google-analytics.com/collect", data = payload)


while run is True:
    post()
EN

回答 2

Code Review用户

发布于 2013-11-18 20:46:26

你需要利率-限制你收到的记录的数量。你必须自己决定什么是最好的利率,因为这是特定于你的场景的。

高优先级:

  • 将“同步”条目列表保存在数据库中。类似于IsSentToAnalytics列。
  • 处理批处理后,更新刚才选择的数据库记录,同步设置为“是”、“1”或“真”。最简单的方法是逐个更新每个条目,但是有更有效的解决方案。
  • 数据库查询只应从尚未同步的项中选择。这在数据库上会更轻。(即添加谓词and where IsSentToAnalytics <> 1)
  • 您的dupCheck满足上述标志,实际上,每次都要提取未使用的数据,这就说明了为什么需要dupCheck。而且,如果是繁忙的时期,就会丢失数据。如果自上次运行以来,数据库中添加了20多个条目,则可能会发生这种情况。这对于业余项目来说可能不错,但对于生产部署来说则是低劣的。
  • 请将代理项主键添加到数据库中。如果有的话,它可以避免每次执行dupCheck时都必须生成散列。
  • 上面的条目在某种程度上取决于如何生成数据。但是,由于这里有时间戳,我假设每条记录都是唯一的,所以您最好按照建议使用代理键。顺便说一下,代理键将是用作主键的序列。插入的每个条目都得到一个唯一的值。
  • 编辑。从下面的反馈中,您可以说有时会有相同时间戳的重复值。如果是这样的话,那么在最初插入数据库之前,您需要过滤掉它们。创建这些条目的任何作业/服务都需要过滤掉重复项。您可以尝试插入,并捕获DBException,因为它将失败列约束。或者,您可以首先进行选择,如果没有返回结果,则插入,否则丢弃。您将需要编辑您的问题与更多的信息,以便我们给您提供更多的细节。

低优先级:

  • 请将睡眠方法移动到while循环中,而不是在SQL拉中。在返回数据之前不需要睡觉。把睡眠放在它该睡的地方。或者将您的函数更改为PullDataAndSleep。如果您认为函数名很好,那么不要更改它的代码,只需重命名即可。否则,把睡眠放在别处。
  • 重用你的连接。每5秒断开和重新连接到数据库,这是毫无意义的,除非您期望您的数据库连接下降。
  • 将while循环更改为"while“,这就像在说while var == True。你基本上是说如果True == True,那就跑。这是多余的。
  • 以固定的间隔从数据库中提取(您正在使用5s,使用它)。
  • 强制执行返回条目的上限数量(您有20条)
  • 上面的最后两个条目将帮助您对发送到Google的请求数量进行限制。如果你垃圾邮件太快,他们可能会阻止/禁止你的IP。
票数 2
EN

Code Review用户

发布于 2015-07-09 00:17:57

最优查询

我会尽量安排这样的事情,你不必担心重复的记录。

在查询中,只能在当前数据库时间之前至少1秒提取具有时间戳的记录。类似地,您将只在最后一次拉扯期间拉出大于或等于服务器时间的记录。

在系统停止运行并必须重新启动时,您将需要一种跟踪最后/下一个查询时间的方法。确保您的解决方案永远不会查询相同的数据两次或排除任何特定的秒。

出口检测

听起来,您会希望出口检测提供不同类型的响应。我怀疑你是否能重用拉码。

为了提高效率,您可以让数据库在最后几个小时内按MAC分组查询所有记录,给出查找的最大时间、找到的最短时间以及每个MAC所涉及的记录数。

也许可以使用pullRecent和pullSessions之类的东西。

Notes

我同意Zoran的观点,在查询函数中添加延迟是没有意义的。该逻辑可能驻留在while循环中。

出于恢复的目的,您可以使用单个行表来跟踪最高的最后或下一秒的查询。

如果您想要使您的轮询响应变化的使用级别,那么考虑在跟踪表中有一个计数器(或一个独立的基于内存的表),该计数器在添加wifiscan记录期间被更新。每当添加N条记录或M分钟通过时,执行轮询运行。在每个投票事件中休息柜台。

还可以借助跟踪表来管理会话计算工作。但是,我怀疑您将需要一种“扩展”会话的方法,在您已经找到了更早的开始和结束时间之后,这些会话将继续处于活动状态。如果您需要找到连续的不使用时间来查找会话边界,那么我建议的两个小时分组查询是不够的。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/35566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档