データベース設計:ER図の基本

テーブルの関連のパターン

同じ意味の列を持つテーブル同士の間には、通常次の3パーンの関連がある。

  • 1対1(1:1)

    『1対1』というのはほぼ見ないらしい。理由は2つのテーブルのレコードが1対1に対応するというのは、主キーが一致するケースなので、通常1つのテーブルにまとめても問題ないため。よって、正規化の過程で『1対1』のテーブルが作られることは無い。

  • 1対多(1:N)

    『1対多』は最もよくある関連のタイプ。正規化によって作られる関連の多くはここに属する。

  • 多対多(N:N)

    『多対多』は特殊なカテゴリで、RDBMSでは『多対多』の関連は作っていけないことになっている。理由は、多対多では、両者のエンティティが共通のキーとなる列を保持していないことで、両エンティティを結合した情報を取得できないため。

    それを解決するために、両者の間に、第3のエンティティとして関連実体を追加する。これは、『実在としては存在しないが、関連としては存在している』というような関連としての事実を追加するみたいなイメージと理解した😐

    具体的なイメージを考える。学生は複数の講義を取ることができ、講義もまた複数の学生が参加できる。それをER図で示すと次のようになる。

    image.png

    上の状態で、1人の学生が講義を複数取ろうとすると、学生テーブルに同一学生コードを追加することになってしまう。(主キーなのに同一のものがある😫)

    そこで関係実体の出番。両者の間には『受講する』という事実上の関係があるので、それを追加する。そうしてあげることで、『多対多』問題が解消され、ある学生は複数の講義を受講できるという関係を正しく表現できるようになる。

    image.png

ER図の描き方

代表的な書き方は次の2つ。2つの特徴について、同じ関係を示すER図と、カーディナリティ(相手エンティティと対応するレコード数)の記号合わせて説明する。

  • IE表記法:鳥の足のような見た目の直感的にわかりやすいER図。厳密に書くのは苦手。

    image.png

    記号の意味は次のとおり。

    記号 意味
    0
    - 1
    /|\ 多(2以上)
  • IDEF1X:「●」や「◇」を用いた抽象度の高いER図。厳密に書くのが得意。「●」は『多』の側にだけつける。

    image.png

    記号の意味は次のとおり。

    記号 意味
    0以上
    ●P 1以上
    ●Z 0または1
    ●n 特定の定数

    部署についている「◇」は、部署コードがNULLでありうることを示している。

    また、独立エンティティ(他のテーブルのデータに依存することなくデータを保持できるエンティティ)を角の尖った四角で示し、従属エンティティ(他のテーブルが存在しないとデータを保持することができないエンティティ)を角の丸い四角で示す。

    さらに、実線は依存リレーション(社員が会社に必ず属さなければいけないという関係)を示し、点線は非依存リレーション(必ずしも社員が部署に所属しなくてもよいという関係)を示す。

参考

データベース設計:正規化の種類

表とテーブルの違い

表は共通点のないデータを並べて構成することも可能で、次のようなもの。

項目1 項目2 項目3
千代大海 10勝5敗 大関
ドラえもん ネコ型ロボット 四次元ポケット
レディガガ 歌手 ファッション

テーブルはある共通点を持ったレコードで構成され、次のようなもの。

社員ID 社員名 年齢
000A 加藤 40
000B 藤本 32
001F 三島 50

キーの種類

キー名 説明
主キー 主キーは、その値により必ず1行のレコードを
特定できるような列の組み合わせのこと。
(一意に識別できる)
複合キー 複数列を組み合わせて作る主キー
候補キー 主キーとして利用なキーが複数存在した場合の、
主キーの候補となるキー
スーパーキー 主キーに、非キー列を付加した時のキーの組み合わせ
外部キー 2つのテーブル間の列同士で設定するもの。
外部キーは人間の親子関係のようなもので、
参照する側は参照元がないとデータを作れない
(親がいないと子は生まれない)。
テーブルに対して一種の『制約』を与え、
この制約を参照整合性制約という

