つくる DDL一式完成
設計が動くことを確かめる
新しいことは出てきません。第5章までに決めたすべて、つまり構造・制約・名前・型・監査列を反映した DDL 一式が用意してあります。今回やるのは、そこにサンプルデータを流し込んで、設計どおりに動くことを確かめることです。
設計書の上では正しく見えても、実際にデータを入れてみると初めて気づくことがあります。
このテーブル、注文と一緒に入れる値が足りない。 この制約、正しいデータまで弾いてしまう。
これを本番の直前に見つけるか、設計の途中で見つけるかで、直す手間は桁違いです。サンプルデータを流すのは、設計のテストです。
流す順番も依存で決まる
作成順と同じ理由で、INSERT にも順番があります。参照先の行が無ければ、外部キーに弾かれます。
INSERT INTO orders VALUES (1, 1, 1, DATE '2026-04-01');
-- ERROR insert or update on table "orders" violates foreign key constraintこのエラーが出たら、設計が間違っているのではなく流す順番が間違っているだけです。マスタから先に、明細を最後に、と覚えます。
監査列は書かない
監査列には DEFAULT now() が付いているので、INSERT で値を渡す必要がありません。渡さない列がある場合は、列名を明示した書き方を使います。
INSERT INTO stores (id, name, pref) VALUES (1, '渋谷店', '東京都');列名を省いた INSERT INTO stores VALUES (...) はすべての列を定義順に渡すという意味なので、監査列まで渡さなければなりません。列を増やすたびに壊れるので、本番の INSERT では列名を必ず書きます。
確かめ方は集計で
データを入れたら、業務で実際に使う集計を1本流します。行が入ったことより、欲しい答えが出せることのほうが重要です。店舗別の売上が出せなければ、そもそも何のための設計だったのかという話になります。
手を動かす
サンプルデータを順番に流し、店舗別の売上を出します。
テーブル構造
CREATE TABLE prefectures (
pref text PRIMARY KEY,
region text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE categories (
id integer PRIMARY KEY,
name text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE customers (
id integer PRIMARY KEY,
name text NOT NULL,
email text NOT NULL,
joined_on date NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT customers_email_uk UNIQUE (email)
);
CREATE TABLE stores (
id integer PRIMARY KEY,
name text NOT NULL,
pref text NOT NULL REFERENCES prefectures (pref),
opened_on date,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE products (
id integer PRIMARY KEY,
name text NOT NULL,
price integer NOT NULL,
is_active boolean NOT NULL,
category_id integer NOT NULL REFERENCES categories (id),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT products_price_ck CHECK (price > 0)
);
CREATE TABLE orders (
id integer PRIMARY KEY,
store_id integer NOT NULL REFERENCES stores (id),
customer_id integer NOT NULL REFERENCES customers (id),
ordered_on date NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE order_items (
order_id integer NOT NULL REFERENCES orders (id),
product_id integer NOT NULL REFERENCES products (id),
quantity integer NOT NULL,
unit_price integer NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (order_id, product_id),
CONSTRAINT order_items_qty_ck CHECK (quantity > 0)
);
期待される出力
| store | total |
|---|---|
| 渋谷店 | 134400 |
| 梅田店 | 24000 |