PHP
AWS
DynamoDB

PHPで学ぶAmazon DynamoDB

More than 3 years have passed since last update.


はじめに

前回はAmazon DynamoDBの基本概念について書きましたが、今回はPHPのSDKからのDynamoDB操作についてまとめました。

前提条件

aws.pharがインストール済み

作業イメージ

今回のフォルダ構成は以下3ファイルのこんな感じの想定です。

┏dynamo.php

┣aws.phar

┗config.php

config.phpでProfile情報を設定して、dynamo.phpで各種DynamoDB操作を行うイメージです。


configファイルを作る

ここにAWS SDKを使う為に必要な情報を記載していきます。

今回はconfig.phpとしてファイルを作成しました。


config.php


return array(
'includes' => array('_aws'),
'services' => array(
'default_settings' => array(
'params' => array(
'key' => 'AWSのキー',
'secret' => 'AWSのシークレットキー',
'region' => 'リージョンを指定'
)
)
)
);



インポートと初期化処理


dynamo.php

<?php

require_once('aws.phar');

use Aws\Common\Aws;
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;

//作成済みのconfig.phpを使って$clientの生成
$aws = Aws::factory('config.php');
$client = $aws->get('dynamodb');



getItem


dynamo.php


//ConsistentReadの指定(読込の整合性)
$get_item_array['ConsistentRead'] = true;

//テーブル指定
$get_item_array['TableName'] = 'test';

//キーはidでString型の'test_id'の条件で検索
$get_item_array['Key']['id'] = array('S'=>'test_id');

//生成した$clientを使ってgetitem処理実行
$result = s$client->getItem($get_item_array);



Tips


・ConsistentReadについて

$get_item_array['ConsistentRead'] = true;

上記コードでは読み取りの整合性を設定しています。

指定しなければデフォルトのfalse (結果整合性)がセットされています。

この機能はgetItem以外ではQueryでも提供されています。


意味
メリット
デメリット

true
強い整合性での読み取り
必ず最新の結果を含めて結果を返す
厳密な結果を返すためレスポンスが遅れる場合がある

false
結果整合性での読み取り
レスポンスが強い整合性より速い
最新の結果は反映されない場合がある

個人的な所感ですが、通常のサイト内検索、例えばユーザーが投稿したコンテンツの情報の検索結果などは多くの場合厳密な整合性結果は求められないはずなので結果整合性(false)で行い、ユーザー登録情報や課金に関する情報など、重複出来なかったり、リアルタイムでの確実な検索が必要な場合は強い整合性(true)を使う感じかなと思います。


・データ型について

//キーはidでString型の'test_id'の条件で検索

$get_item_array['Key']['id'] = array('S'=>'test_id');

上記コードでは検索条件のidに対して「String型ですよ!」と明示しています。

'S'の部分が Stringと明示している箇所です。

このようにDynamoDBのAPIの作法ではデータ操作時にデータ型を明示する必要があります。

前回簡単にデータ型について記載しましたが、今回はAPIから利用する場合のデータ型の指定方法について一覧にしました。

データ型一覧


データ型
説明

S
String
文字列

N
Number
数値

B
Binary
バイナリ

SS
String Set
文字列セット

NS
Number Set
数値セット

BS
Binary Set
バイナリセット

L
List
JSON Arrayのように、順番が保たれた値のコレクションを保持

M
Map
JSON Objectのように、順序付けのないName-Valueペアを保持

Bool
Boolean
true / false

NULL
Null
UnknownあるいはUndefinedな値の状態を表す

2つのデータ型の指定方法

データ型の指定方法には2種類が存在します。

①直接アルファベットを記載する方法

②awsのsdkを使用する方法

①についてはサンプルスクリプトの通りなので、②について説明します。

ファイルの先頭で

use Aws\DynamoDb\Enum\Type;

を行い、以下のように記載すると'S'を指定した事と同様になります。

Type::STRING

他にもNumberならば

Type::NUMBER

とすれば'N'の設定と同意になります。

詳細は公式リファレンスを確認してください。


query


dynamo.php


//テーブル指定
$get_query_array['TableName'] = 'test3';

//ScanIndexForwardは昇順・降順の指定
$get_query_array['ScanIndexForward'] = true;

//Index名の指定(設定があれば)
$get_query_array['IndexName'] = "local-index";

