ラベル simpledb の投稿を表示しています。 すべての投稿を表示
ラベル simpledb の投稿を表示しています。 すべての投稿を表示

2011年8月3日水曜日

Amazon SimpleDBってなんじゃ?(RUBY SDK鈍行編2 railsでsimpledbを使う)

前回とタイトルが微妙につながってませんが、ruby on railsのインストールが終わったので、続いてawsのsdkをつかったrailsアプリケーションを作ってみます。

aws-sdkでは、完全ではないですがrailsのサポートもしており、SimpleDBをrailsのORMとして利用することができます。方法は以下のとおりです。

まず、必要なライブラリを全てインストールします。
# yum -y install ruby-sqlite3
# yum -y install sqlite
# yum -y install sqlite-devel
# yum -y install ncurses-devel
# yum -y install readline-devel
readlineのコンパイルとインストールを行います。
$ cd /usr/local/src/ruby-1.9.2-p290/ext/readline
$ ruby extconf.rb
$ make
# make install

新規にrailsアプリを作成します。(前回と同じものです)
# cd /var/www/html
# rails new myfirstcloud -J -T
# chown memorycraft:memorycraft -R myfirstcloud
$ cd /var/www/html/myfristcloud

bundlerでインストールするgemを定義します。今回sqlite3は使用しませんが、エラー回避のため便宜上入れて起きます。
$ vi Gemfile
...
gem 'aws-sdk'
#gem 'sqlite3'
gem 'sqlite3-ruby', '1.2.5', :require => 'sqlite3'
...

awsのアクセス認証用に証明書情報を定義します。rubyコードでの記述も可能ですが、ここではYAMLで定義します。記法はconfig/database.ymlとほぼ同じです。
$ vi config/aws.yml
development:
  access_key_id: アクセスキー
  secret_access_key: シークレットキー

test:
  <<: *development

production:
  <<: *development


SimpleDBはRDBMSではなくキーバリューストアなので、db:migrateは必要がなく、属性の定義はモデルで行います。aws_sdkのSimpleDBには仮想属性というものがあり、裏側で通常Railsでサポートしているデータ型とSimpleDBの属性が以下のようなメソッドで紐付けられています。
  • string_attr
    stringの属性
  • integer_attr
    integer(整数型)の属性
  • sortable_integer_attr
    値の範囲が決まっているソート可能なintegerの属性

    範囲を:rangeで指定します。
    validates_numericality_ofで最大値と最小値の制約を適用することが一般的で、
    もし範囲外だった場合、実行時エラーを引き起こします。

    通常のintegerとちがうところとして、SimpleDBは数値型をサポートしておらず全ての値は文字列に変換されます。
    そのため、数値でのソートに問題が生じます。たとえば2と10を昇順に並べると文字列比較のため10,2の順になってしまいます。
    このsortable_integerは、この問題に対応するため0詰めして保存されます。
  • float_attr
    float(浮動小数点型)の属性
  • sortable_float_attr
    値の範囲が決まっているソート可能なfloatの属性
    sortable_integerと同じくfloat値を0詰めで保持します。

    【正のfloat】
    たとえばsortable_float_attr :score, :range => (0..10)と指定した場合、
    辞書的にソートされても問題ないように5.5は"05.5"と文字列保存されます。

    【負のfloat】
    たとえば
    sortable_float_attr :position, :range => (-10..10)
      
    のように、範囲が負の値を含んでいいた場合、すべての値を正になるようにマイナス分だけずらして保存されます。
    つまり"000"から"020"として保存されることにより、ソートを可能にしています。

    注意としては、こういった方式で表示したり入力したりした値と、実際に保存される値がことなるので、
    一度運用を開始した後に値の範囲を変更したい場合、保存済みの全ての値を更新してあげる必要があるので要注意です。
  • boolean_attr
    boolean型の属性
    なにも指定しないでnewされたとき、デフォルトはfalseです。
  • datetime_attr
    日時型の属性
    created_atとupdated_atに対して指定された場合、自動管理されます。
  • timestamps
    timestamps
    datetime_attr属性のcreated_atとupdated_atを生成するための便利メソッドです。