制約の種類

参照整合性制約の他に、テーブルの代表的な制約には次のものがある。

制約名 説明
NOT NULL制約 NULLを禁止にする制約。各列ごとに設定できる。
一意制約 ある列の組について一位性を求める制約。
主キーと似ているが、主キーはテーブルに対して1個であるが、
一意制約は何個でも設定可能。
CHECK制約 ある列の取りうる値の範囲を制限する。数値の範囲(20~65)や、
文字列のリスト('開発','人事','営業')みたいに指定できる。

正規化とは

概要

正規化とは、テーブルのレイアウトを正規形にするために行う論理設計の作業の一つ。正規形は、『データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式』という意味。

正規化のポイント

正規化のポイントは3つ。

  • 正規化とは更新時の不都合/不整合を排除するために行う
  • 正規化は従属性を見抜くことで可能になる
  • 正規形はいつでも非正規形に戻せる(正規化は無損失分解。可逆的な操作)

正規化のメリット、デメリット

メリデメ 内容
メリット ・データの冗長性が排除され、更新時の不整合を防止できる
・テーブルの持つ意味が明確になり、開発者が理解しやすい。
デメリット ・テーブル数が増え、SQL文の結合を多用するためパフォーマンスが悪化

どの程度すべきか

  • 第3正規形までは原則必須
  • 関連エンティティが存在する場合は、関連とエンティティが1対1に対応するようにする

正規形のレベル

正規形のレベルは全部で次の6種類あるが、一般的な業務の中で多く用いられるのは、第3までらしい。

  • 第1正規形
  • 第2正規形
  • 第3正規形
  • ボイスコット正規形
  • 第4正規形
  • 第5正規形

第1正規形の定義:スカラ値の原則

第一正規形の定義は、『1つのセルの中には1つの値しか含まない』というもの。

第一正規形の問題としては、テーブルの意味やレコードの単位をすぐに理解できないという点。データ上NULLとなってしまうものが主キーになるような場合、無理矢理にでも値を設定する必要が出てきて、後で参照するときに設定した意味を読み解く必要があるため。

また、そもそも『なぜ1つのセルに複数の値を設定してはだめ?』については、複数の値があると主キーが各列の値を一意に決定できなくなってしまうため。

第2正規形の定義:部分関数従属

主キーの一部の列に対して従属する列がある場合、この関係を部分従属と呼び、主キーを構成するすべての列に従属性がある場合を、完全関数従属と呼ぶ。

第2正規形とは、テーブル内で部分関数従属を解消し、完全関数従属のみのテーブルを作ることをいう。

従属というのは、会社コードが決まると会社名も定まるようなもので、その関係を{会社コード}->{会社名}と表現する。

イメージ的にはある関数fに会社コードを入力すると会社名が出力される(f(会社コード)=会社名)みたいな関係のことを言う。 よって、f(主キー)によってレコードが一意に定まる状態のことを言う。

第3正規形:推移的関数従属

{会社コード,社員ID}->{部署コード}->{部署名}のような2段階の関数従属があるようなものを推移的関数従属という。このような関係が成り立つ列がテーブル内にあると、『所属部員が現在たまたまいない部署』をデータベースに登録できなくなってしまう。

そこで、{会社コード,社員ID}->{部署コード}{部署コード}->{部署名}のようにテーブルを分けてあげることで問題を解消する。

関数的なイメージは、g(f(会社コード,社員ID))=部署名となっている関数を、f(会社コード,社員ID)=部署コードg(部署コード)=部署名の2つに分けてあげるような感じか🤔

ボイス-コッド正規形

第3正規形かつ『非キーから主キーへの関数従属をなくした状態』。ボイス-コッド正規形は非可逆分解になる可能性があるので注意する。

第4正規形

