Upgrade to Pro — share decks privately, control downloads, hide ads and more …

手を動かしながら学ぶデータモデリング - 論理設計から物理設計まで / Data modeling

手を動かしながら学ぶデータモデリング - 論理設計から物理設計まで / Data modeling

Avatar for soudai sone

soudai sone PRO

November 14, 2025
Tweet

More Decks by soudai sone

Other Decks in Technology

Transcript

  1. 1. 座学 40分程度
 2. データモデリング ワークショップ
 a. 前半 20分 +

    解説 10分
 b. 後半 20分 + 解説 10分
 3. まとめ
 タイムテーブル

  2. 自己紹介
 曽根 壮大(41歳)
 Have Fun Tech LLC 代表社員
 株式会社リンケージ CTO

    兼 COO
 
 そ
 • 日本PostgreSQLユーザ会 勉強会分科会 担当
 • 3人の子供がいます(長女、次女、長男)
 • 技術的にはWeb/LL言語/RDBMSが好きです
 • コミュニティが好き たけ
 ね
 とも

  3. ここまでシンプルな実装を目指しましょうと強調してきました が、「シンプルな実装」とはなんでしょうか。RDBMSを使う上で シンプルな実装のヒントは正規化です。正規化のコツは次の ように表現できます。 
 • 事実だけを保存する 
 • 重複がない


    • 不整合がない
 • nullがない
 これらを意識して設計していくとシンプルな設計に近づいてい きます。
 また正規化を行う際はここまで説明したとおり、種別と状態を 考えることも重要です。ライフサイクルが違うデータは往々に して状態や種別が異なります。 場合によってはnullになるよう なカラムやUPDATEが必要なレコードは状態を持っている可 能性があります。こうしたテーブルが見つかった場合はより 深く考察する必要があります。 
 https://agilejourney.uzabase.com/entry/2022/07/28/103000
  4. そして最後にINDEXの数にも注目しましょう。主キーは必ずあ りますが、外部キー制約とユニーク制約を除いたINDEXは主 に検索のために必要なINDEXです。検索のWHEREの対象の 数だけそのテーブルの責務が大きいといえ、 4つ以上の INDEXが必要な場合も同じく深く考察する必要があります。 隠 れた状態をWHEREで絞り込んでいたり、種別をWHEREで絞り 込んでいるケースが見えてくることがあります。 


    このようにシンプルな設計を目指して考察を繰り返していくこ とが重要です。そして同じくらい重要なこととして認識すべき はイージーとシンプルは両立できる、ということです。 シンプ ルを目指し考察を繰り返すことがまさにデータモデリングであ り、変化に強い設計につながっていくのです。 
 https://agilejourney.uzabase.com/entry/2022/07/28/103000
  5. 概念スキーマ データモデリングの3層構造 外部スキーマ 内部スキーマ 論理スキーマ 物理スキーマ ユーザから見えている部分 概念データモデル 論理データモデル 物理データモデル

    概念データモデル 論理データモデル 物理データモデル ザックマンフレームワークの データモデル分類 上から下へ アプリケーションの画面やイン ターフェース
  6. イベント リソース 駐車場 車両 利用者 契約 入庫 出庫 予約 支払い

    時間に依存せず存在するモノ 住所 who(誰が) what(何が) what(何が) where(どこで) 概念をリソースとイベントにわけて列挙する

  7. イベント リソース 駐車場 車両 利用者 契約 入庫 出庫 予約 支払い

    発生した事実 住所 いつ、入庫した? いつ、支払いした? いつ、予約した? 概念をリソースとイベントにわけて列挙する

  8. 利用履歴 概念データモデル図の例
 駐車場 車両 利用者 契約 入庫 出庫 予約 支払い

    月極だった場合は 契約に紐づくのでは? 複数の車両の考慮は? 駐車枠のリソースが必要では? 予約の事実も利用履歴では?
  9. 1. 属性(アトリビュート)を洗い出す
 2. データの関係を明確にする
 a. 1:1なのか1:NのかN:Nなのか
 b. 参照方向の確定(依存の親子関係) 
 3.

    エンティティのライフサイクルで分ける
 4. ユースケースごとにデータの流れを整理する
 5. 属性のnull、updateを無くすところまで分解する
 a. イミュータブルモデリング
 b. SELECTとINSERTのみでデータを表現する
 エンティティの分解するとき
  10. 1. 属性(アトリビュート)を洗い出す
 2. データの関係を明確にする
 a. 1:1なのか1:NのかN:Nなのか
 b. 参照方向の確定(依存の親子関係) 
 3.

    エンティティのライフサイクルで分ける
 4. ユースケースごとにデータの流れを整理する
 5. 属性のnull、updateを無くすところまで分解する
 a. イミュータブルモデリング
 b. SELECTとINSERTのみでデータを表現する
 エンティティの分解するとき
  11. 駐車場 属性を洗い出す
 • 名称 • 管理番号 • 住所 • 緯度

    • 経度 • 最寄り駅 • 収容台数 • 営業時間 • 登録日時 支払い • 名称 • 基本料金 • 時間料金 • 1日最大利用料 • 昼間料金 • 夜間料金 • 支払日時 • 支払料金 • 支払者 • 消費税 • 割引額
  12. 駐車場 属性を洗い出す
 • 名称 • 管理番号 • 住所 • 緯度

    • 経度 • 最寄り駅 • 収容台数 • 営業時間 • 登録日時 支払い • 名称 • 基本料金 • 時間料金 • 1日最大利用料 • 昼間料金 • 夜間料金 • 支払日時 • 支払料金 • 支払者 • 消費税 • 割引額 駐車枠に依存する属性なので やっぱり駐車枠リソースは必要
  13. 駐車場 属性を洗い出す
 • 名称 • 管理番号 • 住所 • 緯度

    • 経度 • 最寄り駅 • 収容台数 • 営業時間 • 登録日時 支払い • 名称 • 基本料金 • 時間料金 • 1日最大利用料 • 昼間料金 • 夜間料金 • 支払日時 • 支払料金 • 支払者 • 消費税 • 割引額 支払い条件の話
  14. 支払い 駐車場 属性を洗い出す
 • 名称 • 管理番号 • 住所 •

    緯度 • 経度 • 最寄り駅 • 収容台数 • 営業時間 • 登録日時 • 名称 • 基本料金 • 時間料金 • 1日最大利用料 • 昼間料金 • 夜間料金 • 支払日時 • 支払料金 • 支払者 • 消費税 • 割引額 支払い内容の話
  15. 支払い内容 属性を洗い出す
 支払い条件 • 名称 • 基本料金 • 時間料金 •

    1日最大利用料 • 昼間料金 • 夜間料金 • 支払日時 • 支払料金 • 支払者 • 消費税 • 割引額 支払い • 名称 • 基本料金 • 時間料金 • 1日最大利用料 • 昼間料金 • 夜間料金 • 支払日時 • 支払料金 • 支払者 • 消費税 • 割引額 分解
  16. 1. 属性(アトリビュート)を洗い出す
 2. データの関係を明確にする
 a. 1:1なのか1:NのかN:Nなのか
 b. 参照方向の確定(依存の親子関係) 
 3.

    エンティティのライフサイクルで分ける
 4. ユースケースごとにデータの流れを整理する
 5. 属性のnull、updateを無くすところまで分解する
 a. イミュータブルモデリング
 b. SELECTとINSERTのみでデータを表現する
 エンティティの分解するとき
  17. 1. 属性(アトリビュート)を洗い出す
 2. データの関係を明確にする
 a. 1:1なのか1:NのかN:Nなのか
 b. 参照方向の確定(依存の親子関係) 
 3.

    エンティティのライフサイクルで分ける
 4. ユースケースごとにデータの流れを整理する
 5. 属性のnull、updateを無くすところまで分解する
 a. イミュータブルモデリング
 b. SELECTとINSERTのみでデータを表現する
 エンティティの分解するとき ER図で表現する
  18. 1. 属性(アトリビュート)を洗い出す
 2. データの関係を明確にする
 a. 1:1なのか1:NのかN:Nなのか
 b. 参照方向の確定(依存の親子関係) 
 3.

    エンティティのライフサイクルで分ける
 4. ユースケースごとにデータの流れを整理する
 5. 属性のnull、updateを無くすところまで分解する
 a. イミュータブルモデリング
 b. SELECTとINSERTのみでデータを表現する
 エンティティの分解するとき
  19. create table users( id bigserial constraint users_pk primary key, name

    text not null, birthday date not null, email text not null, hashed_password text not null ); create unique index  users_email_uindex on users (email); 

  20. alter table users add line_id text; alter table users add

    line_token text; create unique index users_line_token_uindex on users (line_token); create unique index users_line_id_uindex on users (line_id);
  21. passwordは認証情報のみの情報です。一方のemailは認証 情報のみに使われる情報だとするとpasswordと一緒にしてお くのも合理的かもしれません。 
  しかし、emailは「email情報単体で変更される」こともあれ ば、たとえばGitHubのように複数のemailを持つこともあるで しょう。
  このように、emailは認証情報以外の属性も持っています。 こうした場合、emailにpinコードを送ってWeb画面で認証する、 といったワンタイムトークンのような認証機能を実装すると

    passwordは不要になります。 
  こうした運用を想定し、今回はemailとpasswordを別テーブ ルに分ける判断をしました。 
  またこの設定であれば以下の図のように新たなログイン情 報が必要になった際も対応することができます。 
 https://agilejourney.uzabase.com/entry/2022/07/28/103000 そもそもUserじゃなくてMemberな って話が記事にはあるので続きは Webで
  22. 1. 属性(アトリビュート)を洗い出す
 2. データの関係を明確にする
 a. 1:1なのか1:NのかN:Nなのか
 b. 参照方向の確定(依存の親子関係) 
 3.

    エンティティのライフサイクルで分ける
 4. ユースケースごとにデータの流れを整理する
 5. 属性のnull、updateを無くすところまで分解する
 a. イミュータブルモデリング
 b. SELECTとINSERTのみでデータを表現する
 エンティティの分解するとき
  23. Small is beautiful. 小さなプログラムという発想
 1. 小さなプログラムはわかりやすい 
 2. 小さなプログラムは保守しやすい 


    3. 小さなプログラムはシステム
 リソースに優しい
 4. 小さなプログラムは他のツールと組 み合わせやすい
 
 https://amzn.to/33QPAdv
  24. Make each program do one thing well. 一つのことに集中することで
 プログラムに不要な部分をなくせる。 


    不要な部分があると、
 実行速度が遅くなり、
 不必要に複雑になり、
 融通が効かない。
 
 https://amzn.to/33QPAdv
  25. イミュータブルに設計する
 
 
 
 
 
 
 正規化とSimple is Beautiful

    https://scrapbox.io/kawasima/%E3%82%A4%E3%83%9F%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%96%E3%83%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%83%A2%E3%83%87%E3%83%AB [イミュータブルデータモデリング kawasima] [検索]
  26. 1. 論理データモデルを対象のソフトウェアに反映する
 a. RDBMSの場合にはDDL
 b. 検索のためのインデックスや制約を追加する
 2. パフォーマンスの要件のために必要な対応
 a. パーテーション


    b. キャッシュ
 3. 実際に利用するときのSQLを整理する
 a. 参照のためのSELECTや更新の処理
 b. そのときの実行計画を確認する
 c. 10年後も同じ実行計画になるか
 物理データモデリングの進め方
  27. 1. 論理データモデルを対象のソフトウェアに反映する
 a. RDBMSの場合にはDDL
 b. 検索のためのインデックスや制約を追加する
 2. パフォーマンスの要件のために必要な対応
 a. パーテーション


    b. キャッシュ
 3. 実際に利用するときのSQLを整理する
 a. 参照のためのSELECTや更新の処理
 b. そのときの実行計画を確認する
 c. 10年後も同じ実行計画になるか
 物理データモデリングの進め方
  28. 1. 論理データモデルを対象のソフトウェアに反映する
 a. RDBMSの場合にはDDL
 b. 検索のためのインデックスや制約を追加する
 2. パフォーマンスの要件のために必要な対応
 a. パーテーション


    b. キャッシュ …など
 3. 実際に利用するときのSQLを整理する
 a. 参照のためのSELECTや更新の処理
 b. そのときの実行計画を確認する
 c. 10年後も同じ実行計画になるか
 物理データモデリングの進め方 日本向けのサービスとグローバルで想定する最大ユーザ数は変わる 国内ならuserのpkはintで良いかも、グローバルなら bigintやuuidが必要
  29. 現実に向き合った本 • 令和の名著(当社調べ)
 • PostgreSQL & MySQL 対応
 そーだい本、一度は読んで欲しい。あと 5年は現役で読める本だと思っている

    し、「失われた事実」とか「キャッシュ中 毒」なんかは未だによく話をする。
 あと頑張ったら新刊出すかも。
 (連載してたやつをまとめて)
 https://amzn.to/4jBL4nL