データベースを参照してシステム連携する際に気をつけること

データベースを直接参照するシステム連携は、おそらく多くの人が経験したことがあるものだと思う。
そして多くの場合、それはつらい記憶とともに思い起こされるものだと思う。

…ということで、データベースを直接参照するシステム連携方式について、考えをまとめておく。

基本的な考え方

原則として他システムのデータベースを直接連携することはできるだけ避け、APIなどで連携したほうがよいと考える。
その理由は以下の2つが挙げられる。

  • DBへのアクセス頻度や負荷を考慮する必要があり、チームで性能の担保が難しくなる
  • テーブル定義が外部仕様となることで、テーブル定義の変更がチーム内で完結できなくなる場合がある

しかし以下のように、DBを直接参照することでシステム連携したくなる場合がある。

  • 大量のレコードをシステム間で連携する必要がある場合
  • 検索システム等がDBへの接続を標準的にサポートしている場合

データベースを直接参照する場合に考える2つの観点

観点①:性能品質の担保

外部のシステムがDBを直接参照する場合、その頻度や負荷を把握するのが難しくなる。
例えば複雑なクエリに変更されたり、クエリの実行頻度を上げられた場合、DBの性能が不足する可能性がある。
また検索システムが標準的にDBへの接続をサポートする場合は、どのようなクエリがどのような頻度で発生するかを想定することも難しい場合がある。

クエリや実行頻度を変更するたびに性能評価を行うアプローチや、DB負荷を監視しておくことの重要性は否定しない。
しかし現実的にはチーム間でコミュニケーションを取って性能評価を行うコストは低くない。
また各チームでDB負荷を監視する枠組みを用意したとしても、性能問題が評価環境で発見できるとも限らない。1

観点②:内部仕様と外部仕様の分離

DBのテーブル定義は、アプリケーションやシステムとしては内部仕様であることが多い。
そして内部仕様であるならば、チーム内で変更が完結できることが重要である。
しかしDBのテーブルを外部システムが参照するということは内部仕様(テーブル定義)が外部仕様(システム間連携で用いるインタフェース)に昇格するということであり、そのテーブル定義は容易に変更できなくなる。

システム間連携の当事者メンバーは認知しているが、メンバーが入れ替わると認知されなくなるケースも少なくない。
それを考えると、外部システムには専用のビューを用意するなどして、これをインタフェースとして用いるのが好ましい。
そうすれば、ビューで返ってくるデータ形式が維持できる限り、テーブル定義をチーム内で自在に変更することが可能となる。

データベースを直接連携する際の実現方式

方式①:PostgreSQLのマテリアライズドビューを使う

PostgreSQLのマテリアライズドビューを使うことで、性能品質を担保しつつ、外部仕様・内部仕様を分離させる。
マテリアライズドビューはキャッシュが存在するビューであり、その更新タイミング・頻度も指定することができる。
つまりDBへの負荷がコントロールできるため、性能品質をチーム内で担保しやすくなる。

また専用のビューを用意することで、内部仕様と外部仕様の分離も両立できる。

方式②:リードレプリカ+ビューを使う

マテリアライズドビューが利用できないDBであっても、リードレプリカとビューの併用でカバーすることができる。

AWSにおけるRDSやAuroraなど、マネージドなデータベースサービスであればリードレプリカは簡単に用意できる。
外部のシステムはリードレプリカを通じて参照するようにすれば、負荷が増大した場合でも障害の影響範囲を抑えることができるし、性能面についてはコントロールしやすくなる。

そして外部システムで参照したいデータはビューを用いて定義することで、システム間のインタフェースとすればよい。
こうすることで、内部仕様・外部仕様を分離することができる。


  1. 評価環境だとデータ数が少なくて性能問題が発見できならなかった、というケースがある ↩︎

関連記事


  1. DDLを自動生成してJavaと各DBのデータ型を比較してみた
  2. Oracle 11でSELECT文の実行結果をCSV/TSV出力する
  3. Spring BootアプリにFlywayを導入してみた
  4. Spring Data JPAのEntityクラスからDDLを生成する
  5. JavaサーブレットでSQLiteを使う場合のパス指定方法

comments powered by Disqus