第4正規形では、独立な多値従属性が複数存在するテーブルを分割する。多値従属性とは、キーの値を1つ定めると複数の日キーの値が定まる状態のこと。

イメージ的には、1人の社員が複数のチームに所属し、複数製品を担当している関係を、{社員ID}-->{製品コード|チームコード}のように表す。このエンティティの関係をバラして、{社員ID}-->{製品コード}{社員ID}-->{チームコード}のようなテーブルを分割してあげる。

第5正規形

第5正規形では、『関連がある場合は、それに対応する関連エンティティを作る』という作業を行う。

イメージとしては、{社員ID}-->{製品コード}{社員ID}-->{チームコード}だけでは、チームが担当する製品がわからないので、{チームコード}-->{製品コード}という関連エンティティを追加してあげる。つまり事実として関連があるのであれば、それを関連エンティティとして追加する作業を行うということ。

参考

楽々ERDレッスン:テーブル設計実践6

テーブル設計の流れ

テーブル設計の流れの概要にめちゃくちゃわかりやすくテーブル設計の手順が書かれていたので記載。これをベースに作業を進める。

  1. メインとなるテーブル名を出す
  2. 「誰が・何が」を考えてテーブル名を出す
  3. 「誰を・何を」を考えてテーブル名を出す
  4. 各テーブルのカラムを出す
  5. 残ってる、表現できていない情報があれば、テーブルになるか、カラムに追加するかを考える
  6. 関連を入れる
  7. 制約とデフォルト値とINDEXを考える

ガスの請求書

ガスの請求書のテーブル設計を行う。題材は次のもの。

image.png

メインとなるテーブル名を出す(イベント系エンティティを洗い出す)

この紙の目的を考えると、『ガス使用量を検針するもの』なので、メインとなるイベントは『検針』となる

image.png

「誰が・何が」、「誰を・何を」を考えてテーブル名を出す(リソース系エンティティを洗い出す)

『ガス会社』が『ガス使用量』の検針をする。ただ、ガス会社をデータとして記録する必要はないので、『ガス使用量』のみをリソース系エンティティに追加。

image.png

各テーブルのカラムを出す

検針表から見た目通りにカラムを設定していく。

image.png

表現できていない情報を、テーブルにするか、カラムに追加するかを考える

下記の項目がまだ表現できていない。

  • 顧客情報
  • 前月の指示数
  • 前年の情報(使用量、使用日数)
  • 基本料金

前月や前年情報は自己参照っぽい気がするので、エンティティやカラムではなく関連で示すと思うので、顧客情報と基本料金を追加。また、基本料金は、ある程度決まっているようだけど、異なる料金体系になることもあるっぽいので、見出し明細形式にしておく。

image.png

関連を入れる

関連を入れていく。具体的なデータ(検針データがどのように管理されるかを想像しながら)を考えながら関係や多重度を考えていく。外部参照キーも入れていく。前月と前年を関連を入れてみたけど、1体1対応になると思うので、そのように記述してみたけど、これでいいのか微妙😅

とりあえず解答を確認する。

image.png

参考:解答例

image.png

今回は答えが違いすぎて泣けました😭

今回の解答からの得たポイントは次の3つ。

  • テーブルで一緒にしなくても、ビューで表現してしまえば良い(ビューで仮想テーブルを作る)

    今月-前月、当年-前年を自己参照として表現しようとしたけどそうではない。データとしてはいずれも全く同じ属性なので、データとして管理するものは同じで良い(可逆性のある導出項目の削除)。どうデータを見せるかの部分は、ビューで表現する。今回の例だと、検針テーブルを今回分と前回分のあたかも別テーブルと存在するかのようにビューを使ってあげて表現する。

  • 他のデータから計算できるものは可能な限り排除(可逆性のある導出項目の削除)

    今回の例だと、使用期間については『前回検針日翌日から今回検針日までの日数』として計算でき、次回検針日についても『予定として1ヶ月後』となっているので、いずれも検針日さえデータとして残っていれば良いので、当該のものは不要になる。

