SimpleDBを使ってみました

記事タイトルとURLをコピーする

はじめまして。開発部の小田切と申します。

今回、Amazon SimpleDBを使う機会がありましたので、簡単ですが使い方のレポートを書いていきたいと思います。

そういえば、先月にAmazon DynamoDBが発表され、本日(3月1日)からTokyoリージョンでも使えるようになりました。そちらも非常に気になります。

DynamoDBもSimpleDBと同じくNoSQLデータベースです。容量は無制限で、データはSSDに保存されるためパフォーマンスも高そうです。

せっかくDynamoDBがTokyoリージョンで使えるようになったのですが、今回はSimpleDBを使ってみましょう。

目次

  1. SimpleDBの用語
  2. まずは使ってみる
  3. SimpleDBの制約
  4. クライアントツール
  5. まとめ

1.SimpleDBの用語

SimpleDBを使うにあたり、まず出てくる用語は以下の3つです。

ドメイン

RDBでいうところのテーブルと考えてもらって問題ありません。

アイテム

RDBでのレコードに当たるものです。アイテムはアイテム名にて、ドメイン内で一意になります。(つまりアイテム名が主キーですね。)

アイテムには、後述するアトリビュート(属性)を持ちます。

アトリビュート(属性)

アトリビュートは、キーと値をペアにしてデータを格納します。一つのキーに対して複数の値を持たせることも可能です。

なお、SimpleDBにはRDBでのスキーマの様な概念はなく、ドメインはAWSアカウントに対して紐付くようになります。

2.まずは使ってみる

SimpleDBも、他のAWSのサービスと同じく、すぐに使い始めることが出来ます。

しかも、無料枠もあります。(詳しくはAWSのページで確認ください。)

用語について説明しましたが、使ってもらった方が早いと思います。とにかく使ってみましょう。

まずは、AWSのSimpleDBのページにアクセスします。

Amazon SimpleDBの概要のページが表示されます。画面右あたりに「今すぐ申し込む」とありますので、そちらをクリックします。

「今すぐ申し込む」をクリックしますと、AWSのサインイン画面が表示されますので、AWSにサインインします。

サインインしますと、「アカウントの管理」画面が表示され、サインアップしたサービスが一覧表示されます。

上記画面のように、「あなたがサインアップしたサービス」に「Amazon SimpleDB」が表示されていれば、SimpleDBが使用できます。

では早速、使っていこうと思いますが、SimpleDBにはManagement Consoleは無く、APIからの利用となります。

今回はPHPを使用しますのでPHP用 AWS SDKを利用してSimpleDBへアクセスします。

(PHP用 AWS SDKはこちらにありますので、ダウンロードしておきます。)

APIを使う事前準備 「アクセスキーID、シークレットアクセスキーの設定」

まず、AWS SDKの中にある「config-sample.inc.php」をコピーして「config.inc.php」ファイルを作成します。

次に、コピーした「config.inc.php」にアクセスキーとシークレットアクセスキーを設定します。

57行目にアクセスキーを、61行目にシークレットアクセスキーを設定します。

'key' => 'development-key',
'secret' => 'development-secret',

これで準備は完了です。

ここから実際にSimpleDBへデータを入れていきます。

APIの使い方

// sdk.class.phpを読み込み、AmazonSimpleDBのインスタンスを作成します。
require_once 'sdk.class.php';
$sdb = new AmazonSDB();

// 東京リージョンへ接続します。
$sdb->set_region('sdb.ap-northeast-1.amazonaws.com');

ドメインの作成

$result = $sdb->createDomain('team');

引数で指定した名前でドメインが作成されます。

ドメインリストの取得

$result = $sdb->ListDomains();
if ($result->isOK()) {
    foreach ($result->body->ListDomainsResult->DomainName as $domainName) {
        echo $domainName.PHP_EOL;
    }
} else {
    echo "ドメインリストの取得に失敗しました。";
}

ListDomains()を実行しますと、先ほどドメインの作成で作成した"team"ドメインが取得できます。

ここでは、単純にドメイン名を表示しています。

ドメインの削除

$result = $sdb->delete_domain('team');

引数で指定したドメインを削除します。

ドメインにアイテムを登録する。

// 格納するアトリビュート
$team1 = array(
    'name' => 'TEAM 001',
    'description' => '説明とか',
);
$result = $sdb->put_attributes('team', 'team001', $team1);

作成した"team"ドメインへアイテム名を"team001"で登録を行います。

アイテムの属性は、"name"と"description"で登録を行っています。

