SaaSデータベースアーキテクチャの設計

最初の1週間に行う誤ったデータベースの決定は、その後何年もの間、あなたを苦しめることになります。

SaaSの創業者には、マルチテナンシー、課金、そして成長に対応できるスキーマが必要です。設計を誤ると、半年後にはシステム全体を書き直すことになります。

以下に、本番環境に耐えうるスキーマの構築方法をまとめます。

1. テナント戦略の選択

顧客間でデータを分離しなければなりません。

行レベル (Shared DB): 低い複雑性。ほとんどのスタートアップに最適。すべてのクエリに WHERE organization_id = ? フィルタを使用します。 • スキーマレベル (Separate Schemas): 中程度の複雑性。規制要件への対応に適しています。 • データベースレベル (Separate DBs): 高い複雑性。エンタープライズクライアントに最適です。

新規プロダクトの90%において、行レベルのマルチテナンシーが正しい選択です。

2. 正しいエンティティ階層

ユーザーに直接課金してはいけません。ユーザーは入れ替わりますが、組織は存続します。

階層は以下のようになるべきです: User ── MemberOf ── Organization ── Subscription ── Invoice

Users: このテーブルは識別のみに使用します。攻撃を防ぐためにUUIDを使用してください。 • Organizations: これがテナントの境界となります。サブスクリプションは常に組織に紐付けてください。 • Memberships: ユーザーと組織を紐付けるために中間テーブル(join table)を使用します。ロール(役割)はユーザーテーブルではなく、ここに保存してください。

3. 課金とサブスクリプション

is_active のような単純な boolean 型は決して使用しないでください。データが混乱する原因になります。

サブスクリプションにはステートマシンを使用してください。一般的なステートには以下が含まれます: • trialingactivepast_duecanceledexpiredincomplete

これにより、手動でのデータ修正を行うことなく、支払いの失敗や猶予期間(grace periods)を処理できるようになります。

4. 金銭と請求

金銭的なエラーを避けるため、以下の厳格なルールに従ってください:

• 金銭に対して FLOATREAL は決して使用しないでください。セント単位を保存するために整数(integer)を使用します。例えば、$29.99 は 2999 となります。 • invoice_line_items テーブルを使用してください。税務報告や返金にこれが必要になります。 • 顧客のプロダクト利用量に基づいて課金する場合は、usage_events テーブルを使用してください。

5. パフォーマンスのヒント

• 外部キーにインデックスを貼る。 • ステータス列にインデックスを貼る。 • タイムスタンプ列にインデックスを貼る。 • N+1 クエリを避ける。JOIN を使用して、1回のクエリで組織とサブスクリプションのデータを取得するようにします。

優れたスキーマは、機能しているときは意識されることがありません。しかし、失敗したときには壊滅的な影響を及ぼします。

組織(Organization)のために構築してください。ステートマシンを使用してください。お金は整数として保存してください。

Source: https://dev.to/feidou/designing-saas-database-architecture-users-organizations-subscriptions-and-billing-df

Optional learning community: https://t.me/GyaanSetuAi