参考

楽々ERDレッスン:テーブル設計実践5

テーブル設計の流れ

テーブル設計の流れの概要にめちゃくちゃわかりやすくテーブル設計の手順が書かれていたので記載。これをベースに作業を進める。

  1. メインとなるテーブル名を出す
  2. 「誰が・何が」を考えてテーブル名を出す
  3. 「誰を・何を」を考えてテーブル名を出す
  4. 各テーブルのカラムを出す
  5. 残ってる、表現できていない情報があれば、テーブルになるか、カラムに追加するかを考える
  6. 関連を入れる
  7. 制約とデフォルト値とINDEXを考える

病院の領収書

病院の領収書のテーブル設計を行う。題材は次のもの。

image.png

メインとなるテーブル名を出す(イベント系エンティティを洗い出す)

この紙の目的を考えると、『病院が請求するもの』なので、メインとなるイベントは『請求』となる

image.png

「誰が・何が」、「誰を・何を」を考えてテーブル名を出す(リソース系エンティティを洗い出す)

『病院』が『費用』の請求をする。ただ、病院をデータとして記録する必要はないので、『費用』のみをリソース系エンティティに追加。また、費用は複数の請求内容から構成されているので、見出し明細形式にする。

image.png

各テーブルのカラムを出す

領収書から見た目通りにカラムを設定していく。

image.png

表現できていない情報を、テーブルにするか、カラムに追加するかを考える

下記の項目がまだ表現できていない。

  • 請求者の情報(患者の情報)
  • 保険区分、保険負担
  • 請求内容

上記項目はそれぞれをエンティティとした方が、データのまとまりが綺麗と思ったので、それぞれエンティティ化する。また、請求内容は、ある程度分類科される気がしたので、請求分類エンティティも追加した。

image.png

関連を入れる

関連を入れていく。具体的なデータ(自分のデータがどのように管理されるかを想像しながら)を考えながら関係や多重度を考えていく。外部参照キーも入れていく。

また、費用エンティティがなくてもデータとして成立しそうなので削除する。

image.png

解答例を見てみる。

参考:解答例

image.png

今回の解答からの得たポイントは次の3つ。

  • 見たままに属性を追加しきる

    属性の追加忘れが結構あった😅その辺は見たままに全部追加という部分をもう少しきちっとやる必要があると思った。

  • データの扱いやすさを考慮した属性にする

    請求期間については、解答例の方は開始日と終了日で分けて管理するようにしていた。データとして持つなら解答例のような形の方が扱いやすい(期間としてまとめてしまうと、データ処理するときに一度開始と終了に分割する処理が必要になる)と感じたので、今後はそういった属性追加をしていきたい。

  • 事実とデータが一致するようなエンティティに適切な属性を持たせる

    自分の考えだと、保険と金額を請求内容エンティティに入れていたが、解答例だと請求明細に入っていた。理由を少し考えてみた🤔請求内容エンティティに入れた場合、領収書発行後に請求内容の点数や金額を編集すると、発行した領収書のデータと、データベース内のデータに差異が出てしまうからだと思った。よって、あるエンティティ内で事実として動かない部分は、1つのエンティティ内に属性を持たせることが大事なんだと学んだ。

参考

楽々ERDレッスン:テーブル設計実践4

テーブル設計の流れ

テーブル設計の流れの概要にめちゃくちゃわかりやすくテーブル設計の手順が書かれていたので記載。これをベースに作業を進める。

  1. メインとなるテーブル名を出す
  2. 「誰が・何が」を考えてテーブル名を出す
  3. 「誰を・何を」を考えてテーブル名を出す
  4. 各テーブルのカラムを出す
  5. 残ってる、表現できていない情報があれば、テーブルになるか、カラムに追加するかを考える
  6. 関連を入れる
  7. 制約とデフォルト値とINDEXを考える