なお、put_attributes()メソッドは1アイテムずつ登録を行いますが、batch_put_attributes()メソッドというものも存在し、こちらは1度に25個のアイテムを登録することができます。

大量データの登録にはこちらの方が早いということなので、ちょっと検証してみましたので参考にしてください。

約5,000アイテム、アイテム毎の属性は20個でのデータの取込。SimpleDBと同じリージョンに立ち上げたEC2インスタンス(micro)から実行。 batch_put_attributes()での取り込み・・・処理時間:約58秒 put_attributes()での取り込み・・・処理時間:約856秒

ドメインのアイテムを削除する。

$result = $sdb->delete_attributes('team', 'team001');

ドメインに登録されているアイテムを削除します。

ここでは、先ほど登録したアイテム名が"team001"のアイテムを"team"ドメインから削除しています。

アイテムを取得する

SimpleDBのドメインからアイテムを取得する方法は、2つあります。

get_attributes()メソッドを使用してアイテムの取得を行います。

データ取得を行うドメイン、アイテム名を指定してデータ取得を行います。

取得したいアイテムのアイテム名が分かっている場合にはこちらを使います。

$items = $sdb->get_attributes('team', 'team001');
if ($items->isOK()) {
    foreach ($items->body->GetAttributesResult->Attribute as $attribute) {
        $name = (string)$attribute->Name;
        $value = (string)$attribute->Value;
        echo "$name=$value".PHP_EOL;
    }
} else {
    echo "アイテムの取得に失敗しました。".PHP_EOL;
}

SQLを使用してアイテムの取得を行う。

SQLのSELECT文にてデータの取得を行うことも可能です。

複数のアイテムの取得を行う場合や、複雑な条件でアイテムの取得を行いたい場合は、こちらを使います。

$result = $sdk->select('SELECT * FROM team ');
if ($result->isOK()) {
    foreach ($result->body->SelectResult->Item as $item) {
        foreach ($item->Attribute as $attribute) {
            $name = (string)$attribute->Name;
            $value = (string)$attribute->Value;
            echo $name.'='.$value.PHP_EOL;
        }
    }
} else {
    echo 'アイテムの取得に失敗しました。'.PHP_EOL;
}

ソート時の注意

ORDER BY句を指定することで、ソート順の指定をすることも可能です。

ただし、ORDER BYで指定できる項目は1つで、且つWHERE句で条件に指定されていなければなりません。

例えば、下のSQLの場合、1つ目は正常に結果が返されますが、2つ目のSQLはORDER句で指定しているnameをWHERE句の条件として指定していないため、エラーとなります。

OK:SELECT * FROM team WHERE name IS NOT NULL ORDER BY name DESC
NG:SELECT * FROM team WHERE description IS NOT NULL ORDER BY name DESC

このような場合には、以下のように条件を追加します。

SELECT * FROM team WHERE description IS NOT NULL AND name IS NOT NULL ORDER BY name DESC

3.SimpleDBの制約

一通り、APIを使用してデータの投入、取得を行ってみましたが、SimpleDBにはいくつか制約が存在します。

今回は、その中でも開発する中で特に気になったものをあげていきます。

制約1.アイテム名、アトリビュート名、値のサイズの上限:1024バイト

アイテム名、アトリビュート名は特に問題になることは無いと思います。

ただ、値の上限が1024バイトというのはちょっと問題です。ではどうするかというと、いくつか回避方法が用意されています。

回避方法1.S3へデータを格納し、パス情報をSimpleDBのアトリビュートとして保存する。

S3のAPIを利用しなければなりませんが、サイズをまったく気にしなくてよくなります。画像とかサイズが大きい場合はこの方法がよいかもしれません。

回避方法2.アトリビュートに複数の値を持たせる

アトリビュートには複数の値を持たせることができます。そしてそれぞれの値の上限が1024バイトなので、分けることが可能なデータであればこの方法でもよいかもしれません。

$team2 = array(
    'name' => 'TEAM 002',
    'description' => '適当なデータ',
    'temp' => array(
        '属性値1',
        '属性値2',
    )
);
$result = $sdb->put_attributes('team', 'team002', $team2);

ただし、この方法の場合、値を取得したときに順序が保証されません。

なので、値1、値2の順でデータが欲しくても、get_attributesで取得したときには値2、値1の順になってしまうことがあります。

回避方法3.アトリビュートを複数に分ける

アトリビュート自体を複数に分けてしまいます。

$team2 = array(
    'name' => 'TEAM 002',
    'description' => '適当なデータ',
    'temp1' => '属性値1',
    'temp2' => '属性値2',
);
$result = $sdb->put_attributes('team', 'team002', $team2);

