如何使用DynamoDB PHP从表中获取最新的时间戳值
我是DynamoDB的新手.
在我的应用程序中,每个注册用户的帐户都有一些传感器,这些传感器每隔5分钟就会向我们的数据库发送一些数据. 现在我要显示“如果用户已登录他的帐户,我应该为每个传感器显示所有传感器的最新时间戳值”. 我做了三个查询,例如“我在他的帐户下获取了所有设备 – >原始传感器ID – >每个传感器最新值”,因此这个过程需要很长时间才能执行. 我的表看起来像这样: 用户: --------------------- |sno | userId | --------------------- | 1 | naveenkumar | |-------------------- | 2 | abc | |-------------------- | 3 | xyz | |-------------------- sensor_devices: --------------------- | id | sensorId | --------------------- | 1 | sensor1 | |-------------------- | 2 | sensor2 | |-------------------- | 3 | sensor3 | |-------------------- | 4 | sensor4 | --------------------- | 5 | sensor5 | --------------------- 和 用户传感器: ---------------------- | userId | sensorId | ---------------------- | 1 | 1 | |--------------------- | 1 | 2 | |--------------------- | 1 | 4 | |--------------------- | 2 | 5 | |--------------------- data_tbl: --------------------------------------------- | sensorId | value | timestamp | --------------------------------------------- | sensor1 | 4.3 | 2014-01-21 11:21:00| |-------------------------------------------- | sensor2 | 5.0 | 2014-01-21 11:22:00| |-------------------------------------------- | sensor3 | 10.0 | 2014-01-21 11:19:00| |-------------------------------------------- | sensor4 | 6.3 | 2014-01-21 11:25:00| |-------------------------------------------- | sensor1 | 8.3 | 2014-01-21 11:26:00| |-------------------------------------------- | sensor2 | 6.0 | 2014-01-21 11:27:00| |-------------------------------------------- | sensor3 | 9.0 | 2014-01-21 11:24:00| |-------------------------------------------- | sensor4 | 6.3 | 2014-01-21 11:30:00| |-------------------------------------------- 和最终输出表将在他的主页上看到用户: --------------------------------------------- | sensorId | value | timestamp | --------------------------------------------- | sensor1 | 8.3 | 2014-01-21 11:26:00| |-------------------------------------------- | sensor2 | 6.0 | 2014-01-21 11:27:00| |-------------------------------------------- | sensor4 | 6.3 | 2014-01-21 11:30:00| |-------------------------------------------- 我的查询看起来像这样,并且需要很长时间才能执行,所以请为我提供更好的解决方案: 我们假设$_SESSION [‘login_id’] = 1; <?php $aws = Aws::factory('config.php'); $client = $aws->get("dynamodb"); $tableName = "data_tbl"; echo "<table border=1>"; echo "<tr>"; echo "<th>Sensor ID</th>"; echo "<th>value</th>"; echo "<th>Timestamp</th>"; echo "</tr>"; //Query to get user devices $devices = $client->query(array( "TableName" => "users-sensors","KeyConditions" => array( "userId" => array( "ComparisonOperator" => ComparisonOperator::EQ,"AttributeValueList" => array( array(Type::STRING => $_SESSION['login_id']) ) ) ) )); foreach ($devices['Items'] AS $key=>$value) { $id = $value['sensorId']['S']; //Query to get original sensorId from sensor serial number $device = $client->query(array( "TableName" => "sensor_devices","KeyConditions" => array( "id" => array( "ComparisonOperator" => ComparisonOperator::EQ,"AttributeValueList" => array( array(Type::STRING => $id) ) ) ) )); $dids = $device['Items'][0]['sensorId'][Type::STRING]; //Query to get all latest values of sensors $response = $client->query(array( "TableName" => $tableName,"KeyConditions" => array( "sensorId" => array( "ComparisonOperator" => ComparisonOperator::EQ,"AttributeValueList" => array( array(Type::STRING => $dids) ) ) ),"Select" => "SPECIFIC_ATTRIBUTES","AttributesToGet" => array("sensorId","value","timestamp"),"ScanIndexForward" => false,"Limit" => 1 )); foreach ($response['Items'] AS $key=>$value) { echo "<tr>"; $link = "graph.php?id=".$id; echo "<td><a href='$link'>".$value['sensorId']['S']."</a></td>"; echo "<td><a href='$link'>".$value['value']['S']."</a></td>"; $epoch = $value['timestamp']['S']; $timestamp = date('Y-m-d H:i:s',$epoch); echo "<td><a href='$link'>".$timestamp."</a></td>"; echo "</tr>"; } } echo "</table>"; ?> 如果我能得到答案,我会完成我的工作. 解决方法
您从关系数据库的角度来看待和思考DynamoDB. DynamoDB不是关系数据库.您(通常)不希望像在MySQL中那样在DynamoDB中建模您的数据.就像软件开发/计算机科学中的任何事情一样,这是一种权衡.您需要支付一些数据反规范化和重复成本,以换取极低的查询延迟和极高的可扩展性.
我不使用PHP,所以我无法帮助您使用代码,但我认为我可以帮助您完成数据模型设计. 如果我正确理解您的要求,则需要在用户登录时获取每个用户的传感器ID列表及其最新时间戳.如果是这样,这里有一种可能的方法可以将查询从3减少到1: 您的表的哈希键是UserID,范围键是传感器事件的时间戳: ------------------------ | Hash Key | Range Key | ------------------------ | User ID | Timestamp | ------------------------ 该表将具有传感器ID的属性,该属性对应于哪个传感器观察到该事件.传感器29在2014年2月14日上午11:51观察到的用户12的条目可能如下所示: --------------------------------------- | Hash Key | Range Key | Sensor ID | ---------------------------------------- | 12 | 1392396884000 | 29 | ---------------------------------------- 请注意,我使用时间戳(以毫秒为单位),以便DynamoDB可以轻松地对其进行排序. 现在,当用户登录时,您可以按用户ID查询表以获取该用户的每个事件.在您的查询请求中,设置ScanIndexForward => false(来自DynamoDBSDK文档:http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.DynamoDb.DynamoDbClient.html#_query). DynamoDB将按照从最近到最近的顺序返回您的结果.如果该用户有大量事件,DynamoDB将相应地分页结果集,但您可以在DynamoDB文档中看到如何处理该事件. 现在,您拥有该用户的事件列表(或PHP中的相应数据结构).您需要按SensorID进行过滤才能获得最新信息.好消息是,由于结果是有序的,您可以遍历结果并检查每个项目的传感器ID;如果您没有该传感器ID的结果,请将其添加到已过滤的集合中.如果您已经从该传感器ID添加了一个事件,则表示您拥有该用户ID的传感器ID中的最新事件,您应该跳过它. 根据应用程序的需要,如果需要获取传感器的每个事件的列表,您可以使用传感器ID的索引哈希键和事件Timestamp简单地在表上放置全局二级索引.由于用户ID是表的主键的一部分,因此DynamoDB会自动将其投影到索引中. 希望有所帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |