Azure Cosmos DBをDynamoDBと比べてみる
AzureのCosmosDB[1]って使いやすいなぁと個人的に思っているので、AWSのDynamoDBとの比較を個人の感想レベルで記載したいと思います。
CosmosDBが使いやすいと思う点
全ての項目にインデックスを付けられる
何と言ってもCosmosDBが扱いやすい点はこれでしょう。DynamoDBで多くの人が血を吐いたセカンダリインデックスなどというものは不要です。CosmosDBはデフォルトで全ての項目にインデックスが付きます。つまり、デフォルトで全ての項目でソートや絞り込みが可能です。
これはDynamoDBでは出来ないことであり、効率面とかコストとか色々意見はでるとは思いますが、シンプルに扱いやすいのは間違いないと思います。
ユニークキーの存在
CosmosDBではパーティション内でのユニーク制約を設定できるユニークキーが存在します。
このユニークキー制約により、CosmosDBではデータの一意性を保証することが出来ます。
これにより一意性を担保したいデータがある時、アプリケーション側でのデータのチェックが不要になったり、複数データの考慮が不要になるので、とても便利です。
SQLが使える
CosmosDB for NoSQLは、SQLが使えます!
「なに意味不明なことを言っているんだ?」と思われるかと思いますが、生成AIに聞いても使えると言っているので間違いありません。
つまり、生成AIの回答にあるように、NoSQLなのにSQLにそっくりなクエリ構文を使うことができます。これにより、SQLに染まったエンジニアでも比較的容易にキャッチアップすることが出来ますし、DynamoDBでは出来ないような複雑なクエリを実行することもできます。
これが非常に便利です。
サーバレスだと、かなり安く使える
CosmosDBにはプロビジョンドスループットとサーバレスの2つのモードがあります。プロビジョンドスループットは事前に必要なRU/秒を設定するモードですが、サーバレスモードはRU消費量に応じて自動でスケールするします。
このサーバレスモードが、個人的な感覚としてはかなり安いです。AWSで普通にシステムを構築すると基本的にDBの値段が5割くらいを占めてしまうという偏見があるのですが、CosmosDBサーバレスを使った実際の金額がこちら
月額512円。
小規模なシステムではありますが、実際に数年間使い続けているサービスのDBです。とてもそうは思えない安さですよね。キリが良い数字なのは偶然です。
サーバレスでは最小課金がなく、使った分だけ支払えばいいという点が魅力的です。開発環境や負荷の少ない本番環境では、非常にコスト効率が良いと言えるでしょう。
CosmosDBのイマイチな点
もちろんCosmosDBはイマイチだと感じている点もあります。
必須項目のIDが煩わしい
CosmosDBではid
というプロパティが必須となっています。id
がいわゆるプライマリーキーなので仕方ない部分はあるのですが、実際問題として使いづらい場面が多いです。特にCosmosDBの場合はユニークキー制約で一意性を担保できるのに、別途IDを管理する必要があるのは無駄に手間がかかります。
せめてid
以外の名称に変更できればよかったのですが、id
となっている以上ID以外の使い方が難しく、私は大抵の場合無意味にUUIDを発行して入れています。
いい感じの使い方をご存じの方がいたら教えて欲しいです。
SQLが複雑になりがち
先ほどSQLが使える点を利点として挙げましたが、これは逆に問題を引き起こす可能性もあります。
まず、SQL構文を使わないとクエリが書きづらいという点を上げたいです。通常のNoSQLデータベースのようなシンプルなクエリインターフェースが乏しいため、ちょっとしたDB操作でもSQLライクな構文を書く必要があります。
そして、それ以上に大きな問題はSQLで「なんでもできてしまう」点です。複雑な検索条件の式も書けますし、なんならパーティションをまたいだクエリも書けてしまいます。これはDynamoDBでは意図的に制限されている操作ですが、CosmosDBではSQLの柔軟性により簡単に実行できてしまいます。
この自由度は一見便利ですが、パフォーマンスの低下やRUの大量消費を引き起こします。「できるから」という理由でパーティション設計を無視した非効率なクエリを書いてしまうリスクがあり、結果的にコスト増大やパフォーマンス低下につながる恐れがあります。
また、コードの可読性も大幅に低下する可能性が高いです。そもそもリレーショナルなDBを使っていてもSQLを直接書くケースってほとんどないですよね。普通はORM使いますよね。しかしCosmosDBではSQLのような構文を直接書く必要があるので、普通のコードにSQL文が混ざりかなり見にくいコードになってしまいます。(CosmosDBに対応しているORMもなくはないみたいですがかなり限定的です。)
SQLインジェクションなどのセキュリティ面で気をつけないといけないことも増えますので、便利に使うつもりが逆にコストやリスクが増える可能性すらあります。
つまり、CosmosDBはSQLの自由度により分かりやすさやNoSQLデータベースとして効率性を阻害しているとも言えます。それに比べるとDynamoDBの制約は一見不便に思えますが、実はユーザーに効率的な設計を促す仕組みだということが分かります。
NoSQL以外のCosmosDBもあってサービス体系が意味不明
これはCosmosDBの問題と言うよりAzureの問題ですが、サービス体系が意味不明です。CosmosDBと名がつくサービスには以下があります。[2]
- Azure Cosmos DB for NoSQL
- Azure Cosmos DB for MongoDB
- Azure Cosmos DB for Apache Cassandra
- Azure Cosmos DB for Apache Gremlin
- Azure Cosmos DB for Table
- Azure Cosmos DB for PostgreSQL
修飾無しでCosmosDBと呼んだ場合に通常はNoSQLを指していると私は認識しています。
MongoDBはMongoDBですし、CassandraはCassandra、GremlinはGremlinだと思います。そのままですが。Tableは良く分からないのですがAzure Table Storageというサービスと関連があるらしいです。
そして、PostgreSQLはPostgreSQLです。ポスグレです。普通にSQLのDBです。
なんでこんなに方向性がバラバラなサービスを全てCosmosDBとつけたのか理解に苦しみます。
なお、記事を書くあたって公式ドキュメントを確認したら「AI時代のデータベース」とか謎のキャッチフレーズがついていました。
AIアピールをしたいのでしょうけど流石に無理があると思います。
まとめ
個人的には、CosmosDBの全ての項目へのインデックス付与、ユニークキー制約、SQLライクなクエリ言語、そしてサーバレスモードのコスト効率の良さなどが、DynamoDBに比べて使いやすいと感じる点です。一方でIDが必須項目であることや「なんでもできる」SQLの自由度、そもそもAzureのサービスであることが足かせになることもあると感じています。
プロジェクトの要件や既存の技術スタック、チームの経験などによって最適なデータベースは変わってきますが、Azureでアプリやシステムを開発するならCosmosDBは非常に魅力的な選択肢だと思います。
普段からAWSやGoogle Cloudを使っているとなかなか触る機会のないDBだと思いますが、勇気を出して一度CosmosDBを試してみるのと新しい発見があるかもしれません。

NCDC株式会社( ncdc.co.jp/ )のエンジニアチームです。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください! ※エンジニア以外も記事を投稿することがあります
Discussion