🔥

低予算の個人開発でMongoDBをRDBの代わりに使うのは割とあり

に公開1

TL;DR

現代的な環境にデプロイする場合、RDBは非常にコストが悪い。
全開発者がエンタープライズクラスの信頼性が必要な高予算Webシステムを開発している訳ではない。
代わりにMongoDB(やその他ドキュメントDB)を使うことで、無料枠で収めることができる場合があり、そのような目的でトレードオフを理解した上でドキュメントDBを選択するのは合理的な選択肢である。

RDBは高い

RedditやTwitterでMongoDBをRDB(リレーショナルデータベース)の代わりに使うことを馬鹿にするミームをよく見ます。確かにほとんどのWebシステムではMongoDBより一般的なRDBの方が適していることがほとんどです。Webシステムではデータを正規化すればリレーショナルになることがほとんどであるため、これは当然のことです。
しかし個人開発の場合、実際にソフトウェアを開発して運用するときに問題になることが多いのは、データの整合性よりコストだと私は考えています。

https://laiso.hatenablog.com/entry/nope-sql

この記事によくまとまってますが、データベースの費用は無視できません。LambdaやCloud Run, Vercelや Cloudflare Workers のように実行/ビルド環境は無料枠で十分使えることが多くなってきましたが、多くのRDBはかなり高価です。

マネージドRDBは基本的に操作が0でも動いてるだけで課金されるものが多いです。
Googe Cloudの場合、最低でも月額20USDは超えます。円安を踏まえると計算上1年で3万円を余裕で超えるため、個人開発では厳しいレベルです。
https://cloud.google.com/sql/pricing

一方でドキュメントDBの場合、操作や保管した分だけ課金されるものが多く小規模な使い方ならRDBより圧倒的に安価になります。
https://cloud.google.com/firestore/pricing?hl=ja

データの整合性はプログラム側で十分確保できる

RDBの最大のメリットはデータに制約をかけることができる点です。これによりデータベースが不整合な状態になることを防げますが、根本的な話をしてしまうとプログラム側でのバリデーションで個人開発では十分なレベルの整合性を確保できます。
またRDBを使っていたとしても、セキュリティなどの観点からデータのチェックをデータベースのみに依存するのは不適切です。実際問題としていくらデータベース側で整合性が保たれていても、オブジェクトストレージや外部サービスとの整合性は自力で確保する必要があります。
もちろん最後の砦としての役割は大きいですが、業務で使ってる場合でないならコストをかけてまで実現する必要があるとはあまり思っていません。

ORMへの依存問題

RDBを使う場合、SQLインジェクションの防止や型の安全性を確保するためORMを使うことが多いです。
問題は一回ORMに依存してしまうと移行が難しいこと、複数の言語で同一のデータベースを参照するのが困難になる点です。(一時期PrismaがRustやGoからも使えましたが、Prisma側がTypeScriptで完結するようになったので不可能になりました。)

特に後者はCloud Runで定期的にデータを更新してNext.jsで参照したい、といったかなり基本的なケースで問題になります。

ドキュメントDBは安い、無料枠がある

ドキュメントDBの無料枠だとAWSのDynamoDBが有名ですが、他にもあります。
MongoDBは開発元がMongoDB Atlasというマネージドサービスで割と使える無料枠を提供しています。
また最近になって寛大な無料枠を持つFirestore(Google Cloudの外部からもアクセス可能)もMongoDBクライアントから呼び出せるようになりました。
https://docs.cloud.google.com/firestore/mongodb-compatibility/docs/overview?hl=ja

https://cloud.google.com/firestore/enterprise/pricing?hl=ja

特にFirestoreの無料枠はプロジェクトごとに独立している上に、マルチリージョンなども使えるの非常に優秀です。
また仮に無料枠を超えた使い方をするとしても、RDBと比べて非常に安く使えます。

ドキュメントDBの欠点

ここまでメリットだけ挙げてきましたが、もちろん欠点もあります。
メリットとデメリットのトレードオフ(とその補償方法)をどうするかは考える必要があると思います。

  • スキーマがない
    • マイグレーションが不要というメリットでもある
    • データの整合性は自力で頑張る必要がある
  • 結合操作ができない
    • NoSQLな設計を習得する必要がある

その他ソリューション

マネージドRDBの無料枠を使う

Azureには実はSQL Serverの無料枠が存在します。
https://azure.microsoft.com/ja-jp/products/azure-sql/database

CockroachDBなど一部のマイナーなサービスも無料枠を提供しています。
https://www.cockroachlabs.com

名前があまりにも使う気になりませんが意外と優秀です

SQLiteを使う

Litestreamを使えばサーバーレス環境でも永続化できるらしいですが、複数クライアントから書き込みできないのであんまりお勧めしません。

RDBをVMやVPSにデプロイする

マネージドRDBは使えなくなりますが自力で建てると安く済みます。Google Cloudだとe2-microが無料で使えるので小規模な使い方ならありかもしれません。
https://qiita.com/kyogom/items/89eb60c3c98a3087df4a

ただVPSの場合HTTPリクエストを処理するサーバーからのアクセス方法が問題になる上に、バックアップなどは全て自力で管理する必要があります。
システムを全てVPSで動かしているなら問題ありませんが、サーバーレスでできるようなCI経由のデプロイなどは基本的にできなくなります。
管理が面倒な上に高品質なVPSを使うとなると結局コストがかかってくるので、あまりおすすめできません。

Discussion

acomaguacomagu

今のMongoはトランザクションもあるしjoin(aggregate)もあるから優秀なんですよねえ

3