病院の受付伝票

病院の受付伝票のテーブル設計を行う。題材は次のもの。

image.png

メインとなるテーブル名を出す(イベント系エンティティを洗い出す)

この紙の目的を考えると、『患者が診察の受付するもの』なので、メインとなるイベントは『受付』となる

image.png

「誰が・何が」、「誰を・何を」を考えてテーブル名を出す(リソース系エンティティを洗い出す)

『患者』が『治療』の受付をするので、リソース系エンティティを追加。

image.png

各テーブルのカラムを出す

受付表から見た目通りにカラムを設定していく。

image.png

表現できていない情報を、テーブルにするか、カラムに追加するかを考える

下記の項目がまだ表現できていない。

  • 受診科(診療科目)
  • 受診内容
  • 医師名

上記項目はそれぞれをエンティティとした方が、データのまとまりが綺麗と思ったので、それぞれエンティティ化する。

image.png

関連を入れる

関連を入れていく。具体的なデータ(自分のデータがどのように管理されるかを想像しながら)を考えながら関係や多重度を考えていく。外部参照キーも入れていく。

また、治療エンティティがなくてもデータとして成立しそうなので、削除する。

image.png

これまでの演習に比べて1つのエンティティ(受付)の属性がいっぱいになってしまった😅。とりあえず解答例を見てみる。

参考:解答例

受付表の受診科の横の番号は、何かよくわからなかったので表現していなかったけど、どうやら複数の診察をまとめて受付可能という意味だった。よって、1つの受付に複数の診察を割り付ける必要があるので、見出し明細形式で表現する。見出し明細形式でテーブルを作るときは、すぐに関連する属性IDを付与する。

image.png

そのほかの考えは、だいたい同じだったが、受付日時の横の数字は、「端末番号」ということだったので、受付エンティティに入れる必要がある。また、各受診の時刻はそれぞれ異なるはずなので、時刻を受付明細エンティティに移動する。最終的なER図は次のようなものになる。

image.png

今回は、割とイメージ通りの構成であったため、そこまで突っかかることは無くてよかった💪といっても、ER図作るのに結構時間かかってますが😅

とりあえず見たままを表現ということで上記までの検討しかしていなかったが、参考書ではさらに改良したER図が紹介されていた。内容としては、組み合わせに対する制約の管理というもので、今回の例だと、『医師が担当できる科目』や『各受診科で対応する受診内容』には制約がある。それをエンティティとして表現しておくと、入力支援などで使えるらしい。それに対応したER図が次のもの。

image.png

参考

スクラム開発の進め方

SCRUM BOOT CAMP THE BOOKを読んだので、大事だなと思ったことをまとめる。

他に読んだアジャイル本(アジャイルサムライ, いちばんやさしいアジャイル開発の教本)の中では、スクラムに特化した内容。具体的なストーリーを通して学べるため、より現実を感じながら学ぶことができたと思う。

スクラムとは

スクラムアジャイル開発の手法の一つ。そもそもアジャイル開発って何🤔って感じだが、アジャイル開発は次のような進め方をする開発のこと。

  • 関係者は目的達成のためにお互いに協力し合いながら進める
  • 一度にまとめてではなく少しずつ作り、早い段階から実際に動作するものを届け続けて評価を繰り返す
  • 利用者の反応や関係者からのフィードバックを継続的に得ながら、作っているもの自体や計画を調整する。

アジャイル開発手法には、次の種類のものがある。

また、共通するのは『事前に全て正確に予測し、計画することはできない』ということを前提にしている点。

アジャイル開発では、どのくらいの期間・人数で仕事をするかを決めて、その範囲の中で大事な要求から順にプロダクトを作っていく。よって、重要なものから先に作り、そうでないものを後回しにして成果を最大化することを目指す開発。

