DBの寿命はアプリより長い! 長生きするDBに必要な設計とリファクタリングを実践から学ぶ
アプリケーションの寿命よりも長く、データの追加やテーブルの変更で成長し続ける「データベース」と、どのように付き合っていけばよいのでしょうか? 曽根壮大(soudai)さんによる寄稿です。
こんにちは。そーだい(@soudai1025)です。
新しいサービスを始めるとき、必ずと言っていいほどデータベースは利用されています。また今稼働しているサービスの多くでも、RDBMSをはじめ、いろいろなデータベースが利用されています。そんなに広く利用されているデータベースだからこそ、多くの問題の元になるのもまた事実です。
そこで今回は、Webサービスを中心にデータベースの選び方、設計についてお話していきたいと思います。そして私もまさに今、2011年から続くWebサービス「オミカレ」のRDBMSのリファクタリングに携わっており、その経験も余すことなくお伝えします。
DBの寿命はアプリケーションより長い
一番最初にお伝えすべきことは、データベースの寿命はアプリケーションよりも長いということです。これはどういうことでしょうか?
想像してみてください。例えば、新しくSNSのサービスをリリースしたとします。このSNSは1年、2年と順調にユーザー数を増やしていきます。そして、獲得したユーザーをより活用するため、新たにECサービスをローンチしたとしましょう。
このECサービスがリリースされた瞬間から、SNSの会員データはECサービスと共有されることになります。
このように同じデータベースを複数のアプリケーションから参照することは一般的ですし、例えばRDBMSを利用していればトランザクションを備えていますし、適切なユースケースと言えるでしょう。
さて、ECサービスが順調に拡大してきたころ、流行(はや)り廃りもあってSNSを閉じることになりました。そうなるとデータベースはどうでしょうか? 共に生まれ育ったSNSが閉じても、ECサービスから会員情報を参照されているため、閉じることはありません。
このように複数のアプリケーションから参照されることも、そしてアプリケーションよりもデータベースの寿命が長いことも、一般的なことなのです。
アプリケーションのリプレースとDBのリプレース
データベースの寿命を考えるには、もう1つ良い例があります。
ECサービスをリプレースしたいと考えたとき、アプリケーションコードを捨てて、全て新しく実装することはあり得るでしょう。しかし、データベースはどうでしょうか? 中身のデータを全て捨てて、新しく作り直すことはまずないでしょう。
ハードウェアであれば故障や定期交換で新しくなることがありますし、OSやプログラミング言語はバージョンアップが定期的に行われます。特にプログラミング言語のバージョンアップの際には、合わせてリファクタリングを行うこともあるでしょう。
では、データベースはどうでしょうか? ミドルウェアのバージョンアップをすることはあっても、リファクタリングまでされた経験がある方は、読者の方の中でも少ないのではないでしょうか。もちろんデータを捨てて、新しいデータベースを構築することはまずありません。
このように、データベースは寿命が長いからこそ巨大になりやすく、また変化に対する恐れが生まれやすいのが特徴です。
複数のアプリケーションから参照される場合
先程、SNSとECサービスを例に挙げましたが、複数のアプリケーションから参照されるケースは他にもあります。
例えば、SaaSやPaaSとの連携です。あなたが使うサービスが、スマホのプッシュ通知をSaaSを使って実装していた場合、プッシュのリストを連携する必要があります。
また、サーバレスアーキテクチャやマイクロサービス化していけば、その傾向はより顕著になることでしょう。インターフェイスとしてREST APIがあったり、各々のデータストアはあるとしても、共通のデータストアは必要だからです。そして、その多くの共通のデータストアの中に、RDBMSをはじめとするデータベースがあることでしょう。
その他、データ分析基盤にも昨今はSaaSを利用することが一般化していますし、複数のアプリケーションでデータを共有する仕組みは、いろいろな場所で発生します。
0から1にするときのDB設計
このように、データベースはさまざまなところで使われるため重要な存在ですし、だからこそデータベースの問題が多くのサービスに影響します。みなさんも、パフォーマンスチューニングなどで困った記憶があるのではないでしょうか。では、どうしてそのような状態になるでしょうか?
その理由は、データベースの特性にあります。基本的にデータベースにはデータが追加されていきますし、データの状態を変える作業の多くも、テーブルやカラムの追加です。もちろん更新や削除もありますが、参照を除くデータベースの状態の変化の多くは追加で行われるため、まさにデータベースが成長していくのです。
そして5年、10年という長いデータベースの寿命とその特性が噛み合って、巨大なデータベースが生まれるのです。
仕様追加に強い設計
それでは、どうすれば仕様の追加に強いデータベースを作ることができるのでしょうか?
データベースの設計は積み木に例えられます。例えば次の図のように、最初の設計から正しく設計されていたなら、次に行われる仕様の追加もしやすくなります。このように正しく設計していけば、追加はそれほど難しいことではありません。
builderscon 2017登壇資料「rdb antipattern refactoring」25ページより
しかし、次のような形になっていたときはどうでしょう? 次に乗せる仕様が難しいことは、一見してわかりますね。
同じく「rdb antipattern refactoring」27ページより
さらに、この上に丸を乗せる天才が現れた日には、後のメンテナンスが地獄絵図になることは容易に想像できます。しかし、このような状態は残念ながら散見され、アンチパターンと呼ばれたり、悪い設計として存在しています。
それでは、正しく設計し、積み木を載せていくにはどうすればよいのでしょうか?
データと情報の違い
正しい設計の答えは、残念ながらありません。しかし、正しい答えに近づくための手法はいくつかあります。その上で重要なことは、まずデータと情報の違いを知ることです。
データは、ありのままの事実です。そして情報は、表示したい内容に合わせてデータを加工した結果です。
例えば、ユーザー情報の中に「生年月日」があったとします。これはありのままの事実、データです。それでは、ユーザープロフィールに「年齢」を表示したい場合はどうでしょうか? 皆さんのお気づきの通り、年齢は生年月日を加工した情報なのです。
年齢も事実だと思われるかもしれませんが、毎年カウントアップされ、変化します。それに対して、生年月日は変化しません。これが、データと情報の大きな違いの1つです。
名著『SQLアンチパターン』日本語版(オライリージャパン、2013年)のまえがきでも、監訳者の和田省二さんが次のように書いています。
さて、皆さんは「情報」と「データ」の違いをご存知でしょうか。この二者の関係は「多くの情報を秘めた貴重なデータ」という表現で言い尽くせます。いつでも我々が欲しいのは、意味のある(目的を持った)正しい情報なのです。一方、データは単なる各種の事実の値(何らかの、名称とか日付とか金額とか)であってそれ自体に目的はありません。
みなさんにも、この違いが見えてきたと思います。 つまり、データベースに保存するべきなのはまさにデータ、事実を保存することが重要なのです。
データモデリングを最初にする
それでは、データをどのように保存していくか? そのためには、まずデータモデリングすることが大事です。
データモデリングの主な目的は、データの定義し、フォーマットを決めることです。データモデルには、3つの段階があります。
- 概念スキーマ
- 事業ルールや業務データなどを抽象化して、エンティティとして定義する
- 論理スキーマ
- テーブルおよびカラムの場合はER図、オブジェクト指向クラスなどの場合はUML図などで表現して定義する
- 物理スキーマ
- 実際に利用するミドルウェアなどに合わせて定義する
冒頭でデータモデリングしましょうと説明しましたが、まずは概念スキーマの部分から始めます。データモデリングでは、現実世界のデータをエンティティに分けていくことで、どのように関連付けていくか整理することができます。
それによって、RDBMSならリレーショナルモデルにそって論理スキーマを設計し、正規化していくことになりますし、リレーショナルモデルが難しいデータモデル、例えばツリーやグラフなどは、RDBMS以外のデータストアを検討することになります。
このようにデータモデリングすることで、どのデータを、どこに、どのように保存していくかということがハッキリします。
このとき、情報を保存してしまったり、リレーショナルモデルが苦手なデータモデルをRDBMSに保存したり、逆にリレーショナルモデルにすべきところを疎かにしてしまうと、後々に響く設計になってしまいます。
この話は、今年のbuildersconでさせていただきました。
RDB THE Right Way ~壮大なるRDBリファクタリング物語~ - builderscon tokyo 2018
RDBMSとNoSQLの使い分け
続きをお読みいただけます(無料)。

- すべての過去記事を読める
- 過去のウェビナー動画を
視聴できる - 企業やエージェントから
スカウトが届く