🐷

基本から学ぶ テーブル設計 超入門!

2022/11/26に公開

概要

2022/03/30に開催された下記勉強会のメモです
https://modeling-how-to-learn.connpass.com/event/242944/

https://togetter.com/li/1865830

セッション

超入門!テーブル設計をデータモデリングから考えよう

(データモデリングの基本)

  • テーブル設計、どこから考える?
    • データに注目する
    • 「画面・帳票・処理」は「顧客の要望・業務・技術」の変化で変わりやすい
  • データを考え始める取っ掛かり
    • 画面や帳票は項目情報がわかりやすいので取り掛かりやすい

Excelから考えて見ると?

  • 複数行にまたがる(セル結合してるもの)はテーブルで表現できない
    • 分解して1行にする
    • そのままテーブルに

実は問題がある

  • 何箇所も修正が必要(結合してたものを分解したので同じ内容が複数行にある)
  • 打ち間違いがあると誤った値が拡散する
  • 計算できる値をそのまま持っている(保持する必要がある?など検討の余地あり)

マスタデータとトランザクションデータ
→以下の2つにデータを整理

  • マスタデータ
    • 業務を遂行する際の基礎情報
    • 例)社員、商品
  • トランザクションデータ
    • 業務で発生した出来事の詳細を記録
    • 例)売上明細

正規化
→修正箇所も1つで済むように

  • (正規化の結果)細かくテーブルが別れていく
    • テーブルの制約はしっかりと設定する(主キー、外部キー、Not Null等)
    • 変なデータが入ることを防ぐ
  • キーに従属する形でデータが綺麗に別れる

RDRA(ラドラ)で考えてみる

  • 要件定義、要件分析手法
  • 4つのレイヤーごとにダイアグラムを書くことで要件の内容をモデリングする手法

http://vsa.co.jp/rdra/

RDRA(の領域)→概念モデル→論理モデル→物理モデル

  • (RDRAの)ユースケース複合図から物理モデルへの繋がり
    • ユースケース複合図=ユースケースを中心に画面や情報を洗い出すもの
      • ユースケース≒機能
      • 情報≒データ
  • 情報を他のユースケースで使っていないか遡って考えてみる
    • さらに上位の業務フローやビジネスユースケース・業務まで遡ると他にシステムで実現すべき範囲が見えてくる

ビジネスコンテキスト図で考える(と以下のように必要な情報が出てくる)

  • 商品は販売業務だけでなく仕入れ業務にも絡んでいる
    • 商品には単価だけでなく仕入れ値も
    • 仕入れ先に関する情報は?
  • 販売の別ユースケースを考えると
    • 見積り時の値引き、可能な範囲
    • 商品のカテゴリ必要?

なんでも情報を入れればいいわけでもない

  • どんどん情報を追加していくとよく分からない塊が出来上がる
  • 幅広い視点で考えないといけない
    • 俯瞰してみることが必要

データモデルの3つの粒度

  • 概念モデル
    • 抽象度が一番高いモデル
    • 例)社員、商品、売り上げなどがどのような関係にあるか
  • 論理モデル
    • 各項目としてどういったものがあるかまでを考えたモデル
    • 例)上記に加えて商品には商品名、単価などがあるなど
  • 物理モデル
    • データベース特性なども踏まえ実際にシステムに作るレベルのモデル

概念モデルも大事

  • 人々の間で認識は違っている

データをしっかりと捉えるには詳細に見ることも一方で必要

  • 具体的に考える際に多重度からデータを
  • 表計算などでデータを作ってみることで具体化され過不足やおかしな構造をチェックできる

Q

おさらい

  • Excelを元にボトムアップで俯瞰していくと他に色々考えないといけない流れが見えた
  • ということは逆のアプローチをすれば効率がよくなるハズ

出発点は画面・帳票じゃない

  • 参考にはするが帳票や画面からスタートしない考え方ができると良い

データモデルは、データの構造

  • データにはビジネスのルールやロジック、状態の変更ルールといった処理や業務フローなどのプロセスは表現されていない

ビジネスルールは、ドメインモデルで

  • ジネスのルールやロジック、状態の変更ルールといった処理や業務フローなどのプロセスを意識してモデル化するのがドメインモデル

とはいえ、いきなりドメインモデルは難しい

  • データモデルは静的なので分かりやすい
    • モデリングを勉強し始める取っ掛かりとしてオススメ

まとめ

  • 視点を広げる
  • 物事を説明するときは「全体→詳細」
  • 一発で正解は出ないので俯瞰と具体化を行ったり来たりを繰り返す
    • 全体→詳細→全体→...

データモデルからはじめましょう

テーブル設計の考え方とやり方【入門編】

(テーブル設計の基本)

データベースを利用する目的

  • 発生した事実を記録する
  • 記録した事実を利用する

2つの設計アプローチ

  • 追記型(イミュータブル)
    • クラウド環境の疎結合かつ分散型の処理と相性が良い
  • 更新型(ミュータブル)
    • 多くの書籍、ネットの情報、伝統的なやり方は更新型が暗黙の前提

※以降は追記型の考え方とやり方

追記型のテーブル設計

  • 中核テーブル
    • 事実を記録する、変更不可、NOT NULL
    • 消失すると復元不能
  • 周辺テーブル
    • 事実から導き出した二次データ
    • 利用を助ける補助テーブル
      • 性能要件、SELECT分の単純化
    • 中核テーブルさえあれば論理的には不要、復元可能