SimpleDBでは、テーブル定義がないため、アイテム毎にアトリビュートを持たせることが可能です。

なので、1アイテムでのアトリビュートの上限を超えない限りはこの方法でも問題ありません。

制約2.クエリ結果として返されるアイテム数の上限:100個(LIMIT句で2,500まで増やすことが可能)or 1MB

SELECTを実行した際に、どちらかの制限にかかると、すべての結果を一度に取得することが出来なくなります。

これは普通にSELECTを実行すると、割とすぐに制限にかかります。

この制限が適用された場合、SELECTのレスポンスにNextTokenが含まれるようになりますので、NextTokenを見ながら処理を行うようにすれば、すべての結果を取得することが可能になります。

NextTokenの実際の使い方は以下のようになります。

$next = null;
do
{
    $attrs = ($next == null) ? null : array('NextToken' => $next);
    $result = $this->_sdk->select($sql, $attrs);
    if ($result->isOK()) {
        // NextTokenを取得、データに続きがある場合にはtokenが入っているため、再度SELECTを行う。
        $next = (String) $result->body->SelectResult->NextToken;
        foreach ($result->body->SelectResult->Itemas $item) {
            // 処理
        }
    }
}
// NextTokenがNullになるまでは、データを取得する。
while ($next != null);

これで、すべての結果を取得することが可能になります。

4.クライアントツール

APIでデータの参照は行えるのですが、開発をしているとやはり何かクライアントツールがないかなと思ってしまいます。

そこで、検索してみるといくつか出てくるのですが、自分はMacを使っているのと、開発でEclipseを使っているので、「AWS Toolkit for Eclipse」を使ってみました。

インストール方法

今回使用するEclipseのバージョンは3.6(Helios)です。

AWS Toolkit for EclipseのAmazon SimpleDB Managementを使用するには「Eclipse Data Tools Platform 1.7 以上」が必要になります。入っていなければ、先にインストールしておきます。

AWS Toolkit for EclipseのインストールはEclipseのから行います。

メニューの「ヘルプ」から「新しいソフトウェアをインストール」を選択します。

プラグインの追加画面が表示されます。「追加」を選択し、AWS Toolkit for Eclipseの情報を入力します。

名前は適当に分かりやすい名前で、ロケーションに「http://aws.amazon.com/eclipse」と入力し、「OK」をクリックします。

リストに「AWS Toolkit for Eclipse」が表示されますので、チェックし「次へ」をクリックします。

あとは、Eclipseの指示に従いインストールを行います。

インストールが完了しましたら、Eclipseを再起動します。

再起動後にメニューの「ウィンドウ」から「パースペクティブを開く」を選択すると「AWS Management」というパースペクティブが追加されていますので、このパースペクティブを開きます。

AWS Toolkit使い方

まずは、AWSアカウントの設定を行います。

AWS Managementパースペクティブの左上当たりにあるをクリックし、表示されたリストの中から「設定」を選択します。

開いた画面にて、「アカウントの追加」をクリックし「アカウント名」「Access Key ID」「Secret Access Key」を入力し、「OK」をクリックします。(ここで使用する「Access Key ID」「Secret Access Key」はAPIで使用したキーと同じものを指定します。)

これで、アカウントの設定は完了です。

次にリージョンの選択を行います。

おそらくデフォルトは「US East」あたりになっていると思います。今回APIではTokyoリージョンを指定してドメインの作成等行っていますので、リージョンの変更を行います。

リージョンの選択には、「AWS Explorer」の右上にある国旗アイコン「」の下三角をクリックします。すると、選択できるリージョンがリスト表示されますので、使用するリージョンを選択します。今回は「Asia Pacific (Tokyo)」を選択します。

これで、APIで作成したSimpleDBのデータを見ることができます。

「AWS Explorer」にて、Amazon SimpleDBを展開しますと、ドメインの一覧が表示されると思います。

「AWS Explorer」からはドメインの作成、ドメインの削除、SELECTの実行が可能です。

データの確認以外にも、SQLの構文チェック等にも使うことができます。

5.まとめ

一通り使ってみて、最初はドメインなどの用語に違和感を感じましたが、仕組みは簡単ですのですぐに問題なく使うことができました。

ただ、実際に開発を進めていくと、データのインポート/エクスポート機能はほしいなぁと感じました。

今はAPIとして存在していないため、他のAPIを利用して自分で作らなければなりません。

(まあ、それでも簡単に作れるのですが。)

現在はまだベータ版ですので、上記インポート/エクスポート機能を含め今後、いろいろな機能が実装されていくことを期待しています。