設計の全体像

設計は3回、粒度を変えて行う

前回、1枚の表に全部入れると事実が割れることを見ました。では、どうやって分ければいいのか。行き当たりばったりに分けるのではなく、粗いところから細かいところへ、3回に分けて決めていきます。

工程決めること成果物
概念設計何を管理するのかエンティティの一覧
論理設計どんな項目を持ち、どう関係するのかER図・列と関係の一覧
物理設計どのデータベースに、どんな型で作るのかCREATE TABLE 文

概念設計 — 名前だけ決める

最初は、扱うものの名前を並べるだけです。多店舗ECなら「店舗」「商品」「顧客」「注文」「在庫」といったところでしょう。

この段階では列も型も考えません。紙とペンで足りるのが概念設計です。ここで挙げ漏らしたものは、あとの工程で全部やり直しになるので、粗くても広く挙げます。

論理設計 — 項目と関係を決める

次に、それぞれが何を持つかを決めます。店舗なら「店舗名」「都道府県」。そして、店舗と注文はどう繋がるのかを決めます。

ここでもまだデータベース製品の話は出てきません。PostgreSQL だろうと MySQL だろうと、論理設計の結果は同じになります。

物理設計 — 型とキーを決める

最後に、実際に動くものにします。「店舗名」は text なのか varchar(100) なのか。id は integer なのか bigint なのか。ここで初めてデータベース製品の都合が入ってきます。

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

なぜ分けるのか

いきなり CREATE TABLE から書き始めると、必ず手戻りします。型を決めながら「そもそもこのテーブルは要るのか」を考えることになり、頭が2つのことを同時に処理できないからです。

工程を分けるのは、一度に1種類のことだけ決めるためです。

NOT NULL は論理設計の結論

もうひとつ大事なのが NOT NULL です。これは「この項目は必ず値がある」という論理設計の結論を、物理設計の書き方に落としたものです。

店舗名は必ずあります。しかし開店日は、これから開く店なら未定かもしれません。だから opened_on には NOT NULL を付けません。値が無いことを許すかどうかは、型と同じくらい大事な設計の決定です。

手を動かす

概念設計で挙げた「店舗」を、物理設計まで一気に進めてみます。そのうえで、自分が作ったテーブルの姿をデータベース自身に聞いてみます。

テーブル構造

-- まだ何もありません。ここに最初のテーブルを作ります。

期待される出力

column_namedata_typeis_nullable
idintegerNO
nametextNO
preftextNO
opened_ondateYES

ヒント

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