データベースに記録する内容

  • ヒト(当事者)
    • 当事者として登録、行動の履歴
  • キメ(規程)
    • 計算の根拠、判断基準
  • コト(活動)
    • 約束した事実、履行した事実
  • モノ(資源)
    • 利用可能なモノ、増加・現象

事実とは過去形である

  • データベースに記録するのは常に過去
  • 予定も予定したという過去の記録
  • 上書き(改ざん)は禁止
  • 記録の修正は「赤黒」方式
    • 元の記録+取り消し(赤)+修正後の記録(黒)の3つの記録

事実の記録の利用

  • 事実から計算結果・判断結果を導き出す
  • to do, doing, doneの管理
  • 予定・実績・差異の管理

どう記録するか

  • 値のグルーピング
    • 組み合わせによる記録
    • 顧客のデータを(顧客番号、氏名、メールアドレス)で記録
  • 値と値の関係(ある値が決まれば他の値が1つに決まる)
    • 顧客番号がわかれば、氏名とメールアドレスが一つに決まる
    • 氏名がわかっても他は1つに決まらない
  • 値のグループの合成(分解と結合)
    • (顧客番号、氏名)と(顧客番号、メールアドレス)で記録
    • 「顧客番号」で結合、(顧客番号、氏名、メールアドレス)のビューを合成

テーブル設計の基本

  • 一意性制約(UNIQUE)
    • ある値が決まれば他の値が一意に決まる(一意性)
  • 外部キー制約(FOREIGN KEY)
    • 同じ識別キーを使って2つのテーブルの値を合成する(結合性)
  • 一意性制約と外部キー制約で多様なデータを論理的に整理する

テーブル設計4つの視点

  • 識別番号
    • 識別番号が同じだから同じテーブルはアンチパターン
  • 発生時点
    • 発生時点が異なれば別テーブル
    • 同じでも分けた方が良いものもある
  • 記録の目的
    • 値の用途が異なれば別テーブル
  • データの意味
    • 値のグループに名前がついている
      • 届け先住所(注文番号、郵便番号、都道府県、市区町村、街区、番地)
    • 同じデータでも意味が違えば別データ

値と値の関係の整理

  • キーが同じでも値の意味が異なれば別のテーブルで記録する
    • テーブルにNULLを入れるのではなく、任意の項目を別テーブルにばらすという考え方は選択肢としてある
      a. 顧客登録(顧客番号、氏名)
      b. 連絡方法[必須](顧客番号、メールアドレス)
      c. 連絡方法[任意](顧客番号、電話番号)

どう記録するか

  • 意味を明確にする
    • スキーマ名
    • テーブル名
    • カラム名
  • 正確に記録する
    • データ型
    • 制約
  • テーブルとテーブルを関係づける
    • 先行-後続
    • 集約-明細
    • 一意-重複

アンチパターン:いい加減な記録

  • 名前がいいかげん(意味不明、虚偽)
  • データ型がいいかげん
  • 制約がいいかげん(制約がない)

テーブル設計のやり方/学び方

  • 実際に手を動かす→テキストで記述して実行
    • PostgreSQL推奨
    • データ型と制約、追記方式の学習
  • 以下はアンチパターン
    • ツールを使ってDDL生成
    • フレームワークでDDLの作成と実行を隠蔽
    • DDL/SQLかけなくてもデータベースは使える

正しく記録する

  • CREATE TABLE文を理解する
    • スキーマを使う(※DBによってはこの概念がないものがあります)
    • 制約を書く
  • スキーマ名・テーブル名・列名にこだわる
    • 日本語
      • 説明的な名前
    • スキーマによる構造化
      • テーブルをグルーピング
      • スキーマ名で関心事を分離
    • 関連づけテーブルの名前
      a. 部門_X_従業員:構造の表現を重視
      b. 所属:意味を表現かつ更新型
      c. 配属_履歴:意味を表現かつ追記型

データ型:可能な限り狭く定義する→CHECK制約でデータ型をさらに制限する

  • 数量:NUMERIC
  • 個数:自然数という選択肢、下限と上限
  • 日付:日付型を使う(文字列にしない)
  • 識別番号:数値or文字列orUUID
  • 名称:文字列、最大長
  • 作成タイムスタンプ:UTC

制約にこだわる:良いテーブル設計の根幹

  • NOT NUL
    • すべての列で宣言すべき
    • NULLという事実はない
    • NULLはSQLとプログラムに複雑さを持ち込む
  • 一意性制約(UNIQUE)
  • 主キー制約(PRIMARY KEY)
  • 外部キー制約(FOREIGN KEY)
  • チェック制約(データ型の教科:設計意図の表現)
    • どこまで宣言するか?→基本は全て書く
    • エクセルのテーブル定義書でなく、コード(DDL文)で文書化

対象別のテーブル設計の基礎

  • 中核テーブルに追記型で事実を記録、(パフォーマンスなど)必要に応じて更新型の周辺テーブルで管理
  • 「規定」を扱うときは方針を選択(テーブルorプログラム)
    • 以前はテーブル記述が基本だったが、プログラム変更やデプロイが容易になった今は費用対効果が変わってきている

参考書籍

PostgreSQL文書:5章、8章
https://www.postgresql.jp/document/current/index.html
理論から学ぶデータベース実践入門:1章、7章
https://www.amazon.co.jp/dp/4774171972/
現場で役立つシステム設計の原則:6章
https://www.amazon.co.jp/dp/477419087X/
楽々ERDレッスン:2章
https://www.amazon.co.jp/dp/4798110663/

Discussion