属性の洗い出し
器に中身を詰める
前回、5つの器を並べました。今回はそこに列を入れていきます。この「エンティティが持つ項目」を属性と呼びます。
属性を決めるときに考えることは、次の3つです。
- 何を持つか — 要件文に出てきた性質を拾う
- どんな型か — 数えるものか、文字か、日付か、はい/いいえか
- 値が無いことを許すか —
NOT NULLを付けるかどうか
商品の属性を決める
要件文をもう一度見ます。「取り扱う商品には価格とカテゴリがあり、販売終了した商品も記録として残します」。
ここから拾えるのは価格とカテゴリ、そして「販売終了かどうか」です。名前は明示されていませんが、商品に名前が無いと使い物にならないので当然要ります。要件文に書いていない当たり前の項目は、自分で補う必要があります。
| 属性 | 型 | NOT NULL |
|---|---|---|
| id | integer | 主キー |
| name | text | 付ける |
| price | integer | 付ける |
| category | text | 付ける |
| is_active | boolean | 付ける |
型を選ぶ
価格を integer にするか numeric にするかは、よく迷うところです。円だけを扱い、小数が出ないなら integer で足ります。消費税の内訳や外貨を扱うなら numeric が要ります。今回は税込みの円だけなので integer にします。
「販売終了した商品も残す」は boolean になります。 販売終了したら行を消す、という設計にしてしまうと、過去の注文がどの商品だったのか分からなくなります。消さずに is_active を false にする。これを論理削除と呼びます。
途中から列を足す
すでにあるテーブルに列を足すときは ALTER TABLE を使います。
ALTER TABLE products ADD COLUMN name text NOT NULL;設計は一発では決まらないので、この文は現場で何度も打つことになります。ただし行がすでに入っているテーブルに NOT NULL の列をいきなり足すことはできません。既存の行にどんな値を入れればいいのか、データベースには分からないからです。その場合は DEFAULT を一緒に指定します。
いまは行が1件も入っていないので、そのまま足せます。設計の変更は、データが入る前ほど安いということです。
手を動かす
products に4つの列を足して、商品エンティティを完成させます。
テーブル構造
CREATE TABLE stores (
id integer PRIMARY KEY,
name text NOT NULL,
pref text NOT NULL,
opened_on date
);
CREATE TABLE products (id integer PRIMARY KEY);
CREATE TABLE customers (id integer PRIMARY KEY);
CREATE TABLE orders (id integer PRIMARY KEY);
CREATE TABLE inventories (id integer PRIMARY KEY);
期待される出力
| column_name | data_type | is_nullable |
|---|---|---|
| id | integer | NO |
| name | text | NO |
| price | integer | NO |
| category | text | NO |
| is_active | boolean | NO |