0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

拡張性のあるDB設計について(RDB)

0
Last updated at Posted at 2025-10-08

ガチ初心者向けです。

未来を見据えた設計をしよう

皆さんご存知の通り、DBは一度運用を始めてしまったら変更するのが難しくなります。
拡張性のないDBと言うのは、

  • アップデートのために新しいカラムを追加したいけど、追加したら既存のデータが壊れる
  • 仕様変更で画面に表示させたいデータがあるけど、何故かTABLEに存在しない (更新日、更新者など)

例えばブログの記事を格納するためのDB TABLEを作るとします。
↓の図を見て皆さん何か違和感を感じませんか?

image.png

このテーブルを使い続けた場合、カテゴリー名を変えたくなった場合困る可能性があります。
今は'グルメ'でありますがもし'グルメ感想'などに変えたくなった場合どうするんでしょう。
SQLのUPDATE文で全て変えるとしても実際にプロダクトとして運用しているDBでそれやるのはすごい危険ですしもし一文字でも誤字ったらやばいですよね。

なのでテーブルを増やしカラムを変えてみましょう

image.png

カテゴリーのマスターテーブルを作り、postsテーブルにはカテゴリーをForegin Keyとして持たせます。
これで正規化を実現する同時に、カテゴリー名を変更するハードルも低くなりました。

しかし、この設計ではまた違う問題が発生するかもしれません...

それはカテゴリーを複数選択したい時です。
以前
category = "1, 2, 3" みたいなstring値を保存して <,>で区切るようにすればいいのでは?
と仰る方とお会いしたことがありますが、DBはCSVではありません。
カテゴリー名に特殊文字を含むことが仕様として求められるケースもありますし、
検索機能を追加する際にフィルターを作ることが大変困難になります。

もしユーザーが後からid="2"のカテゴリーだけ外したくなったらどうするんですか?
もしカテゴリーがグルメの記事だけを検索したい時どうするんでしょう。
"1"を含めているかどうかで検索しますか? でもそれだとidが"11"のカテゴリーも検索に含まれる可能性ありませんか?

まあ関数のロジックちゃんと組めばこの設計でもなんとか実装はできますが、そもそも最初から設計ちゃんと綺麗にしていれば悩まずに済む問題なんですよね。

そこで次のような設計案になります。

image.png

postsとcategoryをFKとして持つテーブルで複数選択を管理します。
これだと記事にカテゴリーを何個でも選べますし、後からカテゴリーを外すのも可能です。
あと特定のカテゴリーだけ検索したい時もSQLのJOIN句で検索すればすぐ終わるので楽です。

テーブルが増えれば増えるほど管理が難しくなる、処理も遅くなると言うのは事実です。
それでも用途によってテーブルを別けた方がいいケースは沢山あります。

1つのテーブルで全部解決しようとしない、別けた方が良い時は別ける

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?