ここでは以下のようにモデルを定義します。
$ vi app/models/my_first_domain.rb 
class MyFirstDomain < AWS::Record::Base
  string_attr :title
  integer_attr :num
  sortable_integer_attr :sort_num, :range => 0..99
  boolean_attr :bool_val
  timestamps

  validates_presence_of  :title, :num
end

ドメインがまだ存在していない場合は、rubyコンソールから作成することも可能です。
$ rails console
> MyFirstDomain.create_domain

モデルとドメインの作成が終わったら、それ以外の部分をscaffoldで作成します。
rails generate scaffold_controller MyFirstDomain title:string num:integer sort_num:sortable_integer bool_val:boolean

最後にroutesに追加します。
$ vi config/routes.rb
Myapp::Application.routes.draw do
    # 追加
    resources :my_first_domains
end

それでは確認してみましょう。

httpd.confの設定は前回のとおりであることを確認したら、
ブラウザで
http://IPアドレス/my_first_domains
を見てみましょう。
このとおり、my_first_domainのscaffoldのインデックス画面が確認できます。


それでは、アイテムを新規作成してみます。
ためしにSort Numを範囲外の1000で 登録しようとすると、下記のようにエラーが発生します。



これを防ぐため、モデルにvalidates_numericality_ofを追加します。
$ vi app/model/my_first_domain.rb
validates_numericality_of :sort_num, :greater_than_or_equal_to => 0, :less_than_or_equal_to => 99

再度登録しようとすると、今度はちゃんとバリデーションメッセージが表示されるようになりました。


範囲内の数値で登録すると、正常に登録が成功しました。


このとおり、railsからもさくっとSimpleDBを使うことができました。

つかれた。。今日はここまで。

2011年6月20日月曜日

Amazon SimpleDBってなんじゃ?(その2 PHP SDK編)

前回、SimpleDBをscratchpadから使用してみましたが、実際にはプログラムからSDKを通じて使用するケースがほとんどだと思うので、今回はPHPのSDKを使用してアイテム(レコード)のCRUD(作成、読込、更新、削除)をしてみたいと思います。

準備

今回はPHPのSDKを使用するので、ここからSDKをダウンロードしてロードしやすい場所に配置します。
$ mkdir src
$ cd src
$ wget http://pear.amazonwebservices.com/get/sdk-latest.zip
$ unzip sdk-latest.zip
$ cd sdk-1.3.4
$ mkdir /var/www/html/api
$ mv sdk-1.3.4 /var/www/html/api/
$ cd /var/www/html/api
$ ln -s sdk-1.3.4 sdk
SDKのドキュメンテーションを参考にいろいろなクエリを試して見ます。


ドメイン(テーブル)の新規作成

パラメータは  前回、ドメイン(テーブル)を作成した際と同様ドメイン名です。
<?php
  
  //ダウンロードしたSDKディレクトリのsdl.class.phpをロードします。
  require_once '../../sdk/sdk.class.php';
  //アクセス用のキーを定義します。
  $access_key = "xxxxxxxxxxxxxxxxxx";
  $secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  //キーをもとにSDKのSDBアクセサクラスを初期化します。
  $sdb = new AmazonSDB($access_key, $secret_key);
  //ドメイン作成します。
  $data = $sdb->createDomain("member");
  //戻り値から成否を判断し、成功なら戻り値のダンプを返します。
  if($data->isOK()){
    print_r($data);
  }
  else{
    print_r("失敗〜");
  }
