第38夜 AWS SimpleDBの超基礎

そんなのがほしいみたいなコメントがあったので。そういやSImpぇDBがどんなものかってコードかいてない気がした。SQLっぽいというだけで。

全体の流れ

まず全体を見てもらったほうが早いだろうということで今回のサンプルコードのシナリオ。SimpleDBTestというクラス名。メソッドも引数も日本語なのでこれだけ見てなんとなくわかるはず。

public static void main(String[] args) {
    new SimpleDBTest().run("TEST");
}

private void run(String ドメイン名) {
    String アクセスキー = "----";
    String シークレットキー = "----";


    AmazonSimpleDBClient sdb = new AmazonSimpleDBClient(new BasicAWSCredentials(アクセスキー, シークレットキー));
    sdb.setEndpoint("sdb.ap-northeast-1.amazonaws.com");//東京リージョン

    ドメイン作成(sdb, ドメイン名);
    ドメイン一覧(sdb);

    データ追加(sdb, ドメイン名, 1, "北海道");
    データ追加(sdb, ドメイン名, 2, "青森県");
    データ追加(sdb, ドメイン名, 3, "岩手県");
    データ追加(sdb, ドメイン名, 13, "東京都");
    データ追加(sdb, ドメイン名, 47, "沖縄県");

    データ一覧(sdb, ドメイン名);

    ドメイン削除(sdb, ドメイン名);

    sdb.shutdown();
}

以下の手順で行うということ。

単語

  • ドメインというのはRDBでいうところのテーブルに相当する。
  • アイテムというのがRDBのテーブルの中の行に相当する。
  • 属性というのがRDBのカラムに相当する。

これだけわかれば大丈夫。

ドメインの作成

private void ドメイン作成(AmazonSimpleDBClient sdb, String ドメイン名) {
    CreateDomainRequest request = new CreateDomainRequest(ドメイン名);
    sdb.createDomain(request);
    System.out.println("ドメイン名:" + ドメイン名 + "を作成しました");
}

引数はドメイン名のみなので簡単。

なんたらrequestというのを作成してそれをSimpleDBClientインスタンスの各種メソッドに渡す。これがすべてのSimpleDBの使い方、というのを覚えておいてほしい。

ドメイン一覧を表示

private void ドメイン一覧(AmazonSimpleDBClient sdb) {
    ListDomainsResult listDomains = sdb.listDomains();

    System.out.println("---------------------");
    System.out.println("ドメイン名一覧");
    for (String name : listDomains.getDomainNames()) {
        System.out.println(name);
    }
}

文字列を格納したListが取得できるというだけ。簡単。すべての一覧取得だとなんたらrequestすら必要ない。

サンプルデータの作成

private void データ追加(AmazonSimpleDBClient sdb, String ドメイン名, int ID, String 名前) {
    PutAttributesRequest request = new PutAttributesRequest();
    //SimpleDB は文字列のみなため、0うめ2桁にする。実際のところprintfの%0d使ったほうが楽かも
    String itemName = SimpleDBUtils.encodeZeroPadding(ID, 2);

    //データ本体
    ReplaceableAttribute data = new ReplaceableAttribute();
    data.withName("NAME").withValue(名前);

    request.withDomainName(ドメイン名).withItemName(itemName).withAttributes(data);

    sdb.putAttributes(request);
}

一番ややこしいのがここ。ここを理解すれば後は問題ない。

最初と最後を見るとここもなんたらrequestを利用しているのがわかる。つまり、使い方は同じ。

itemNameというのはItemを一意に現す名前。RDBのROWIDとか主キーみたいなもの。2桁の数値型としたいところだが、SimpleDBは文字列しか扱えないため0埋めなどの処理を行う必要がある。その辺のユーティリティは用意されている。

withなんたらという書き方はセッターを列挙するのがたるいので自分自身を返して、ピリオドでつなげてかけるというもの。

ドメイン名とアイテム名はわかると思うが、最後のwithAttributesが属性を設定する。実際のデータ部分。ここはコレクションや可変長配列で設定できるため複数入れることが可能(今回は可変長配列でいれてある。ひとつしかないのでわかりにくいが)だ。つまり、カラムの名前と値のセットということ。

サンプルデータの検索表示

private void データ一覧(AmazonSimpleDBClient sdb, String ドメイン名) {
    String query = String.format("select * from %s where itemName() < '%02d'" ,ドメイン名  , 10);
    SelectRequest request = new SelectRequest(query,true);
    SelectResult result = sdb.select(request);

    System.out.println("---------------------");
    System.out.println("データ一覧");
    for (Item row : result.getItems()) {
        int id = SimpleDBUtils.decodeZeroPaddingInt(row.getName());//0埋め解除
        String name = row.getAttributes().get(0).getValue();
        System.out.printf("%02d : %s%n", id, name);
    }
}

クエリ文字列を利用してデータの検索。RDBと違うのは文字列しか扱えないことと連結できないこと。countもつかえたり(ただし、件数が増えると速度は落ちていく)普通に検索ができる。

itemName()というのは特殊な書き方で、これがアイテム名を利用するというもの。それくらいしか問題はないはず。
あとは前に出てきた0埋め2桁として扱うというところくらいか。

ドメインの削除

private void ドメイン削除(AmazonSimpleDBClient sdb, String ドメイン名) {
    DeleteDomainRequest request = new DeleteDomainRequest(ドメイン名);
    sdb.deleteDomain(request);
    System.out.println("ドメイン名:" + ドメイン名 + "を削除しました");
}

ここまで読んだなら簡単。




とまぁ、SimpleDBはRDBを利用したことがある人にとって手軽に始められるものだ。データは1つの属性で1024バイトまで、文字列のみなど制限はあるが、そのかわりしっかりインデックスが着いて検索される。EC2重で動かす必要がない、ということで管理ツールなどを単独で作れるのが利点。その代わり大きいサイズのデータはS3に格納するなどを考えないといけない。

トランザクションはなく、1行単位でしか値の更新の安全性が取れない。楽観的排他制御が出来るようになっているので(古いバージョンはなかった)行単位でなら排他が可能だ。