要件からエンティティ抽出

要件文はこれです

設計の出発点は、いつも日本語の文章です。今回の要件は次のものです。

マイショップ・チェーンは、全国に店舗を持つ小売チェーンです。各店舗は都道府県と開店日を持ちます。取り扱う商品には価格とカテゴリがあり、販売終了した商品も記録として残します。顧客は会員登録してから注文します。注文は必ずどこかの店舗で行われます。どの店舗にどの商品が何個あるかという在庫も管理します。

名詞を拾う

エンティティ候補を見つける最初のやり方は単純で、要件文の名詞に印を付けることです。上の文なら、店舗・都道府県・開店日・商品・価格・カテゴリ・顧客・注文・在庫、といったところが拾えます。

拾った名詞をふるいにかける

拾った名詞すべてがエンティティになるわけではありません。判断の軸は次の2つです。

それ自体が独立して存在するか。 店舗は、注文が1件も無くても店舗として存在します。一方「都道府県」は、店舗の性質を説明しているだけで、それ単体で管理したいものではありません。こういうものは属性であって、エンティティではありません。

複数個あって、1件ずつ区別したいか。 商品は何千件もあり、1件ずつ区別します。「価格」は商品の性質なので、価格だけを1件ずつ区別することはありません。

このふるいを通すと、次のように分かれます。

拾った名詞判定
店舗エンティティ
都道府県・開店日店舗の属性
商品エンティティ
価格・カテゴリ商品の属性
顧客エンティティ
注文エンティティ
在庫エンティティ

迷ったら残す

「在庫」はどちらとも取れます。商品の属性として「在庫数」を持たせる手もあるからです。しかし今回は店舗ごとに在庫が違うので、商品の属性にはできません。店舗と商品の組み合わせごとに1件あるので、エンティティとして立てます。

判断に迷ったときは、いったんエンティティとして残します。あとで属性に降格させるのは簡単ですが、挙げ忘れたものは気づけないからです。

名前は英語の複数形にする

テーブル名は storesproducts のように英語の小文字・複数形にします。理由は3章で扱いますが、いまは「1つの表には複数件入るから複数形」とだけ覚えてください。

手を動かす

5つのエンティティを、仮のテーブルとして書き出します。この段階では列は id と名前だけで構いません。器を先に並べて、中身は次回に詰めます。

テーブル構造

CREATE TABLE stores ( id integer PRIMARY KEY, name text NOT NULL, pref text NOT NULL, opened_on date );

期待される出力

table_name
customers
inventories
orders
products
stores

ヒント

query.sql
学習モード
コードの実行結果
データベースを初期化中...