?>
成功した場合、戻り値のオブジェクトのisOK()がtrueで返ります。
戻り値のダンプは以下のとおりです。
CFResponse Object
(
    [header] => Array
        (
            [content-type] => text/xml
            [transfer-encoding] => chunked
            [content-encoding] => gzip
            [vary] => Accept-Encoding
            [date] => Mon, 20 Jun 2011 08:09:44 GMT
            [server] => Amazon SimpleDB
            [_info] => Array
                (
                    [url] => https://sdb.amazonaws.com/
                    [content_type] => text/xml
                    [http_code] => 200
                    [header_size] => 205
                    [request_size] => 691
                    [filetime] => -1
                    [ssl_verify_result] => 0
                    [redirect_count] => 0
                    [total_time] => 2.144966
                    [namelookup_time] => 0.208893
                    [connect_time] => 0.403431
                    [pretransfer_time] => 0.804195
                    [size_upload] => 0
                    [size_download] => 193
                    [speed_download] => 89
                    [speed_upload] => 0
                    [download_content_length] => 0
                    [upload_content_length] => 0
                    [starttransfer_time] => 2.144638
                    [redirect_time] => 0
                    [method] => POST
                )

            [x-aws-stringtosign] => 略
            [x-aws-request-headers] => Array
                (
                    [Content-Type] => application/x-www-form-urlencoded; charset=utf-8
                )

            [x-aws-body] =略
        )

    [body] => CFSimpleXML Object
        (
            [@attributes] => Array
                (
                    [ns] => http://sdb.amazonaws.com/doc/2009-04-15/
                )

            [ResponseMetadata] => CFSimpleXML Object
                (
                    [RequestId] => 673f1239-14be-ff54-9115-8ede692b7dc9
                    [BoxUsage] => 0.0055590278
                )

        )

    [status] => 200
)
このようにアクションの戻り値はヘッダ、ボディ、ステータス部に分かれて構成されたXMLのオブジェクトとして返され、実際のレスポンスデータはボディ部に含まれます。
このアクションはドメイン作成でデータの取得ではないため、返却値はなくメタデータのみが返されます。
また、戻り値のisOKメソッドでアクションの成否の判断ができます。


アイテム(レコード)の追加

SimpleDBではアイテムの追加と更新は同じメソッドを利用します。
アイテムの追加は、ドメイン名(テーブル名)とアイテム名(プライマリキー)と各属性(カラム名)とその値の連想配列をパラメータとします。戻り値はドメインの作成と同様更新アクションなので、返却値はなくメタデータのみになります。
<?php

  require_once '../../sdk/sdk.class.php';

  $access_key = "xxxxxxxxxxxxxxxxxx";
  $secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

  $sdb = new AmazonSDB($access_key, $secret_key);
  
  //1件ずつのインサート
  $data1 = $sdb->put_attributes('member',//ドメイン名
                                     'memorycraft',//アイテム名(プライマリキー)
                                     array(//各属性名と値の連想配列
                                       'country' => 'Japan',
                                       'location' => 'Tokyo',
                                     )
                                );

  /*
   * 複数件同時にインサート
   * ・ドメイン名
   * ・アイテム名(プライマリキー)をキーにした属性と値の連想配列
  */
  $data2 = $sdb->batchPutAttributes('shop', //ドメイン名
                                            array('David' => array('country' => 'USA',
                                                               'location' => 'Seattle'
                                                              ),
                                                 'Satoru' => array('country' => 'Japan',
                                                              'location' => 'Saitama'
                                                              )
                                            )//アイテム名をキーにした属性と値の連想配列
                                   );

    if($data1->isOK() && $data2->isOK()){
      print_r($data1);
      print_r($data2);
    }
    else{
      print_r("失敗〜");
    }

?>
値のセットは、1件の場合はput_attributeメソッドで、複数アイテム同時にセットする場合はbatchPutAttributesメソッドを使用します。

最後の引数としてreplace引数をtrue/falseで追加すると、指定したアイテム名が該当するアイテムが既に存在した場合の挙動をコントロールできます。replace引数はデフォルトfalseです。
//普通のインサート
$data1 = $sdb->put_attributes('member',
                                     'memorycraft',
                                     array(
                                       'country' => 'Japan',
                                       'location' => 'Tokyo',
                                     )
                                );
//値を変えて再投入
$data2 = $sdb->put_attributes('member',
                                     'memorycraft',
                                     array(
                                       'country' => 'Japan',
                                       'location' => 'Chiba',
                                     )
                                );