スクラムの『5・3・3』

スクラムは最低限のルールのセットで構成されている。

5つのイベント(会議等)

イベント名 説明
スプリント ・固定期間に区切って開発する際の単位。最長でも1ヶ月
・スプリントは他のイベントの入れ物
スクラムではスプリントを繰り返すことでリズム良く開発を進める
スプリントプランニング ・スプリントを進める計画のためスプリントの冒頭で行う
・スプリントで何(what)をどう(how)作るかを計画する
デイリースクラム ・スプリントゴール達成のための毎日の状況確認
・昨日やったこと、今日やること、障害となることなどを話す
スプリントレビュー ・スプリントでの成果物をデモする
・フィードバックを受けて、プロダクトバックログを見直す
・今後の予定や見通しの共有
スプリントレトロスペクティブ ・直近スプリントでのカイゼン活動
・バグが生まれるプロセスを直す
・提案されたカイゼンの1つは次回のスプリントに必ず反映する

3つのロール(人の役割)

ロール名 説明
プロダクトオーナー プロダクトバックログ管理の責任者
開発チーム ・プロダクトバックログを開発する人
・機能横断的なチームである必要がある
(開発チームでプロダクトを作るための作業全てができる。)
スクラムマスター スクラム開発のプロセスが円滑に回るように仕切る人
・マネージャーや管理者ではなく、スクラム開発を誘導するトレーナー的な役割をする

3つの作成物

作成物名 説明
プロダクトバックログ ・機能や要求、要望、修正などプロダクトに必要なものを抽出し、実現したい順に並べたもの
・常にメンテナンスして最新に保つ
・上位項目については見積もりを済ませる
スプリントバッグログ ・選択したプロダクトバックログ項目と実行計画
・プロダクトバックログを具体的な作業に分割する
・後から増えることもある
・1タスクは1日以内で終わるサイズ
インクリメント ・スプリント単位で評価可能なもの
(動作して検査可能なソフトウェア)
・累計のプロダクトバックログ項目を合わせたもの
・プロダクトバックログアイテムが完成の定義を満たした時に誕生する
・よって、完成の定義が決まっていないと評価できない

全体の流れ

上記の『5・3・3』の流れのイメージをまとめる。

image.png

上のイメージのように、スクラム開発は『PDCA』を回すためのフレームワークと捉えると分かりやすい。『P:スプリントプランニング』、『D:実装+デイリースクラム』、『C:スプリントレビュー』、『A:スプリントレトロスペクティブ』みたいな対応になると思う。

雰囲気はつかめた、で、どうする?

スクラムの進め方はなんとなくわかったので、それぞれのイベントで役立つノウハウをまとめておく。

プロダクトバックログの決定

プロダクトバックログでは次のことを決める必要がある。

  • どういうことを実現するのか(ゴール)
  • 絶対に達成したいことは何か(ミッション)

ゴールとミッションを明確にする

上記を決める活動の1つに、インセプションデッキと呼ばれる手法がある。インセプションデッキでは、明らかにすべき点を10個の質問でまとめられていて、それについてスクラムチームで話し合い、スライドにまとめていく。

プロダクトバックログのサンプル

詳細なフォーマットはない。機能を列挙したものや、ユーザストーリで書いたものなどがある。

  • 機能列挙

    機能 目的 詳細 見積もり
    日報入力 最新情報から戦略を考える 日単位で訪問先、
    担当者、案件情報を入力する
    ログイン 機密のため利用者を制限 社員番号とパスワードで認証
    ・・・
  • ユーザストーリ

    ストーリー デモ手順 見積もり
    毎日訪問先の状況を記録したい。最新情報から戦略を練りたいため XXX社の記録ページを表示して、訪問日時、商談状況、報告内容を入力して記録ボタンを押す。確認画面が・・・
    利用者を制限したい。機密情報を社員のみに開示するため 未ログイン状態でアクセスするとログイン画面を表示。〇〇の社員番号とパスワードを・・・
    ・・・

