はじめに
最近ハッカソンで初めてちゃんとDB設計をしました。開発したアプリ自体は必要最低限の機能に絞っていたので複雑な設計ではないのですが、個人的に学ぶ事が多かったので感想ベースで備忘録としてまとめます。
「初心者がDB設計しようとするとこうなる」みたいな一つの例として参考になれば幸いです。
アプリの基本機能
アプリ概要
大学内での豆知識共有サービス。アプリの性質的には掲示板かSNSに近い。
DBに関わる主な機能
- 豆知識の投稿(タイトル、本文、カテゴリ選択)。本文はNULL許容。
- 豆知識の削除
- 他人の豆知識に対するいいね
- ログイン/ログアウト
- 自分がされているいいね数でランクが上がる
詰まった点
良いね数によるランク変化の表現方法
方法としては
- usersテーブルに良いね数カラムを作って、「AさんのユーザーIDに紐づく豆知識」が豆知識テーブルに新たに挿入される度に、usersテーブルのAさんの良いね数カラムが加算され、その値をレスポンスする方法
- いいね数カラムは概念スキーマ内に作らず、リクエストがくるたびに豆知識テーブルにあるAさんの豆知識の数を一覧取得しレスポンスする方法
の2つを考えました。2個目の方法で良いね数が表現できる時点で、1個目の良いね数カラムは冗長的なデータとなると思います。そのため1個目の方法はDB設計的にあまり適さない方法ですし、豆知識挿入と良いね数加算は同時に行う操作なので、整合性を取るために同一トランザクションに含める必要があり、Typesccriptでのトランザクション管理の学習コストが発生しますが、今回のハッカソンでは概念実証的な感じで開発していたので、「良いね数カラムがあった方がわかりやすいし多少の非整合性は許容してコア機能の開発をしよう」ということで1個目の方法を選びました。
ただ、遅いと言われるJOINを豆知識テーブルを使って算出した良いね数に対して使うことも無さそうなため、あえて良いね数カラム作って非正規化させるメリットもないですし、今思うとそこまで良いね数カラムを設けても嬉しい開発体験は生まれなかったので最初から冗長性は無くしても良かったと思いました。そのため今後はその部分を修正する予定です。
↑はDB設計の概要をチームメンバー用にドキュメントとしてまとめたものなのですが、ドキュメントとしてまとめると後から当時自分考えていたことを思い出せるので自分にとっても嬉しいことが多く積極的にやるべきだなと感じました。学んだ点
中間テーブルの概念
良いね数という概念で中間テーブルに触れられたのでとてもいい経験になった。
今後の方向性(余談)
テーブル構造の今後の変更としては以下
- 上述した良いね数カラムの削除
- カテゴリーは一般ユーザーは干渉できず管理者だけが操作できる存在にしているのですが、現状管理者画面は未実装で管理者権限での豆知識カテゴリーの追加編集削除等はできないので、それができるようにcategoriesテーブルにuser_idというカラムを追加し、そのuser_idにusersテーブルのidを参照する外部キーを設定するなどして管理者画面上でUIでカテゴリーを管理できるようにする予定です。
- 最近Goを使って「豆知識毎にチャットルームを設け、チャットルーム内で豆知識についてリアルタイムでお話できる機能」を作っているのですが、SupabaseのDBとチャットというユースケース用のDBが独立してしまっているので、どうにかして2つのDB間で整合性を担保できるようにするか、Supabaseで行っている役割を全てGo側に置き換えるなどして対処する予定です。
参考
SQL 第2版: ゼロからはじめるデータベース操作
積読状態だったので読みました。いざSQLを書こうとすると自力で書けなかったので辞書的に読みました。知りたいSQL構文周辺の基礎知識を知れるのでとても助かりました。
達人に学ぶDB設計徹底指南書 第2版
今回のハッカソンのDB設計ではこちらの書籍に非常に助けられました。どういう設計がなぜ良くてなぜだめなのかが全然分からない自分からすると最高の書籍でした。まだ十分に読み切れていなかったり、意図を汲み取れていない部分もあると思うのでしっかり読んでいきたいです。
また、こちらの書籍の著者であるミック氏がX上でありがたすぎるDB周りのガイドマップを作成してくださっているので、今後はこれに沿って理解を深めていけたらなと思います。
Web API: The Good Parts
直接的にDB設計がしやすくなったという訳ではないのですが、API設計の概要を掴んでからDB設計するとアプリ全体のデータの流れをイメージしながらDB設計ができる気がしたので読んで良かったなと思います。こちらの書籍も全然読み切れていないのでしっかり読んでいきたいです。
さいごに
今後はより複雑な要件のデータモデリングも経験してみたいと思いました。