この場合、2回目のput_attributeの時点では既にmemorycraftというアイテムは存在しているので、location属性はTokyoという値を上書きせずに更にChibaという値も持つことになります。SELECTするとlocation属性の値としてTokyo, Chibaの2つが返ることがわかります。

また、最初から複数値をセットすることもできます。
$data = $sdb->put_attributes('member',
                                     'memorycraft',
                                     array(
                                       'country' => 'Japan',
                                       'location' => array('Tokyo', 'Chiba'),
                                     )
                                );

このようにデフォルトの状態では既存アイテムに対して複数値のセットになってしまうことを避けたい場合は、put_attributeの第4引数であるreplace引数をtrueにセットします。
//普通のインサート
$data1 = $sdb->put_attributes('member',
                                     'memorycraft',
                                     array(
                                       'country' => 'Japan',
                                       'location' => 'Tokyo',
                                     )
                                );
//値を変えて再投入
$data2 = $sdb->put_attributes('member',
                                     'memorycraft',
                                     array(
                                       'country' => 'Japan',
                                       'location' => 'Chiba',
                                     ),
                                     true//replace引数をtrueに
                                );
この場合、locationは複数値にならずTokyoがChibaに変更されます。


アイテム(レコード)の検索

アイテムの検索はRDBでいうところのSELECTにあたります。
戻り値には検索結果としての返却値が含まれています。
>?php
  require_once '../../sdk/sdk.class.php';

  $access_key = "xxxxxxxxxxxxxxxxxx";
  $secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";

  $sdb = new AmazonSDB($access_key, $secret_key);
  $sql = "select * from member where country = 'Japan'";//country属性がJapanのものを検索
  $data = $sdb->select($sql, array("ConsistentRead" => "true"));

    if($data->isOK()){
      print_r($data);
    }
    else{
      print_r("失敗〜");
    }

?<

この場合、戻り値$dataのダンプは以下のようになります。
CFResponse Object
(
    [header] => Array
        (
            [content-type] => text/xml
            [transfer-encoding] => chunked
            [content-encoding] => gzip
            [vary] => Accept-Encoding
            [date] => Mon, 20 Jun 2011 11:19:32 GMT
            [server] => Amazon SimpleDB
            [_info] => Array
                (
                    [url] => https://sdb.amazonaws.com/
                    [content_type] => text/xml
                    [http_code] => 200
                    [header_size] => 205
                    [request_size] => 753
                    [filetime] => -1
                    [ssl_verify_result] => 0
                    [redirect_count] => 0
                    [total_time] => 0.808396
                    [namelookup_time] => 0.002231
                    [connect_time] => 0.195101
                    [pretransfer_time] => 0.595389
                    [size_upload] => 0
                    [size_download] => 285
                    [speed_download] => 352
                    [speed_upload] => 0
                    [download_content_length] => 0
                    [upload_content_length] => 0
                    [starttransfer_time] => 0.808132
                    [redirect_time] => 0
                    [method] => POST
                )

            [x-aws-stringtosign] => 略
            [x-aws-request-headers] => Array
                (
                    [Content-Type] => application/x-www-form-urlencoded; charset=utf-8
                )

            [x-aws-body] => 略
        )

    [body] => CFSimpleXML Object
        (
            [@attributes] => Array
                (
                    [ns] => http://sdb.amazonaws.com/doc/2009-04-15/
                )

            [SelectResult] => CFSimpleXML Object
                (
                    [Item] => Array
                        (
                            [0] => CFSimpleXML Object
                                (
                                    [Name] => memorycraft
                                    [Attribute] => Array
                                        (
                                            [0] => CFSimpleXML Object
                                                (
                                                    [Name] => location
                                                    [Value] => Tokyo
                                                )

                                            [1] => CFSimpleXML Object
                                                (
                                                    [Name] => country
                                                    [Value] => Japan
                                                )

                                        )

                                )

                            [1] => CFSimpleXML Object
                                (
                                    [Name] => Satoru
                                    [Attribute] => Array
                                        (
                                            [0] => CFSimpleXML Object
                                                (
                                                    [Name] => location
                                                    [Value] => Saitama
                                                )

                                            [1] => CFSimpleXML Object
                                                (
                                                    [Name] => country
                                                    [Value] => Japan
                                                )

                                        )

                                )

                        )

                )

            [ResponseMetadata] => CFSimpleXML Object
                (
                    [RequestId] => d2c6f796-5d0d-cc2f-3b63-e461e108d38e
                    [BoxUsage] => 0.0000320033
                )

        )

    [status] => 200
)
このように、body要素のSearchResultの中に検索結果が出力されてきます。
この場合はアイテム(レコード)が2件取得されたので、Item要素はCFSimpleXML Objectの配列になりますが、1件の場合は配列ではなくCFSimpleXML Objectになります。

