こんにちは、新卒エンジニアの川本です。
BUYMAのサーバーサイドを中心に開発しています。
この記事はEnigmo Advent Calendar 2022の12日目の記事です。
データモデリングについて学習中で、DB設計の入門書を読んで論理設計について第1~5正規化といった内容を学習しましたが、いざ個人開発でデータモデリングしようとしたらどうしたらいいのかよくわからず、手を動かすことはできませんでした。
そんな状況の時にイミュータブルデータモデリングというモデリング手法について知ったことをきっかけけに、データモデリングがイメージしやすくなりました。
この記事ではイミュータブルデータモデリングを実践してみて感じたことを紹介できればと思います。
目次
データと情報の違い
データと情報には以下の違いがあります。
この違いから正確な情報が必要ならデータが正確に記録されていなければならないことがわかると思います。
イミュータブルデータモデリングとは
イミュータブルデータモデリングとは、データを失わずにRDBに正確に記録できるように、更新と削除がなるべく起きないようにデータモデリングすることです。
更新と削除が起きるということは、データが変更された、失われたということです。 つまり、正確なデータをすべてRDBに記録できていないことになり、必要な情報を抽出できない可能性が出てくるということです。
イミュータブルデータモデリングの手順
ここでは、イミュータブルデータモデリングを実践したことで、正規化について理解が深まった瞬間があったので例を交えて紹介できればと思います。
詳しい手順が知りたい方は以下の記事がすごくわかりやすいです。 scrapbox.io
エンティティはイベントとリソースにに分類される
分類の判断には、エンティティが日時属性を持つかどうかで判断できます。 日時属性を持つエンティティはイベントエンティティに分類されます。
エンティティに対して、「~する」という動詞をつけてみると識別しやすいです。 例えば「会員する」という日本語は不自然ですけど、「注文する」という日本語は自然です。 ここから注文はイベントエンティティで会員はリソースエンティティであることがわかります。
今回はこのイベントエンティティについて少し深ぼって説明していきます。
イベントエンティティには日時属性を1つだけ持つようにする
イベントは1つの日時属性を持ちます。 例えば、注文エンティティなら注文日時を持ちます。
ここで以下のような設計の注文テーブルがあったとします。
上記の注文テーブルは、注文日時の他に請求日時、入金日時、更新日時を持ってしまっています。 これはこの注文テーブルの中に、以下の異なるイベントが混在していることを示しています。
- 請求
- 入金
これらは別のイベントエンティティである請求エンティティ、入金エンティティとして分解することができます。
そうすると以下のように設計することができます。
こうすることで、請求や入金が発生しても注文テーブルをUPDATEする必要なく、それぞれのテーブルへのデータのINSERTのみでデータを記録することができます。
ここまでの流れは実はOne Fact in One Place(1つの事実は1つの場所に)という正規化の行為そのものとなっています。
第1~5正規化を意識しながら初学者が正しく正規化するのは難しいと思いますが、ここまで紹介した手順だとまだイメージがつきやすいのではないでしょうか。
普段Railsで開発していて感じたこと
Railsで普段開発をしていると更新日時をもたないことは違和感があるかもしれません。
Railsでscaffoldすると更新日時カラム(updated_at)が自動で入ると思います。
order(注文)リソースをscaffoldする。
$ rails g scaffold order amount:integer
自動的に作成日時(created_at), 更新日時(updated_at)が入る。
# == Schema Information # # Table name: orders # # id :bigint not null, primary key # amount :integer not null # created_at :datetime not null # updated_at :datetime not null # class Order < ApplicationRecord end
これはRailsがWEBシステムで必要なのは、最新のデータだけであるという制約を設けていて、UPDATEが起こること前提の設計になっているからだと思われます。
この強い制約を設けることでUPDATEやDELETEを許容する代わりに、たいていのことはデータベースと1対1となったModelのCRUDで表現できるというシンプルさを手に入れることができます。
Modelに書くことができず、Serviceクラスが肥大化したりするのはデータモデリングの設計が悪い可能性が高いそうです。
このあたりは以下のPodcastで詳しく説明されているので、聞いてみてください。 anchor.fm
イミュータブルデータモデリングとの向き合い方
イミュータブルデータモデリングで考えると、イベントをエンティティとして捉えることからエンティティの数も増え、INSERTのみで記録することからデータ量も増えます。
そうすると、論理設計の段階では問題なかったかもしれませんが、いざ物理設計する際に実装を考慮するとパフォーマンスの問題に直面することもあるかと思います。
イミュータブルデータモデリングはデータモデリングにおける正解ではなく、一種の論理設計をする際の制約として捉えるといいと思います。
考え方としては以下のような順番かと思います。
最後に
イミュータブルデータモデリングはデータモデリングにおける正解ではなく、一種の考え方です。
私のように初学者でデータモデリングに対して苦手意識がある人は一度イミュータブルデータモデリングについて調べて実践してみるといいかもしれません。
興味がある人は、WEB+DB PRESS Vol.130のデータモデリング特集を面白いので読んでみてください。 gihyo.jp
こちらの楽々ERDレッスンという書籍も実践的な内容が多くおすすめです。 www.shoeisha.co.jp
明日の記事の担当は インフラエンジニア の 山口 さんです。お楽しみに!
株式会社エニグモ すべての求人一覧