作業の見積もり

プロダクトバックログの内容をまずは大雑把に下記くらいに分類する。

  • 簡単に終わりそう
  • 少し大変そう
  • 結構大変そう

上記の振り分けをしたら、1つのプロダクトバックログの項目に対して、作業量の基準値を設定する。その基準に対して、他の項目たちが相対的にどんな感じかをそれぞれ見積もっていく。この時のやり方には、見積もりポーカーと呼ばれるものもある。

また、プロダクトバックログは、細かくしすぎない。見積もりは結局のところ推測でしかないので、プロダクトバックログを細かくして、見積もりを詳細にしたところでズレが起こる。その際、せっかく詳細に見積もりにかけた時間が無駄になるため

全体の見積もり(必要なスプリント数の見積もり)

上記で決定したプロダクトバックログと見積もりをもとに、全体でどの程度の時間が掛かるかが見通せるようになる。

理由は、それまでのスプリントで消化した見積もり数の値から、1スプリントで消化できる見積もり数(ベロシティ)を予測でき、残プロダクトバックログの見積もり数合計➗ベロシティで、残りどの程度かかるかがわかるようになるため。

スクラムを初めてやる場合には、何回か数をこなし、スプリントの平均ベロシティを出すと良い。

スプリントプランニングの実行

スプリントプランニングでは次のことを行う。

  1. このスプリントで何をするかを共有する
  2. 完成の定義を決める
  3. 必要な作業(タスク)を洗い出す
  4. スプリント内で終わるかを判断する

デイリースクラムで進捗確認

デイリースクラムでは次のことを共有する。

  • スプリントゴール達成のために昨日やったこと
  • スプリントゴール達成のために今日やること
  • スプリントゴール達成の妨げになる障害や問題点

デイリースクラムの中では、問題を見つけることだけにとどめ、実際の対処はデイリー後に議論する。

また、スプリントゴールに対して、スプリントバーンチャートを書いてみると、進捗把握できるため、有効らしい。

image.png

バーンダウンチャートとは?

スプリントレビューでフィードバックを得る

スプリントレビューでは、スプリント開始時に決めたプロダクトバックログのうち、完成したものを開発チームおよびステークホルダーに見せて、今後のフィードバックを得る。

実際に動くものを触ることで期待したものになっているかの確認を行え、要求通りであっても『実は使いにくかった』というような改善のヒントを得ることができる。

スプリントレトロスペクティブでスプリント自体を見直す

スプリントレトロスペクティブは『ふりかえり』。スプリントを通してうまくいかなかったことや改善点等をチームで話し合って、次のスプリントをよりうまく回せるようにする。

ふりかえりの手法としては、『KPT』や 『Fun Done Learn』などいろんなやり方がある。心理的安全性のあるチームを作るためにコミュケーション向上を狙ったものや、スプリント中のやりにくい作業などを思い起こして、どうすればいいかなどを考える。

PDCA でいうところの『C』にあたる部分かなと思っています。ここで決めた内容を次回のスプリントで『A』するという感じかなと。

参考

楽々ERDレッスン:テーブル設計実践3

テーブル設計の流れ

テーブル設計の流れの概要にめちゃくちゃわかりやすくテーブル設計の手順が書かれていたので記載。これをベースに作業を進める。

  1. メインとなるテーブル名を出す
  2. 「誰が・何が」を考えてテーブル名を出す
  3. 「誰を・何を」を考えてテーブル名を出す
  4. 各テーブルのカラムを出す
  5. 残ってる、表現できていない情報があれば、テーブルになるか、カラムに追加するかを考える
  6. 関連を入れる
  7. 制約とデフォルト値とINDEXを考える

ハンバーガーショップのレシート

ハンバーガーショップのレシートのテーブル設計を行う。題材は次のもの。