これらはXMLオブジェクトなどを含んでいるため結果セットのパースや操作がやや面倒です。
そのため、こちらのサンプルのようにレスポンスを連想配列セットに再構築する汎用メソッドやライブラリなどを用意しておくと便利です。
$data = $sdb->select($sql, array("ConsistentRead" => "true"));//クエリ実行
$data = reorganize_data($data->body->Item());//戻り値を再構築
print_r($data["rows"][0]["country"]);//1番目のアイテムの国を出力

また、SimpleDBはデフォルトでは非アトミックなため、SELECTなどでその前の更新内容の伝播が遅れていても読み込まれる場合があります。それを防ぐためには、このサンプルのように第2引数のオプション配列でConsistentReadを有効にするように指定します。ポイントはTRUEを文字列として渡すことです。ブール値で渡すとエラーが発生します。
$data = $sdb->select($sql, array("ConsistentRead" => true));//エラーが発生
$data = $sdb->select($sql, array("ConsistentRead" => "true"));//正しい指定のしかた

アイテム名(プライマリキー)を直接参照、指定する際はitemName()という関数を使用します。
$sql = "select * from member where itemName() = 'memorycraft'";

そのほかSELECTで使用できるクエリ構文に関してはSimpleDBのデベロッパーガイドが参考になります。


続き(アイテムの更新、削除)はまた次回~

2011年6月17日金曜日

Amazon SimpleDBってなんじゃ?(その1 Scratchpad編)

いまさらですが、さいきんAWSで遊んでます。AmazonWebServiceというAmazonが貸し出すインフラをAPIを使って構築できるダイナミックなサービスです。

その中でSimpleDBというサービスがあります。普段ぼくらが使っているMySQLやOracleなどのリレーショナルデータベースとはちがって、結合や複雑なトランザクションがなく、単体の表がたくさんあるような、エクセルに似たデータの持ち方をしています。

つまり複雑さを捨てた代わりに、スピードや拡張性を追求しているということができます。

SimpleDBはエクセルやRDBMSに該当する以下の概念があります。
  • ドメイン:エクセルではシート、DBでいうテーブル
  • アイテム:エクセルでは行、DBではレコード
  • アイテムネーム:プライマリキー
  • 属性:エクセルでは列、DBではカラム
そのほかいろいろ制限やクセはあるようですが、とりあえず遊んでみました。


既にAWSのアカウントを保持していることが前提ですが、
SimpleDBのページで利用申し込みをします。




 申し込むと登録完了メールが届いて、すぐつかえるようになります。

 普通はプログラムから使用するんですが、その前にまず簡単なクライアントツールが用意されているので、それで触ってみます。

Javascript Scratchpad for Amazon SimpleDBというツールをダウンロードして、解凍した中にあるindex.htmlをブラウザで開きます。

ヘッダにアクセスキーとシークレットアクセスキーを入力して、右側のリストから仕様したいAPIを選びます。



ドメイン(テーブル)の作成

まずは表(ドメイン)を作りたいので、"CreateDomain"を選択します。これはDBでいうところのcreate tableに該当します。

Domain Name(テーブル名)を入力し、"Display Signed URL"を押すと、APIリクエストのURLが表示され、"Invoke Request"を押すと実際にそのURLで別窓をターゲットにドメイン生成のAPIアクセスが行われ、XMLのレスポンスが返ります。
ここではDomain Nameに"member"と入力しました。

 すると、
