最近、AWSを触っていて、Amazonが貸し出すインフラを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と入力しました。

そうすると、


 
  813d1434-dc52-b4ae-2616-0f3e57dbfcec
  0.0055590278
 

というレスポンスが返ってきました。

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

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

先程のindex.htmlから今度は、ヘッダ右のリストの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レスポンスが返ります。


 
 member
 
 
 1af6eec5-5ab5-2b84-c4f1-7a731f874dab
 0.0000071759
 

ここで、さっきのCreateDomainのレスポンスとの違いを調べてみると、レスポンスの意味が理解できてきました。
ListDomainsResultという要素がDomainNameという要素を1つ含み、DomainNameはmemberというテキストを持っています。
これが実際に知りたかったドメイン一覧の部分で、残りの ResponseMetadataの部分は、それ以外のメタデータのようです。
つまりさっきのCreateDomainは返却値のあるクエリではなく更新のクエリだったため、メタデータのみが返ってきたということがわかります。
この構成はDBのSELECTとDDLの関係にとても似ています。

アイテム(行)の追加

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

上部にDomain NameとItem Nameという項目があるので、Domain 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と入力して結果を見てみます。


 
  
  1
  namememorycraft
  countryJapan
  
  
  2
  nameDavid
  countryUSA
  
  
  3
  namePierre
  countryFrance
  
 
 
  694e492f-feec-e860-258e-29086b644585
  0.0000411449
 

このように3件登録されているのがわかります。

ここで、NextTokenの意味について調べてみたのですが、これは、次の結果セットへのポインタのようなものだとわかりました。

SimpleDBには、スピードや冗長性を保つために他のものを犠牲にしており、たとえば1度のクエリ実行によりフェッチできる件数は最大2500件までになります。

そのため、SimpleDBでは結果の一部だけを取得した場合、APIレスポンスの中にそれに続く結果セットへのポインタとしてNextTokenという文字列を含めて返却します。

たとえば、この場合select * from member limit 2というクエリを発行した場合、レスポンスには2件分の結果セットのほかに以下のような要素が入っています。

rO0ABXNyACdjb20uYW1hem9uLnNkcy5RdWVyeVByb2Nlc3Nvci5Nb3JlVG9rZW7racXLnINNqwMA
C0kAFGluaXRpYWxDb2ddGVudExTTnQAEkxqYXZhL2xhbmcvU3Ry
aW5nO0wAEmxhc3RBdHRyaWJ1dGVWYWx1ZXEAfgABTAAJc29ydE9yZGVydAAvTGNvbS9hbWF6b24v
c2RzL1F1ZXJ5UHJvY2Vzc29yL1F1ZXJ5JFNvcnRPcmRlcjt4cAAAAAAAAAAAAAAAAAIAAAAAAAAA
AAAAAAAAAAAAAABwcHB4

そして、次の結果セットを取得する場合は、このNextTokenをセットして同じクエリで、再度クエリ実行します。

すると、残りの1件が以下のように取得することができます。


 
  
  3
  namePierre
  countryFrance
  
 
 
  ac269ea7-4733-8da2-6705-41a069a88d0f
  0.0000228616
 

複数に分割された結果セットにおいて、NextToken要素は、最後の結果セットになるまでレスポンスに含まれ、

常にその次の結果セットへのポインタを示します。

つまり、APIをプログラム内で仕様する際には、すべての結果を一度に表示したい場合、NextTokenがなくなるまでループしながら結果の取得をするようなロジックを組む必要があります。

また、ページネーションを明示的に行う場合も、limit句とNextTokenを組み合わせて使用する必要があります。

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

こちらの記事はなかの人(memorycraft)監修のもと掲載しています。

元記事は、こちら