みなさん、こんにちは!フリューでモバイルサイト開発を行っている鷲見といいます。
現在、あるソーシャルプラットフォーム上のアプリケーションを構築するプロジェクトでの、クラウド環境の導入の進行状況をそのまま記事にしています。
1ヶ月導入期という記事を書き始めてもう4ヶ月経ちますが、たぶん気のせいです。
今回からしばらくは利用するデータベースサービスAmazon SimpleDBについて、
その制限や特徴、回避方法、データ設計、プログラミングについて説明していきたいとおもいます。
今回はSimpleDBの特徴と制限について説明します
SimpleDBのおさらい
http://aws.amazon.com/jp/simpledb/
SimpleDBはAWS上で展開されている非リレーショナル型のデータストアサービスです。
イメージとしてはKVS(Key Value Store)型のデータベースをイメージすると分かりやすいかと思います。
特徴としては高い可用性と運用の容易さが上げられます。負荷が高くなったような場合にもAWS側で自動的にスケールアウト・スケールアップを行ってくれます。
また、データは自動的に複数のAvailability Zone(AZ)に分散して保存されるので、データがなくなってしまうといったリスクも少なく、可用性も高くなっています。
メリット
- 可用性が高い
- AWS側で管理するサービスなので運用のコストがほとんど掛からない
- スケールアウト・スケールアップを自動で行ってくれる
- 価格が安い
デメリット
SimpleDBの詳細な特徴
ドメイン・属性・アイテム
RDBではテーブル、列という概念が利用されていますが、SimpleDBでは少し異なる考えをとっています。
ドメイン(Domain)
RDBでいうところのテーブルに該当します。ドメインには複数の属性をもつことができます。
属性(Attribute)
RDBでいうところの列によく似ています。属性は名前と値のペアで、ドメインに属します。1つの属性に複数の値を設定することも可能です。
また、他のアイテムに設定されている属性が他のアイテムに存在するとは限りません。
アイテム(Item)
RDBでいうところの行によく似たものです。アイテムはドメイン内において一意となるアイテム名を持ちます。
二次元表における例
Employee
| アイテム名 | name | pref | unit | manager |
| ----- | ---- | ---- | ------- | ------- |
| Emp1 | 鷲見 | 京都 | 開発
企画 | |
| Emp2 | 九岡 | 福井 | 開発 | 佐藤 |
| Emp3 | 川下 | 宮崎 | 企画 | 鈴木 |
この表で説明すると
- ドメイン名はEmployee
- 属性名はname,pref,unit,manager
- アイテムはEmp1,Emp2,Emp3
- 属性は複数の値を持つことができる。(アイテムEmp1の属性unitには開発と企画の2つの値が設定されている。)
- 他のアイテムで設定されている属性が、別のアイテムで存在するとは限らない(アイテムEmp1には属性managerは存在しない)
となります。
すべての値は文字列
SimpleDBではすべてのデータ項目が文字列として扱われます。そのため、プログラム側のデータ型に合わせる際には文字列から該当するデータ型への変換処理が必要となります。
SQLの知識を生かせるSELECT API
Select APIでは通常のSQLのQueryとよく似たQueryを利用することができ、SQLの知識をそのまま活かすことができます。
例えば、上述の表のEmp1をname属性を指定して取り出す場合、
select * from Employee where name='鷲見'
といったクエリをSelect APIに投げることで取得することができます。
もちろん、『order by』によるソートや、『limit』による取得件数の制限も可能です。
自動的なインデックス付け
SimpleDBではすべての属性値に対して、自動的にインデックス付けが行われます。RDBでは自分で設計してインデックスを作成する必要がありましたが、SimpleDBでは自動的に作成されます。
自動的にインデックス付けが行われることによりSelect APIでの検索やソートが行えるようになっています。
SimpleDBの制限
SimpleDBには通常のRDBにはない多くの制限が存在します。
サイズ・容量の制限
SimpleDBには他のAWSのサービス同様、データのサイズ・容量に関する制限が多く存在します。
下記の情報は2011年8月25日時点での情報です。
最新の情報は以下に掲載されているので各自で確認してください。
http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?SDBLimits.html
ドメインあたりのサイズの上限 | 10GB |
---|---|
ドメインあたりの属性値の数 | 10億個 |
ドメイン名の制限 | 3−255文字(半角英数および’-‘,’_’,’.’) |
1アカウントあたりのドメイン数の上限 | 250個 |
1アイテムあたりに含まれる属性ペアの数の上限 | 256個 |
属性名・属性値・アイテム名のサイズの上限 | 1,024バイト |
属性名・属性値・アイテム名に利用できる文字 | XMLとして有効に扱うことのできるすべてのUTF-8の文字 |
PutAttribute APIで操作可能な属性値の数の上限 | 256個 |
Select APIでリクエスト可能な属性値の数の上限 | 256個 |
BatchPutAttributes APIで操作可能なアイテム数の上限 | 25個 |
Select APIで取得可能なアイテム数の上限 | 2,500個 |
クエリの実行時間の上限 | 5秒 |
Select APIで指定可能なユニークな属性の数の上限 | 20個 |
Select APIで利用可能な比較演算子の数の上限 | 20個 |
Select APIのレスポンスサイズの上限 | 1MB |
文字列型の制限
上述の特徴でも述べている通り、属性値はすべて文字列となります。
文字列を扱うだけであれば問題はないのですが、数値項目でソートを行う場合などに文字列であるがゆえの制限が発生します。
SimpleDBでは全てのデータが文字列になるので、ソートも辞書順でのソートとなります。
例えば『1』,『9』,『10』を昇順でソートすると、辞書順になるので『1』,『10』,『9』の順になってしまいます。
またマイナス値が入ってくるとさらにややこしくなり、『9』,『8』,『−8』,『-9』を昇順でソートすると、辞書順で『9』,『8』,『−9』,『−8』という順になってしまいます。
このように全てが文字列であるがゆえの制限があるので、この制限をデータ設計やプログラムで吸収する必要があります。
整合性に関する制限
SimpleDBでは基本的に『結果的な整合性』という考え方で整合性をとっています。
SimpleDBではデータは物理的に離れた複数のAvailability Zone(AZ)にデータの複製が配置され、読み込みの際にはこの複製のデータも読み込みにいきます。
データの更新要求が発行された際に、複製が発行されているサーバに対し、データの更新を転送します。データの更新がすべての複製に反映されるまで少し時間がかかるので、全ての複製が更新されるまでの間、更新前の結果が返ることがあります。このタイムラグは通常は1秒以内とされています。結果的に整合性はとれるのですが、このタイムラグの間は更新前の結果が返ることがあるという整合性の取り方を『結果的な整合性』と呼びます。
必ず更新されたデータを返す『整合性』のオプションも準備されています。更新の結果は必ず反映されますが、データの更新が反映されるまで待つことになるので、『結果的な整合性』より処理時間がかかるようになってしまいます。
更新が行われるデータの特性を考慮し、どちらの整合性オプションを採用するのかを検討する必要があります。
データ構造に関する制限
SimpleDBにはRDBでいうところのデータベースのようなものが存在しません。1つのアカウントの1つのリージョンに対して、1つのデータベースが与えられているというイメージになります。
データベース内でテーブル名が重複してはいけないように、SimpleDBでもドメイン名の重複は許可されていません。
これによって何が困るかというと、同じアカウントで開発環境と本番環境を構築した場合、
- 本番環境とテスト環境で同じドメインを利用し、特定の属性の値により本番環境かテスト環境かどうかを判別する
- 本番環境とテスト環境で異なるリージョンで同じドメインを利用する
- 本番環境とテスト環境でドメイン名を異なるものにする
という対応が必要になります。
データベースという考え方が存在しないため、通常のRDBで行う開発環境と本番環境でデータベースを切り替えるという対応ができないのです。
この開発環境と本番環境の差を吸収する設計が必要になります。
今回のまとめ
今回はSimpleDBについて詳細な特徴と制限について説明してみました。
特徴としては
制限としては
- サイズ・容量の制限
- 文字列型の制限
- 整合性の制限
- データ構造の制限
について説明しました。
次回はこれらの制限の回避方法について説明したいとおもいます。