//キーがidで値がString型でtest1のデータを取得
$get_query_array['KeyConditions']['id']["ComparisonOperator"]='EQ';
$get_query_array['KeyConditions']['id']["AttributeValueList"]=array(array('S'=>'test1'));

//キーがlocalで値がString型でlocal1のデータを取得
$get_query_array['KeyConditions']['local']["ComparisonOperator"]='EQ';
$get_query_array['KeyConditions']['local']["AttributeValueList"]=array(array('S' => "local1"));

//query実行
$result = $client->query($get_query_array);



Tips


・ScanIndexForwardについて

$get_query_array['ScanIndexForward'] = true;

上記コードではデータの昇順・降順を指定します。

ScanIndexForward = true (昇順)

ScanIndexForward = false (降順)


・ComparisonOperatorについて

//キーがidで値がString型でtest1のデータを取得

$get_query_array['KeyConditions']['id']["ComparisonOperator"]='EQ';

上記コードではComparisonOperatorを'EQ'に設定することによって取得条件がイコールのデータを取得する事を意味しています。

ComparisonOperatorは直訳すると「比較演算子」です。

つまりここに「イコール」「以下」「以上」などの値をセットする事によって取得条件を変更する事が可能です。

ComparisonOperatorの設定値一覧


意味

EQ
イコール

LE
以下

LT
未満

GE
以上

GT
より大きい

BEGINS_WITH
○○で始まる

BETWEEN
値1と値2の間

BETWEENを使う際の注意点

BETWEENを使う場合、データ型が必ず一致する必要があります。

OK例

('N' => '1')と('N' => '2')でBETWEEN使用

はNumber型での検索なのでOK

NG例

('S' => '1')と('N' => '2')でBETWEEN使用

はString型の1とNumber型の2を検索しようとしているのでNG


・QueryとScanの違いについて

Queryとほぼ同等の検索機能としてScan機能も提供されていますが、今回はQueryのみサンプルを作成しました。理由としては公式ページに以下のような記述があるようにQueryのほうが検索性能が優れているからです。


一般的に、Query オペレーションは Scan オペレーションよりも効率的です。


Queryの長所


  • Scanでは通常の結果整合性しか利用出来ませんが、Queryの場合は強い結果整合性を利用する事が可能です。


  • Scanでは常にテーブル全体がスキャンされるが、Queryではキー条件のセットを持たずに特定の範囲のキーだけが検索されます。


あえてのScanの長所

Queryではプライマリキーの属性値だけが検索されるのに対してScanではテーブル内のすべての項目を検索する事が可能です。

プライマリキー以外で検索をかけるのであればScanは有効な手段ですが、テーブル全体スキャンの弊害として、検索負荷が大きい点があり、結果としてテーブルが大きくなるに従ってScanでの検索性能が低くなります。

個人的な所感

公式ページに詳細の記載がありますが、あらかじめ設計していればQueryの使用だけで良い気がします。


putItem


dynamo.php


//テーブル指定
$put_item_array['TableName'] = 'test2';

//stringキーに String型でtestをセット
$put_item_array['Item']['string'] = array('S' => 'test');

//numキーに Number型で1をセット
$put_item_array['Item']['num'] = array('N' => '1');

//putItem実行
$result = $client->putItem($put_item_array);



updateItem


dynamo.php


//テーブル指定
$update_item_array['TableName'] = 'test';

//キーであるidがString型で'test'のデータがupdate対象
$update_item_array['Key']['id'] = array('S' => 'test');

//ActionはPUTで指定
$update_item_array['AttributeUpdates']['value1']['Action'] = 'PUT';

//updateするデータはvalue1にString型でupdateを指定
$update_item_array['AttributeUpdates']['value1']['Value'] = array('S' => 'update');

//updateItem実行
$result = $client->updateItem($update_item_array);



Tips


・Actionについて

//ActionはPUTで指定

$update_item_array['AttributeUpdates']['value1']['Action'] = 'PUT';

上記コードでは更新の種類をPUTとして指定しています。

PUT以外にも以下のような種類があるので一覧にまとめました。


意味

PUT
属性と値を追加。既に属性があれば新しい値に置換

ADD
属性と値を追加

DELETE
削除


おわりに

今後も気づいた点、修正すべき点あればこの記事はアップデートしていこうと思います。