use*_*531 3 php amazon-web-services amazon-dynamodb
我是DynamoDB的新手.
在我的应用程序中,每个注册用户的帐户都有一些传感器,这些传感器每隔5分钟就会向我们的数据库发送一些数据.
现在我要显示"如果用户已登录他的帐户,我应该为每个传感器显示所有传感器的最新时间戳值".
我用三个查询做了这个,比如"我在他的帐户下获取了所有设备 - >原始传感器ID - >每个传感器的最新值",因此这个过程需要很长时间才能执行.
我的表看起来像这样:
用户:
---------------------
|sno | userId |
---------------------
| 1 | naveenkumar |
|--------------------
| 2 | abc |
|--------------------
| 3 | xyz |
|--------------------
Run Code Online (Sandbox Code Playgroud)
sensor_devices:
---------------------
| id | sensorId |
---------------------
| 1 | sensor1 |
|--------------------
| 2 | sensor2 |
|--------------------
| 3 | sensor3 |
|--------------------
| 4 | sensor4 |
---------------------
| 5 | sensor5 |
---------------------
Run Code Online (Sandbox Code Playgroud)
和
用户传感器:
----------------------
| userId | sensorId |
----------------------
| 1 | 1 |
|---------------------
| 1 | 2 |
|---------------------
| 1 | 4 |
|---------------------
| 2 | 5 |
|---------------------
Run Code Online (Sandbox Code Playgroud)
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|
|--------------------------------------------
Run Code Online (Sandbox Code Playgroud)
和最终输出表将在他的主页上看到用户:
---------------------------------------------
| 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|
|--------------------------------------------
Run Code Online (Sandbox Code Playgroud)
我的查询看起来像这样,并且需要很长时间才能执行,所以请为我提供更好的解决方案:
我们假设$ _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>";
?>
Run Code Online (Sandbox Code Playgroud)
如果我能得到答案,我会完成我的工作.谢谢
您从关系数据库的角度来看待和思考DynamoDB.DynamoDB 不是关系数据库.您(通常)不希望像在MySQL中那样在DynamoDB中建模您的数据.就像软件开发/计算机科学中的任何事情一样,这是一种权衡.您需要支付一些数据反规范化和重复成本,以换取极低的查询延迟和极高的可扩展性.
我不使用PHP,所以我无法帮助您使用代码,但我认为我可以帮助您完成数据模型设计.
如果我正确理解您的要求,则需要在用户登录时获取每个用户的传感器ID列表及其最新时间戳.如果是这样,这里有一种可能的方法可以将查询从3减少到1:
您的表的哈希键是UserID,并且范围键是Timestamp传感器事件的:
------------------------
| Hash Key | Range Key |
------------------------
| User ID | Timestamp |
------------------------
Run Code Online (Sandbox Code Playgroud)
该表将具有Sensor ID对应于哪个传感器观察到该事件的属性.12传感器29在2014年2月14日上午11:51 观察到的条目可能如下所示:
---------------------------------------
| Hash Key | Range Key | Sensor ID |
----------------------------------------
| 12 | 1392396884000 | 29 |
----------------------------------------
Run Code Online (Sandbox Code Playgroud)
请注意,我使用时间戳(以毫秒为单位),以便DynamoDB可以轻松地对其进行排序.
现在,当用户登录时,您可以查询表User ID以获取该用户的每个事件.在您的查询请求中,设置ScanIndexForward => false(来自此处的DynamoDBSDK文档:http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.DynamoDb.DynamoDbClient.html#_query ).DynamoDB将按照从最近到最近的顺序返回您的结果.如果该用户有大量事件,DynamoDB将相应地分页结果集,但您可以在DynamoDB文档中看到如何处理该事件.
现在,您拥有该用户的事件列表(或PHP中的相应数据结构).您需要过滤SensorID以获取最新信息.好消息是,由于结果是有序的,您可以遍历结果并检查Sensor ID每个项目; 如果您没有结果Sensor ID,请将其添加到过滤的集合中.如果你已经添加媒体链接从一个事件Sensor ID,这意味着你必须从最近发生的事件Sensor ID为User ID,你应该跳过它.
根据应用程序的需要,如果需要获取传感器的每个事件的列表,您可以使用索引哈希键Sensor ID和事件简单地在表上放置全局二级索引Timestamp.由于它User ID是表的主键的一部分,因此DynamoDB会自动将其投影到索引中.
希望有所帮助.
| 归档时间: |
|
| 查看次数: |
2258 次 |
| 最近记录: |