查询自上次检查后条目是不是发生变化并持续检查一段时间

Posted

技术标签:

【中文标题】查询自上次检查后条目是不是发生变化并持续检查一段时间【英文标题】:query if a entry has changed since last check and continuously check for a time查询自上次检查后条目是否发生变化并持续检查一段时间 【发布时间】:2013-07-29 17:09:13 【问题描述】:

高级理念: 我有一个可以通过 http 请求连接到我的网站的微控制器...我想在数据库上记录更改后立即向设备提供响应...

由于终端设备是客户端,即微控制器...我不知道无需设置端口转发即可将数据传递给客户端的方法...这是非常不希望的...问题出现了当尝试将数据从外部网络发送到内部网络时... A. 端口转发或 B 让客户端设备启动请求,这使我想到让设备向轮询更改的文件发送 http 请求

更新

非常感谢奥利·琼斯。我已经暗示了他的一些 建议在这里。

Jason McCreary 建议修改一个很大的列 改进,因为它应该提高速度和可靠性......很好 建议! :)

如果在此示例中存在过度工作的数据库问题 也许以下将在哪里工作......当数据插入时 数据库将更改写入文件...然后循环 不断检查该文件是否有更新....想法?

我有table1,我想查看自上次检查以来特定行(基于 UID/键)是否已更新,并且如果记录投注更新,则持续检查 60 秒...

我想我可以使用 INFORMATION_SCHEMA 数据库来做到这一点。

此数据库包含有关表、视图、列等的信息。

尝试解决方案:

    <?php 
$timer = time() + (10);//add 60 seconds
$KEY=$_POST['KEY'];
$done=0;

if(isset($KEY))
//loign stuff
require_once('Connections/check.php');
$mysqli = mysqli_connect($hostname_check, $username_check, $password_check,$database_check);
if (mysqli_connect_errno($mysqli))
 echo "Failed to connect to MySQL: " . mysqli_connect_error(); 
//end login


$query = "SELECT data1, data2
FROM station 
WHERE client = $KEY
AND noted = 0;";

$update=" UPDATE station
SET noted=1
WHERE client = $KEY
AND noted = 0;";

while($done==0) 
   $result = mysqli_query($mysqli, $query);
   $update = mysqli_query($mysqli, $update);

   $row_cnt = mysqli_num_rows($result);

   if ($row_cnt > 0) 
      $row = mysqli_fetch_array($result);
      echo  'data1:'.$row['data1'].'/';
      echo  'data2:'.$row['data2'].'/';
      print $row[0];
      $done=1;
   
   else 
      $current = time();
      if($timer > $current) $done=0; sleep(1);  //so if I haven't had a result update i want to loop back an check again for 60seconds
   else  $done=1; echo 'done:nochange';//60seconds pass end loop


mysqli_close($mysqli);
echo 'time:'.time();

else echo 'error:nokey';
?>

这是提高速度和提高可靠性的适当方法和建议吗

【问题讨论】:

为什么不在表中添加一个 modified 列并检查它? “持续检查”是什么意思? “看一次,然后通过重复检查不断锤击数据库”? @MarcB 是的。这就是我的意思……睡眠(2);我猜不会受伤 @JasonMcCreary 老实说,我不认为这是一种检查是否发生更改的方法,然后在我发布更改后重置修改后的列....嗯,我喜欢它我仍然对如何持续检查数据库感兴趣 你的高层次目标是什么,你可能搞错了。 【参考方案1】:

如果我正确理解您的应用程序,您的客户端就是一个微控制器。它不时向您的 php / mysql Web 应用程序发出 HTTP 请求。该请求的频率取决于微控制器,但似乎是每分钟一次左右。

请求基本上是问,“伙计,有什么新东西要给我吗?”

您的网络应用需要发送答案,“不是现在”或“这就是我所拥有的”。

您应用的另一部分是提供相关信息。它与您的微控制器异步执行此操作(即,只要它愿意)。

使微控制器查询高效是您当前的目标。

(请注意,如果我有任何这些假设错误,请纠正我。)

您的表将需要一个last_update 列、一个which_microcontroller 列或等效列,以及一个notified 列。只是为了笑,让我们也加入value1value2 列。您还没有告诉我们您在表格中保留了哪些类型的数据。

更新表格的软件需要这样做:

 UPDATE theTable 
   SET notified=0, last_update = now(), 
       value1=?data, 
       value2?=data
 WHERE which_microcontroller = ?microid

它可以根据需要随时执行此操作。新数据值替换并覆盖旧数据值。

处理微控制器请求的软件需要执行以下查询序列:

  START TRANSACTION;

 SELECT value1, value2
   FROM theTable 
  WHERE notified = 0
    AND microcontroller_id = ?microid
    FOR UPDATE;

 UPDATE theTable
    SET notified=1
  WHERE microcontroller_id = ?microid;

 COMMIT;

这将从数据库中检索最新的 value1 和 value2 项目(您的应用程序的数据,无论它是什么),如果它自上次查询以来已更新。处理来自微控制器的请求的 php 程序可以响应该数据。

如果 SELECT 语句没有返回任何行,您的 php 代码会以“无更改”响应微控制器。

这一切都假设微控制器 ID 是唯一键。如果不是,您仍然可以执行此操作,但会稍微复杂一些。

请注意,我们在此示例中没有使用 last_update。我们只是使用了通知标志。

如果您想等到上次更新后的 60 秒,可以这样做。也就是说,如果你想等到 value1 和 value2 停止变化,你可以这样做。

  START TRANSACTION;

 SELECT value1, value2
   FROM theTable 
  WHERE notified = 0
    AND last_update <= NOW() - INTERVAL 60 SECOND
    AND microcontroller_id = ?microid
    FOR UPDATE;

 UPDATE theTable
    SET notified=1
  WHERE microcontroller_id = ?microid;

 COMMIT;

要使这些查询高效,您需要此索引:

  (microcontroller_id, notified, last_update)

在此设计中,您不需要让 PHP 代码循环轮询数据库。相反,您在微控制器签入更新时查询数据库/

【讨论】:

您完成了 99%,非常感谢您的回复。那么为什么循环...我希望系统尽可能快...而不是让客户不断发送请求我认为在 php 脚本检查循环中是否有任何更改时,将连接打开 60 秒会更有效和更快。如果没有任何内容,则连接关闭,然后立即发送新请求从客户端。为了在更新记录时减轻数据库的压力,可以更新更改日志文件。循环可以只检查日志文件... 非常感谢您的回复和非常详细的信息! Ollie id 很想听听您对我的评论的回复。 在 Web 服务器软件中进行 sleep() 式调用确实不是一个好主意。如果您只有一个微控制器(或其他客户端),这可能并不重要。但是在 sleep()ing 时保持连接打开会破坏系统的可扩展性。信不信由你,让微控制器稍后进行轮询可能比让它等待更有效。 最好让微控制器每分钟询问 50 次,然后像我建议的那样只询问一次 while 循环?【参考方案2】:

如果所有table1 更改 都由PHP处理,则没有理由轮询数据库。在更新 table1 时在 PHP 级别添加您需要的逻辑。

例如(假设 OOP):

public function update() 
  if ($row->modified > (time() - 60)) 
    // perform code for modified in last 60 seconds
  

  // run mysql queries

【讨论】:

如果插入数据时我将更改写入文件...然后循环不断检查该文件是否有更新... 为什么需要这个文件?您不能在确定更改时执行所需的操作吗? 由于终端设备是客户端,即微控制器...我不知道无需设置端口转发即可将数据传递给客户端的方法...这是非常不受欢迎的。 ..尝试将数据从外部网络发送到内部网络时出现问题...A.端口转发或B让客户端设备发起请求,这使我想到让设备向文件发送http请求轮询更改....

以上是关于查询自上次检查后条目是不是发生变化并持续检查一段时间的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery / Shopify 订单数据查询

当文件存储在列表或对象中时,为什么文件的上次访问时间会发生变化?

检查自上次检查以来是不是有匹配单位的时间

PHP & MySQL:检查表的数据是不是在没有轮询的情况下发生了变化?

使用反应式表单在 Angular 中检查后,表达式发生了变化

检查上次查询中是不是使用了缓冲区