<CreateDomainResponse>
  <ResponseMetadata>
    <RequestId>813d1434-dc52-b4ae-2616-0f3e57dbfcec</RequestId>
    <BoxUsage>0.0055590278</BoxUsage>
  </ResponseMetadata>
</CreateDomainResponse>
というレスポンスが返ってきました。

まだ慣れていないので、このレスポンスで正常なのかわかりません。
ドメインの一覧を見て"member"ドメインが作成されたか調べてみましょう。



ドメイン(テーブル)の一覧

今度はヘッダ右のリストから"ListDomains"というAPIを選択します。これは現在登録中のドメインの一覧を取得するものです。mysql でいうところのshow tablesでしょうか。


ここで、2つの入力項目"Max Number Of Domains" と "Next Tokens"があります。
"Max Number Of Domains"はそのまま取得したい最大件数の制限をかけるものです。
"Next Token"に関しては後ほどアイテムの一覧で説明します。

ここではMax Number Of Domainsに10と入れて"Invode Request"を押します。
すると以下のようなXMLレスポンスが返ります。
<ListDomainsResponse>
  <ListDomainsResult>
    <DomainName>member</DomainName>
  </ListDomainsResult>
  <ResponseMetadata>
    <RequestId>1af6eec5-5ab5-2b84-c4f1-7a731f874dab</RequestId>
    <BoxUsage>0.0000071759</BoxUsage>
  </ResponseMetadata>
</ListDomainsResponse>
ここで、さっきのCreateDomainのレスポンスとの違いを見ると、レスポンスの意味がわかってきました。ListDomainsResultという要素がDomainNameという要素を1つ含みDomainNameはmemberというテキストを持っています。これが実際に知りたかったドメイン一覧の部分で、残りのResponseMetadataの部分は、それ以外のメタデータのようです。つまりさっきのCreateDomainは返却値のあるクエリではなく更新のクエリだったため、メタデータのみが返ってきたということがわかります。この感じはDBのSELECTとDDLの関係にとても似ています。



アイテム(行)の追加

 "member"というドメインが正常に作成されたようなので、次は行(アイテム)を追加していきましょう。APIリストから"PutAttribute"を選びます。


 上部にDomain NameとItem Nameという項目があります。memberドメインに行(アイテム)を追加するので、"member"と入力します。Item Nameですが、これはmemberドメインのプライマリキーにあたるものです。member内で一意ならばなんでもいいので、メールアドレスなどでもいいですが、ここではIDっぽく1と入れておきます。

そして、以下Attributeというブロックがあり、Name、Value、Replaceという項目があり、右上の+と-のマークがあります。ここで属性(カラム)を好きなだけ追加します。
ここでは、nameとcountryの属性を設定します。

まず最初のAttributeのボックスにname属性を追加します。
Name:name
Value:memorycraft
Replace:
そして、右上の+ボタンを押し、次のAttributeボックスにcountry属性を追加します。
Name:country
Value:Japan
Replace:
このように属性名とその値をセットで登録して、"Invoke Request"を押します。するとCreateDomainのときと同じようにResponseMetadataだけのレスポンスが返ってきます。更新系のクエリのためです。

このようにして以下のように3アイテム追加しました。

ItemName, name, country
1, memorycraft, Japan
2, David, USA
3, Pierre, France

これらが正常に登録されているか見てみましょう。



アイテムの検索

さきほどはドメインの一覧をListDomainsで調べました。これは、create table したものをshow tablesで調べるようなものです。今度は行を調べるのでselect文にあたるクエリを使います。
SimpleDBには、SQLと似たSelect構文があり、それを使います。

APIリストからSelectを選びます。

 ここには
