The following two tabs change content below.
アバター画像

メンバー

福岡市博多区でWebシステム開発の受託・ラボ型SES・web集客サービス、3つのWebサービスを提供中

Webエンジニアのあなた、Webエンジニアを目指しているあなた、データベース設計で

・頭を悩ませたこと

・有限な時間を悲しくなるほど失ったこと

・顧客や仲間に大迷惑をかけたこと

ありませんか?

私がWebアプリ開発を始めた頃、データベース選択に悩んだ経験は今でも鮮明に覚えています。
初めての大規模プロジェクトでは、どのデータベースが最適か判断できず、結果的に途中でデータベースの再設計が必要になり、貴重な時間とリソースを浪費しました。


この苦い経験から学んだRDBNoSQLの特徴と選択基準について、今回の記事ではお届けします。

本記事でこれから紹介する内容は、皆さんがプロジェクトの要件に最適なデータベースを選択し、効率的な開発を行うための道標となるでしょう。データベース設計の悩みを解消し、スキルアップにつながる知見を、この機会に吸収されて、以前の私のように、貴重な時間とリソースを浪費されないようにお気を付けください。

RDBとは

リレーショナルデータベース(RDB)は、私がキャリア初期に最初に触れたデータベースタイプです。顧客管理システムを開発した際、データの一貫性と関連性の維持が重要だったため、RDBを選択しました。

RDBは、データを行と列からなるテーブル形式で整理することで、データ間の関係明確に定義できます。各テーブルは特定のエンティティ(顧客、商品など)を表し、主キーと外部キーによって関連付けられます。

RDBのもう一つの重要な特徴は、ACID特性(原子性、一貫性、独立性、永続性)です。あるECサイト開発では、決済処理中にシステム障害が発生しても、トランザクションの一貫性が保たれ、データの不整合を防ぐことができました。これにより、特に金融や決済システムのようなトランザクションの整合性が重要な分野で信頼性が高まります。

RDBの種類

RDBの種類として、MySQL、PostgreSQLについてそれぞれ紹介していきます。

MySQL

私が最初に使用したRDBはMySQLです。中小規模のWebアプリケーション開発プロジェクトで採用しました。MySQLは導入・運用が比較的簡単で、多くのプログラミング言語との連携が容易です。また、活発なコミュニティサポートがあるため、問題解決がスムーズです。しかし、大規模データセットでのパフォーマンス低下が課題となることがあります。さらに、特定の高度な機能は有料版でのみ提供される場合もあります。

PostgreSQL

複雑なプロジェクトでは、より高度な機能が必要となり、PostgreSQLを採用しました。PostgreSQLは複雑なクエリ高度なデータ型のサポートが強みで、GISデータなど特殊データ型にも対応しています。また、拡張性信頼性が高く、多くの企業で採用されています。ただし、MySQLよりも多くのリソースを要するため、サーバーのスペックが重要となります。また、設定や最適化がやや複雑であるため、初心者には敷居が高いかもしれません。

NoSQLとは

キャリア中期に、従来のRDBでは対応が難しい課題に直面しました。特に、大量の非構造化データや高いスケーラビリティが必要なプロジェクトです。そこでNoSQL(非リレーショナルデータベース)を採用しました。

NoSQLは固定スキーマに依存せず、柔軟なデータモデルを提供します。
あるソーシャルメディア分析プロジェクトでは、様々な形式のユーザーコンテンツを効率的に格納するためにNoSQLを選びました。

NoSQLの主な利点は水平スケーラビリティで、負荷増大時に新しいサーバーを追加するだけで容量拡張できます。また、スキーマレスなため、データ構造の変更が非常に容易です。これにより、迅速な開発サイクルが可能になり、特にアジャイル開発に適しています。

NoSQLの種類

NoSQLの種類として、MongoDBとRedisを紹介していきます。

MongoDB(ドキュメント指向データベース )

最初に使用したNoSQLはMongoDBでした。MongoDBはJSONライクなドキュメント形式でデータを格納します。柔軟なスキーマでデータ構造の変更が容易であり、階層構造データに特に適しています
また、開発サイクルの短縮が可能で、初期段階での迅速なプロトタイピングに役立ちます。ただし、複雑な結合操作が苦手であり、トランザクションサポートが限定的であるため、トランザクションの整合性が重要なプロジェクトには不向きです。

MongoDBの制限レベルは以下の通りです。

(1)基本的な等価結合のみをサポートしており、複数の条件による結合や複雑な結合条件の実装が困難です。

(2)大規模なデータセットでの結合操作は非常にコストがかかり、クエリ実行時間が遅くなる傾向があります。

(3)条件付き結合やサブクエリはサポートされていますが、SQLほど直感的でなく、複雑な構文が必要です。

(4)結合操作($lookup)には100メガバイトのメモリ制限があり、これを超える場合はディスクを使用するため、パフォーマンスに影響を与える可能性があります。

(5)複数のコレクション間の複雑な関係多段階の結合を必要とするクエリは、MongoDBでは効率的に処理できません。

これらの制限により、複雑な関係を持つデータモデルや、多数のテーブル間の結合を必要とするアプリケーションでは、MongoDBの使用が適していない場合があります。

↓私が参考にしたMongoDB公式ドキュメントがこちらです。
スキーマ設計プロセス: https://www.mongodb.com/docs/manual/data-modeling/schema-design-process/
データモデリング: https://www.mongodb.com/docs/manual/data-modeling/

Redis(キーバリューストア)

