どの電話番号が正しいのか
大阪の物流資材の会社では、受注をExcelの1枚の表で管理しています。
1行が1件の注文で、取引先の名前と電話番号も毎回書いています。
ある日、丸山商店の電話番号が変わりました。担当者は、最新の1行だけを直しました。翌月、別の担当者が古い番号に電話をかけ、つながりませんでした。
このレッスンのゴール
メモ
データをテーブルに分けて、1つの事実を1か所にだけ保存することができる。
キーワード
| ことば | いみ |
|---|---|
| 重複 | 同じ事実が何か所にもあることです。 |
| 不整合 | 同じはずの値が、場所によって違うことです。 |
| 正規化 | 重複がないようにテーブルを分けることです。 |
| NoSQL | 表の形にこだわらないデータベースです。 |
| ドキュメント | 1件のデータを、まとまった形で保存したものです。 |
学生が入力するセルは、このプレビューでは空白です。
同じ事実を何度も書くと食い違う
1枚の表では、丸山商店の電話番号が、注文の数だけ書かれています。これが重複です。
番号が変わったら、全部の行を直さなければなりません。1行でも直し忘れると、番号が2つになります。これが不整合です。
次のクエリで、実際に食い違いを見つけてください。
試そう: 食い違いを探す
-- 丸山商店の電話番号は、いくつ登録されていますか。
SELECT id, customer, phone FROM order_list WHERE customer = '丸山商店';
-- 電話番号の種類を数えます。2と出たら、食い違いがあります。
SELECT COUNT(DISTINCT phone) FROM order_list WHERE customer = '丸山商店';
取引先の表と注文の表に分ける
取引先の名前と電話番号は、取引先の事実です。品物と数量は、注文の事実です。
そこで、customers と orders の2つの表に分けます。注文の表には、取引先の番号 customer_id だけを書きます。
こうすると、電話番号は1か所にしかありません。直すのも1行だけです。このように分けることを、正規化といいます。
試そう: 分けた表をつなぐ
-- 電話番号は customers に1回だけあります。
SELECT * FROM customers;
-- 注文と電話番号を一緒に見るときは、JOIN でつなぎます。
SELECT orders.id, customers.name, customers.phone, orders.item
FROM orders
JOIN customers ON orders.customer_id = customers.id;
-- customers の丸山商店の電話番号を変えたと考えてください。
-- 直すのは1行だけで、すべての注文に反映されます。
よくある間違い
注意
「表は細かく分けるほど、よい設計だ」と思う人がいます。そうとは限りません。分けるほど、読むときのJOINが増えます。同じ事実が何度も出てくるときに分けます。売上の集計表のように、読む速さを優先して残すこともあります。
NoSQLが合う場面
表の形に合わないデータもあります。例えば、通販の商品です。服にはサイズと色があり、家電には消費電力と保証期間があります。
こうした項目がばらばらなデータは、1件ずつまとまった形で保存すると扱いやすくなります。これをドキュメントといい、MongoDBのようなNoSQLのデータベースが使います。
お金や在庫のように、正確さが大切なデータには、表のデータベースが向いています。
比べよう: 表とドキュメント
| 表のデータベース | ドキュメント型のNoSQL | |
|---|---|---|
| 形 | どの行も同じ列 | 1件ごとに項目が違ってよい |
| 得意なこと | JOINと集計、振込 | 形がばらばらなデータ |
| 向いている例 | 受注、口座、在庫 | 商品カタログ、操作の記録 |
学生が入力するセルは、このプレビューでは空白です。