今回は、それらのテーブルにSDKをつかってアクセスしてみます。
ここでは、PHP SDKを使用してみます。
クラスの初期化
DynamoDBクラスの初期化は以下のように行います。
キーなどのパラメータは認証用のファイルに記載しておき省略することも可能です。
$ddb = new AmazonDynamoDB( array( 'key' => 'xxxxxxxxxxxxxxx', 'secret' => 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyy', 'default_cache_config' => '/tmp/cache'));
データの投入
次に、前回作成した2つのテーブルにそれぞれデータを投入してみます。
値の指定は、DynamoDBの型名とstring値を紐付けた形で投入するようです。
//book $books = array( array('1', '978-4274066306', 'Joel on Software'), array('2', '978-0321413093', 'Implementation Patterns'), array('3', '978-1244865723', 'Agile Software Development'), ); for($i=0; $i<count($books); $i++){ $ddb->put_item(array( 'TableName' => 'book', 'Item' => array( 'id' => array(AmazonDynamoDB::TYPE_NUMBER => (string)$books[$i][0]), 'isbn' => array(AmazonDynamoDB::TYPE_STRING => (string)$books[$i][1]), 'name' => array(AmazonDynamoDB::TYPE_STRING => (string)$books[$i][2]), ) )); } //comment $comments = array( array('1', strtotime('-10 days'), 'memorycraft', 'i like this'), array('1', strtotime('-7 days'), 'hoge', 'i never like this'), array('2', strtotime('-9 days'), 'moge', 'this is awesome'), ); for($i=0; $i<count($comments); $i++){ $ddb->put_item(array( 'TableName' => 'comment', 'Item' => array( 'book_id' => array(AmazonDynamoDB::TYPE_NUMBER => (string)$comments[$i][0]), 'posted_at' => array(AmazonDynamoDB::TYPE_NUMBER => (string)$comments[$i][1]), 'username' => array(AmazonDynamoDB::TYPE_STRING => (string)$comments[$i][2]), 'message' => array(AmazonDynamoDB::TYPE_STRING => (string)$comments[$i][3]), ) )); }
データアクセス
続いて、先程データを投入したテーブルに対して、値の取得を行なってみます。
Hashのプライマリキーで一意に取得できる場合は、下記のようにget_itemで行います。
//Hashプライマリキーで完全一致 echo 'get_item (1) ' . print_r( $ddb->get_item( array( 'TableName' => 'book', 'Key' => array('HashKeyElement' => array(AmazonDynamoDB::TYPE_NUMBER => '1') ) )->body->Item->to_json(), true ) . "\n";出力は以下のようになります。
get_item (1) {"id":{"N":"1"},"isbn":{"S":"978-4274066306"},"name":{"S":"Joel on Software"}}
複合プライマリキーを使い、Hashキーを指定し、Rangeキーで絞るような場合は、queryを使用します。
//複合キーで検索 echo 'query ' . print_r( $ddb->query( array('TableName' => 'comment', 'HashKeyValue' => array(AmazonDynamoDB::TYPE_NUMBER => '1'), 'ConsistentRead' => true, 'RangeKeyCondition' => array( 'ComparisonOperator' => AmazonDynamoDB::CONDITION_GREATER_THAN_OR_EQUAL, 'AttributeValueList' => array(array(AmazonDynamoDB::TYPE_NUMBER => (string)strtotime('-8 days'))) ) ) )->body->Items->to_json(), true ) . "\n";出力は以下のようになります。
query {"0":{"book_id":{"N":"1"},"message":{"S":"i never like this"},"posted_at":{"N":"1326880572"},"username":{"S":"hoge"}}}
また、キー値以外で検索を行う場合は、scan関数を利用します。
//キー以外で検索 echo 'scan ' . print_r( $ddb->scan( array( 'TableName' => 'comment', 'AttributeToGet' => array('username', 'message'), 'ScanFilter' => array( 'username' => array( 'ComparisonOperator' => AmazonDynamoDB::CONDITION_EQUAL, 'AttributeValueList' => array( array(AmazonDynamoDB::TYPE_STRING => 'memorycraft') ) ) ) ) )->body->Items->to_json(), true ) . "\n";出力は以下のとおりです。
scan {"0":{"book_id":{"N":"1"},"message":{"S":"i like this"},"posted_at":{"N":"1326621372"},"username":{"S":"memorycraft"}}}
テーブルの作成
ちなみにテーブルの作成は以下のように行います。
//book $ddb->create_table(array( 'TableName' => 'book', 'KeySchema' => array( 'HashKeyElement' => array( 'AttributeName' => 'id', 'AttributeType' => AmazonDynamoDB::TYPE_NUMBER ) ), 'ProvisionedThroughput' => array( 'ReadCapacityUnits' => 50, 'WriteCapacityUnits' => 10 ) )); //comment $ddb->create_table(array( 'TableName' => 'comment', 'KeySchema' => array( 'HashKeyElement' => array( 'AttributeName' => 'book_id', 'AttributeType' => AmazonDynamoDB::TYPE_NUMBER ), 'RangeKeyElement' => array( 'AttributeName' => 'posted_at', 'AttributeType' => AmazonDynamoDB::TYPE_NUMBER ) ), 'ProvisionedThroughput' => array( 'ReadCapacityUnits' => 50, 'WriteCapacityUnits' => 10 ) ));
この際、テーブルの作成には時間が多少かかるので、テーブルを作成したあとに続けてデータ追加処理など行う場合は、以下のように待機します。
foreach(array('book', 'comment') as $table_name){ $count = 0; echo $table_name . " : status "; do { sleep(1); $count++; $res = $ddb->describe_table(array( 'TableName' => $table_name )); $status = (string)$res->body->Table->TableStatus; echo ($status === 'ACTIVE' ? $status . "\n" : '.'); } while ((string) $res->body->Table->TableStatus !== 'ACTIVE'); }出力は以下のようになります。
book : status ...........................ACTIVE comment : status ACTIVE
テーブルの削除
テーブルの削除は以下のように行います。
foreach(array('book', 'comment') as $table_name){ $ddb->delete_table( array('TableName' => $table_name) ); }
RDBとは違うので、データの構成などに工夫が必要ですが、RDBとの使い分けで非常に高い効果を発揮すると思います。
東京リージョンへの展開が待ち遠しいですが、US-Eastに立てたインスタンスからはRTTがないので、ハイパフォーマンスを体験できます。
以上です。