数年前にDynamoDBを使用した開発を行った。
その際に感じたのがDynamoDBはメインDBに向かないというのが一つの感想であった。当時の僕は、ピヨピヨのエンジニアだったので、この感想は自分の技術力不足にだったこともありあまり、大きな声でこの考えを発信することはできなかった。
しかし、最近Xで「DynamoDBをメインで使用すると至難の道である」という趣旨の投稿があったので、やはり自分は間違っていなかったのかもしれないと思い、DynamoDBについて掘り下げようというモチベーションが湧いてきた。
それと時を同じくして「AWSの基本・仕組み・重要用語が全部わかる教科書」を読んだ際にDynamoDBの仕組みの解説が非常に腹落ちしたのでそのアウトプットとして本記事を書こうと決意をした。
という訳で今回のメインテーマは「DynamoDBは何故Webシステムでメインデータベースに向かないと考えたのか」。
「Webシステムで」と書いたのは僕がシンプルにWebシステムしか経験がないということであり、あくまで僕の(狭い)観測範囲ではという注釈をつけておきたい。
はじめにまとめ
取り敢えず、分散型のNoSQLでスキーマレスという特徴から、DynamoDBをメインDBとして使うと苦労したよという話だが、もう少しまとめてみたい。
DynamoDBを使用する上で理解しなければいけない性質
・NoSQLであるということ
・スキーマレスであり、キーはパーティーションキーとソートキーのみ
・分散型であるということ
DynamoDBでできないこと
・SQLを使用できない。(これはメインのDBに不向きな理由というよりつまづきポイントに近い)
・キーの設定に制約がある
・正確に集計するような複雑なクエリを書くことができない(結合や副問合せ、論理演算、GROUP BYによる集計など)
解説
クエリ言語
DynamoDBはNoSQL系のデータベースであり、RDB用のクエリ言語であるSQLは使用できない。
DynamoDBはキーバリュー型のデータ構造をしており、表のようにデータを管理するRDBとはデータの取り扱い方が異なるため
スキーマレス
DynamoDBパーティションキーとソートキーでデータを取得するキーバリュー型という性質、また、拡張性を重視したスキーマレスという性質上、スキーマ定義がDB上でできない。
そのため、RDBのように複数の項目をキーとしては設定できないため、複数の項目でユニークにしたいカラムの組み合わせを作れない。
項目の型定義もない。NULLがダメだとか、何文字までみたいな制約もない。
AppSyncを使用してスキーマの定義はできるが、自由に定義してしまうため、「あれ?こんな項目あったっけ」みたいな凡ミスも起こる。(これは開発者がしょぼいだけ)
分散型
結局ここが大きい。
DynamoDBが可用性とスケーラビリティを実現するために、データを各AZに分散させて配置している。こうすることで単一障害点をなくし、拡張性を優位にすることができる。
しかし、この分散配置は全てのAZに同じデータを格納しているわけではなく、AZによって保管されているデータが異なる。そのため、一回のクエリで全てのデータを処理して紐づけるような複雑なクエリを行うことができない。
具体的にRDB目線でできないことは下記のようになる。
・結合や副問合せ
・ANDやORなど論理演算
・GROUP BYによる集計
これだけで何にもできないような気がしてしまう。
My解決策
結合や副問合せなどの正確な処理が必要な場合はRDB、シンプルにキーで引っ掛けられるデータはDynamoDBとハイブリットな構成にするのが良いかもしれない。DynamoDBのメリットを享受できてるかは分からないけど。
感想
分散型であり一元的にデータを管理できていないため、結果整合性、強い整合性といったオプションがあるんだと少し納得した。
DynamoDBだけでなくNoSQLを使いこなしている人はどうやって使ってんのか教えて下さい。