"Select Expression"、"Next Token"、"Consistent Read"という項目があります。
ここでは"Select Expression"に単純に"select * from member"と入力して結果を見てみます。
<SelectResponse>
  <SelectResult>
    <Item>
      <Name>1</Name>
      <Attribute><Name>name</Name><Value>memorycraft</Value></Attribute>
      <Attribute><Name>country</Name><Value>Japan</Value></Attribute>
    </Item>
    <Item>
      <Name>2</Name>
      <Attribute><Name>name</Name><Value>David</Value></Attribute>
      <Attribute><Name>country</Name><Value>USA</Value></Attribute>
     </Item>
     <Item>
       <Name>3</Name>
       <Attribute><Name>name</Name><Value>Pierre</Value></Attribute>
       <Attribute><Name>country</Name><Value>France</Value></Attribute>
      </Item>
    </SelectResult>
  <ResponseMetadata>
    <RequestId>694e492f-feec-e860-258e-29086b644585</RequestId>
    <BoxUsage>0.0000411449</BoxUsage>
  </ResponseMetadata>
</SelectResponse>
このように3件登録されているのがわかります。

ここで、"NextToken"とはなんでしょうか。
調べてみると、次の結果セットへのポインタのようなものだとわかりました。
SimpleDBには、スピードや冗長性を保つために他のものを犠牲にしており、たとえば1度のクエリ実行によりフェッチできる件数は最大2500件までです。
そのため、SimpleDBでは結果の一部だけを取得した場合、APIレスポンスの中にそれに続く結果セットへのポインタとしてNextTokenという文字列を含めて返却します。

たとえば、この場合select * from member limit 2というクエリを発行した場合、レスポンスには2件分の結果セットのほかに以下のような要素が入っています。
<NextToken>rO0ABXNyACdjb20uYW1hem9uLnNkcy5RdWVyeVByb2Nlc3Nvci5Nb3JlVG9rZW7racXLnINNqwMA
C0kAFGluaXRpYWxDb2ddGVudExTTnQAEkxqYXZhL2xhbmcvU3Ry
aW5nO0wAEmxhc3RBdHRyaWJ1dGVWYWx1ZXEAfgABTAAJc29ydE9yZGVydAAvTGNvbS9hbWF6b24v
c2RzL1F1ZXJ5UHJvY2Vzc29yL1F1ZXJ5JFNvcnRPcmRlcjt4cAAAAAAAAAAAAAAAAAIAAAAAAAAA
AAAAAAAAAAAAAABwcHB4</NextToken>
そして、次の結果セットを取得する場合は、このNextTokenをセットして同じクエリで、再度クエリ実行します。

すると、残りの1件が以下のように取得することができます。
<SelectResponse>
  <SelectResult>
    <Item>
      <Name>3</Name>
      <Attribute><Name>name</Name><Value>Pierre</Value></Attribute>
      <Attribute><Name>country</Name><Value>France</Value></Attribute>
    </Item>
  </SelectResult>
  <ResponseMetadata>
    <RequestId>ac269ea7-4733-8da2-6705-41a069a88d0f</RequestId>
    <BoxUsage>0.0000228616</BoxUsage>
  </ResponseMetadata>
</SelectResponse>
複数に分割された結果セットにおいて、NextToken要素は、最後の結果セットになるまでレスポンスに含まれ、常にその次の結果セットへのポインタを示します。

つまり、APIをプログラム内で仕様する際には、すべての結果を一度に表示したい場合、NextTokenがなくなるまでループしながら結果の取得をするようなロジックを組む必要があります。
また、ページネーションを明示的に行う場合も、limit句とNextTokenを組み合わせて使用します。

また、"Consistent Read"という項目も、同様にスケーラビリティを優先したためあえて捨てられたデータの一貫性に関する項目です。分散されたデータストレージへ更新が伝播しきるまえに取得されると最新のデータではないものが取得されるようになっており、それでスピードを出しているのですが、それではまずい場合もあります。
その場合はこの"Consistent Read"をtrueに設定することにより、取得スピードは遅くなるけれども最新のデータを取得できるようになっています。
 あまり使いすぎるとSimpleDBのよさがなくなってしまうので、要所で使うのが好ましいようです。
また、結局全部trueになってしまった、という場合はそもそもSimpleDBではなくRDBMSを使用するこを検討したほうがいいかもしれません。


今日はここまでー。
いきなりがんばりすぎて続く気がしない。。。