リアルタイム分析や高速キャッシュが必要なプロジェクトではRedisを活用しました。Redisは非常に高速な読み書きが可能で、シンプルで効率的なデータモデルを提供します。
特にメモリ内処理により、低レイテンシが実現され、リアルタイム処理に最適です。

しかし、Redisは、複雑なクエリには不向きです。Redisが複雑なクエリに不向きな理由は以下の5点です。

(1)基本的なクエリ機能の制限:Redisはキーバリューストアとして設計されており、SQLデータベースと比較して複雑なクエリのサポートが限られています。広範なスキャンや結合操作などはRedisの得意とするところではありません。

(2)リレーションシップモデリングの難しさ:Redisではリレーションシップをモデル化することが困難です。内部的な全文検索サポートがなく、データ間の関係性を表現するのが難しい構造になっています。

(3)集計機能の欠如:合計、平均などの集計関数はサポートされておらず、クライアント側で処理する必要があります。

(4)インデックスのサポート制限:インデックスは内部的にサポートされておらず、回避策として「セット」を使用できますが、手動でのメンテナンスが非常に複雑になります。

(5)クエリ言語の欠如:Redisはクエリ言語をサポートしておらず(コマンドのみ使用)、リレーショナルデータベースのようなアドホッククエリのサポートがありません。

また、Redisではデータサイズがメモリに制限されるため、次の理由から、大量データの永続保存には不適切です。

(1)Redisは主にキーバリューストアとして設計されており、広範なスキャンや結合操作などの複雑なクエリ操作はRedisの得意とするところではありません。

(2)Redisはインメモリデータベースでメモリに依存するため、保存できるデータ量は利用可能なRAMに制限されます。よって、データセットが大きくなるにつれて、必要なRAMのコストが高くなり、データセット全体のスキャンなどの操作が非効率になります。

そのため、以下が不適切な使用例です。

  • 大規模なトランザクションデータの長期保存
  • 継続的に増加する履歴データの保存
  • 高可用性と耐久性が必要な重要なビジネスデータの保存
  • データサイズが急速に増加するアプリケーション

↓私が参考にしたRedis公式ドキュメントがこちらです。
 Redis ドキュメント: https://redis.io/docs/latest/

BigQueryとは

最近のデータ分析プロジェクトでは、Google CloudのBigQueryを使用する機会が増えています。

あるeコマースプラットフォームでは、数テラバイトの顧客行動データを分析するためにBigQueryを導入しました。

BigQueryの主な特徴は、ペタバイト規模のデータも高速処理可能なスケーラビリティです。また、サーバーレスアーキテクチャにより、インフラ管理の負担が軽減され、自動拡張が可能です。

さらに、標準SQLに対応しているため、馴染みのあるSQLで操作が可能です。コラム指向ストレージにより、分析に最適化されたデータ構造を提供しています。

私の経験では、BigQueryのツリーアーキテクチャにより、複雑なクエリも数秒で処理できる点が非常に印象的でした。また、Google Cloudの他のサービスとの連携も非常にスムーズで、データ分析プロジェクトでは欠かせないツールとなっています。

RDBとNoSQLの違い

実務経験から、RDBとNoSQLの違いと適材適所を強く実感しています。

RDBは、データモデルとして表形式の関連データを提供し、事前定義された厳格なスキーマを持ちます。これにより、データの一貫性と整合性が保証され、特にトランザクション処理が重要な金融や決済システムに適しています。ただし、大規模データセットでのパフォーマンス低下垂直スケーリングへの依存が課題となります。

一方、NoSQLは多様なデータモデルを提供し、柔軟または動的なスキーマを持ちます。これにより、非構造化データや半構造化データを効率的に格納でき、特にリアルタイム分析大規模データ処理に適しています。また、水平スケーリングが可能で、負荷増加に対応しやすいです。

RDBの適用例としては、トランザクションの整合性が重要な金融アプリケーションや、データ構造が明確な業務システム、複雑な関係と詳細なレポートが必要なCRMシステムなどがあります。私が開発したある決済システムでは、トランザクションの整合性を保証するためPostgreSQLを選択しました。

NoSQLの適用例としては、リアルタイムのセッション管理(Redis)、大量センサーデータを扱うIoTアプリケーション(Cassandra)、柔軟なスキーマが必要なCMS(MongoDB)などがあります。IoTプロジェクトでは、数百のセンサーからのデータストリームを効率的に処理するためCassandraを採用し、スケーラビリティの高さを実感しました。

最後に

データベース選択は、プロジェクトの要件によって大きく左右されます。

RDBを選択すると良いプロジェクト要件

データの整合性と関係が最重要な場合

複雑なトランザクションとデータ結合が必要な場合

・データ構造が安定している場合

です。

NoSQLを選択すると良いプロジェクト要件

非構造化/半構造化データを多く扱う場合

・極めて高いスケーラビリティが必要な場合

柔軟で変化するデータスキーマがある場合

です。

BigQueryを選択すると良いプロジェクト要件

・大規模データ分析が主目的の場合

・インフラ管理の負担を減らしたい場合

・他のGoogleサービスと連携したい場合

です。

余談

私の最近のプロジェクトでは、

・トランザクション処理にRDB

・セッション管理にRedis

・大規模分析にBigQuery

と用途に応じて複数のデータベースを組み合わせています。

データベース選択で悩んだら、まずは要件を明確にし、必要に応じてハイブリッドアプローチを検討することをお勧めします。