image.png

メインとなるテーブル名を出す(イベント系エンティティを洗い出す)

この紙の目的を考えると、『顧客が食べたいものを注文するもの』なので、メインとなるイベントは『注文』となる

image.png

「誰が・何が」、「誰を・何を」を考えてテーブル名を出す(リソース系エンティティを洗い出す)

『顧客』が『商品』を注文するので、リソース系エンティティを追加。

image.png

各テーブルのカラムを出す

レシートから見た目通りにカラムを設定していく。

image.png

表現できていない情報を、テーブルにするか、カラムに追加するかを考える

下記の項目がまだ表現できていない。

  • セットの部分
  • 預かり金
  • 預かり方法

セット部分は、あるセットに対して複数の商品が割りつくと思うので、『セットメニュー』と『セット構成』エンティティを用意。預かり金はとりあえず『入金』エンティティを作ってそこに突っ込んでみる。

image.png

関連を入れる

関連を入れていく。具体的なデータ(マク○ナルドのメニューを想像しながら🤤)を考えながら関係や多重度を考えていく。外部参照キーも入れていく。

image.png

注文エンティティと注文リストエンティティを結びつければ良さそうなんだけど、注文リストエンティティへの関連がおかしい。『単価』属性がセット構成エンティティと商品エンティティに重複しているのが良くないと思うので、セットメニューをどうにかして商品に突っ込みたいが、、、、、、

ここでギブアップしました😅というわけで回答を見てみる。

参考:解答例

イベント(出来事系)系の抽出のポイントは、動詞〇〇日と言っても成り立つかという点。そういう意味で、注文・入金はいずれも条件を満たすため、イベント系エンティティと言える。

ただ、入金については、レシート上の事実としては、『お金を預かる』という内容なので、より正確には下記のようなエンティティが適当。

image.png

分析のためには、それぞれで考える方がわかりやすいため、まずは注文エンティティから。

理解に苦しだ、複数商品を1度にまとめて注文するようなものは、『まとめ部分と個別内訳部分』に分けて考えるとよくて、見出し明細形式やマスターディテール形式と呼ばれるらしい。

image.png

次は、リソースを抜き出す(誰が、何を)。今回の例だと、『誰が』という部分は意味持たないと思っていたけど、そういう場合は抽出不要らしい。データベースは事実を記録するので、意味を持たない部分は記録不要みたいな感じか🤔よって、『何を』を考えると、商品エンティティが出てくる。

image.png

商品エンティティもセットメニューのようなものがあるので、見出し明細形式として考えられそうだが、セット商品と単品商品を同時に頼むこともあるので、セット商品も単品商品として捉えて次のようなエンティティにする。

image.png

また、セット商品も単品商品の組み合わせなので、複数の商品の組み合わせに対して単品としてエンティティを構成しないといけない。つまり、セットメニューに付与された商品ID(複数商品用)と、そのセットを構成する商品ID(単品用)を一緒に扱わなければならないので、商品ID属性を2つ持つ必要がある。

image.png

次にレシートを見ると、『POS#』と『EatIn』の文言があり、今まで出てきたエンティティの属性には、はまらないので、それぞれエンティティ化する。

image.png

だいたいエンティティと大枠ができたら、属性を追加していく。まずは、わかりやすい注文テーブルから。

image.png

次に商品テーブル。商品テーブルには当該商品がセットかどうかを見分ける区分を追加しておく。

image.png

残ったやつには、当該テーブルを示す要素を追加する。

image.png

次に、『お金を預かる』部分を考える。注文エンティティに入れてしまうというパターンもあるようだが、参考書では入れずに別のイベントとして捉えている。

image.png

最後に、それぞれの関係と多重度を考えて、結びつけていく。

image.png

自分もセット構成までたどり着けたのはよかったが、自己参照(再帰)の部分を理解していなかったのでなかなか難しいと感じました。😅

参考