データをあるべき場所に置く
ほかに 28 言語で読めます
English · Español · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

モジュール4/6:Data Architectコース第2章「意味のあるデータモデリング」。各モジュールは単独でも読めます。 前へ:論理モデルを作る · 次へ:第3正規形まで設計し、それから戻す
このモジュールが答える問い: 正規化は、データが本当はどこに属するのかを見極めるのにどう役立つのか?
論理モデルができました。エンティティ、関係、属性、キー。ここで、データモデリングで最も大切な問いの一つを立てたいと思います。このデータは本当にここに属しているのか?
シンプルに聞こえますが、そうではありません。項目の一つひとつが、作られた時点では筋が通っていたシステムをたくさん見てきました。問題は、項目がばかげていたことではなく、事実が間違った場所に保存されていたことでした。配送が、本当は物流センターを記述している情報を持っている。同じ住所が何百ものレコードに現れる。一つの項目にカンマ区切りで3つの値が入っている。ビジネス上の一つの事実を変えると、1万件のレコードを更新しなければならない。それが正規化が解決を助けてくれる問題です。データベースの用語に埋もれる前に、全体の考え方を示しておきましょう。事実を、それが属する場所に置く。 このモジュールのほかの部分は、それをより体系的に行うためのものです。
正規化とは何か?
Section titled “正規化とは何か? ”正規化とは、それぞれの事実が、それが属する場所に一度だけ保存されるようにデータを整理することです。1つのテーブルが多くの役目を担いすぎているとき、それぞれが一つのものを記述するテーブルに分け、キーでつなぎます。
なぜそうするのか? 一度だけ保存された事実は、一度だけ変更すればよいからです。正規化は、同じ事実が多くのレコードにコピーされる冗長性を防ぎ、それとともに、あるコピーは更新されて他のコピーは更新されないときに入り込む不整合も防ぎます。だからこそ、レコードが一日中作成され更新されるSalesforceのようなトランザクションシステムに合うのです。
正規化は正規形と呼ばれる段階を踏んで進めます。それぞれの段階が、一つの問いを投げかけます。
- 第1正規形(1NF): 1つの項目に1つの値。そして、すべての行を一意に識別するもの。
- 第2正規形(2NF): すべての事実が、行を識別するものの一部ではなく、全体を記述している。
- 第3正規形(3NF): すべての事実がこのものを記述していて、それと関係する別のものを記述していない。
第3正規形の先にも正規形はあります。それについて、そしてなぜ普通は第3正規形で止めるのかについては、後で少し触れます。まずは、3つのステップが起きる様子を見てみましょう。
なぜ正規化するのか?
Section titled “なぜ正規化するのか? ”ライブで教えるとき、私は配送からは始めません。犬から始めます。犬のことは誰でもわかるので、ビジネスに気を取られる人はいません。そしてデータが自分の居場所を探そうとする様子を見ていけるのです。それから、同じ手順をSteve Truckingに当てはめます。
おすわり、まて、モデル
Section titled “おすわり、まて、モデル ”出発点:生のスプレッドシート。 私が何匹かの犬を画面に出し、それから教室の皆さんが自分の犬を加えます。数分で大きなリストが一つできあがります。犬、生まれた年、飼い主、飼い主の住んでいる場所、犬種、ブリーダー、そして覚えている芸。
| 犬 | 生年 | 飼い主 | 郵便番号 | 都市 | 犬種 | ブリーダー | 芸 |
|---|---|---|---|---|---|---|---|
| ベラ | 2017 | マーカス | 80202 | デンバー | ラブラドール | Maple Ridge | おすわり、まて、お手 |
| マイロ | 2019 | マーカス | 80202 | デンバー | プードル | Golden Meadow | おすわり、ごろん |
| マックス | 2022 | アナ | 64105 | カンザスシティ | ミックス | おすわり、死んだふり | |
| ルナ | 2020 | ケンジ | 98101 | シアトル | ハスキー | Cascade | おすわり、まて、スピン |
| ロッキー | 2024 | プリヤ | 30301 | アトランタ | ビーグル | Maple Ridge | おすわり |
| ココ | 2014 | アナ | 64105 | カンザスシティ | チワワ | Little Paws | お手、スピン |
これで動きます。どんなスプレッドシートも初日は動きます。でも、すでに何がおかしいかを見てください。お手ができる犬をすべて見つけるにはどうすればいいでしょう? アナの郵便番号は2行にあり、マーカスのも同じです。誰かが片方だけを更新したらどうなるでしょう? Maple Ridgeは2回出てきますし、カンザスシティもそうです。そしてマックスは保護施設から来たので、ブリーダーがまったくいません。
ステップ1:第1正規形。 ルールは2つです。各項目は1つの値だけを持つので、カンマで並べた芸のリストはやめなければなりません。そして各行には、それを一意に識別するものが必要です。 犬の名前ではありません。マックスという名前の犬はたくさんいます。IDです。自動生成されるIDか、GUIDです。芸はそれぞれの行に分けられ、犬と芸の組み合わせごとに1行になります。そして芸が自分の行を持てば、カンマ区切りのリストでは言えなかったことを書く余地ができます。その芸がどれくらい難しいか、この犬がどれくらい上手にできるか、そしていつ覚えたか。
犬(犬IDで識別)
| 犬ID | 名前 | 生年 | 飼い主 | 郵便番号 | 都市 | 犬種 | ブリーダー |
|---|---|---|---|---|---|---|---|
| D-001 | ベラ | 2017 | マーカス | 80202 | デンバー | ラブラドール | Maple Ridge |
| D-002 | マイロ | 2019 | マーカス | 80202 | デンバー | プードル | Golden Meadow |
| D-003 | マックス | 2022 | アナ | 64105 | カンザスシティ | ミックス | |
| D-004 | ルナ | 2020 | ケンジ | 98101 | シアトル | ハスキー | Cascade |
| D-005 | ロッキー | 2024 | プリヤ | 30301 | アトランタ | ビーグル | Maple Ridge |
| D-006 | ココ | 2014 | アナ | 64105 | カンザスシティ | チワワ | Little Paws |
犬の芸(犬ID+芸で識別)
| 犬ID | 芸 | 難易度 | 習熟度 | 習得 |
|---|---|---|---|---|
| D-001 | おすわり | 易しい | 上級 | 2017-11 |
| D-001 | まて | 易しい | 上級 | 2018-01 |
| D-001 | お手 | 普通 | 良好 | 2018-06 |
| D-002 | おすわり | 易しい | 上級 | 2020-02 |
| D-002 | ごろん | 難しい | 練習中 | 2023-05 |
| D-003 | おすわり | 易しい | 良好 | 2022-06 |
| D-003 | 死んだふり | 難しい | 練習中 | 2024-03 |
| D-004 | おすわり | 易しい | 上級 | 2020-11 |
| D-004 | まて | 易しい | 良好 | 2021-01 |
| D-004 | スピン | 普通 | 上級 | 2021-06 |
| D-005 | おすわり | 易しい | 練習中 | 2025-02 |
| D-006 | お手 | 普通 | 上級 | 2015-06 |
| D-006 | スピン | 普通 | 練習中 | 2025-04 |
これで「お手ができる犬をすべて」は簡単な問いになりました。でも、犬の芸が何で識別されているかに注目してください。1つのものではなく、2つのものの組み合わせ、犬と芸です。これを覚えておいてください。
ステップ2:第2正規形。 第2正規形が意味を持つのは、行が組み合わせで識別されているときだけで、犬の芸はまさにそうです。そこで、すべての列にこう問います。それは組み合わせ全体を記述しているのか、それとも一部だけか? 習熟度は、この犬がこの芸をすることを記述しています。ベラはおすわりの上級者で、ロッキーはまだ練習中です。習得も同じです。でも難易度は? おすわりはどの犬がやっても易しい芸です。それは芸を、つまりキーの一部だけを記述しています。だから、おすわりのどの行にも「易しい」が繰り返されているのです。そこで芸は独自のテーブルを持ち、残るのはペアです。
芸
| 芸ID | 芸 | 難易度 |
|---|---|---|
| T-01 | おすわり | 易しい |
| T-02 | まて | 易しい |
| T-03 | お手 | 普通 |
| T-04 | ごろん | 難しい |
| T-05 | 死んだふり | 難しい |
| T-06 | スピン | 普通 |
犬の芸(犬ID+芸ID)
| 犬ID | 芸ID | 習熟度 | 習得 |
|---|---|---|---|
| D-001 | T-01 | 上級 | 2017-11 |
| D-001 | T-02 | 上級 | 2018-01 |
| D-001 | T-03 | 良好 | 2018-06 |
| D-002 | T-01 | 上級 | 2020-02 |
| D-002 | T-04 | 練習中 | 2023-05 |
| D-003 | T-01 | 良好 | 2022-06 |
| D-003 | T-05 | 練習中 | 2024-03 |
| D-004 | T-01 | 上級 | 2020-11 |
| D-004 | T-02 | 良好 | 2021-01 |
| D-004 | T-06 | 上級 | 2021-06 |
| D-005 | T-01 | 練習中 | 2025-02 |
| D-006 | T-03 | 上級 | 2015-06 |
| D-006 | T-06 | 練習中 | 2025-04 |
この犬の芸のテーブルは、モジュール2で見つけたものです。データモデリングでは名前があります。連結、あるいは私の呼び方では論理的な連結オブジェクトです。1匹の犬は多くの芸を覚えていて、1つの芸は多くの犬に覚えられています。連結はその間に位置しますが、空っぽの配管ではありません。関係そのものに属する事実、つまり習熟度と日付を持っています。モジュール6でまた出会います。そして第3章では、Salesforceが「連結オブジェクト」をもっと狭い意味で使っていることを見ます。Salesforceの連結オブジェクトとは、2つの主従関係を持つカスタムオブジェクトです(第3章、モジュール7)。
ステップ3:第3正規形。 では犬のテーブルに戻りましょう。そこにあるものはすべて犬IDで識別されているので、第2正規形には言うことがありません。第3正規形は別の問いを投げかけます。この事実は犬を記述しているのか、それとも犬と関係する別のものを記述しているのか? 犬種はそれ自体が一つのものです。どの犬であってもラブラドールはラブラドールで、大きさのようなそれについての事実は、ベラではなく犬種に属します。郵便番号と都市は、犬ではなく飼い主を記述しています。どちらの犬を見ていても、それはアナが住んでいる場所です。ブリーダーの詳細はブリーダーを記述しています。どれも別の事実についての事実なので、それぞれ独自のテーブルに移り、犬は外部キーでそれを指し示します。
- 犬: 犬ID、名前、生年、飼い主ID、犬種ID、ブリーダーID
- 飼い主: 飼い主ID、名前、郵便番号、都市
- 犬種: 犬種ID、犬種、サイズ
- ブリーダー: ブリーダーID、名前、都市
- ステップ2からの芸と犬の芸
これでアナは一度だけ保存され、彼女の2匹の犬が両方とも彼女を指し示しています。Maple Ridgeも一度だけ保存され、犬種のテーブルは、大きさのような各犬種についての事実の置き場所を与えてくれます。スプレッドシートにはそれを置く場所がありませんでした。外部キーは空欄でもかまいません。マックスにはブリーダーIDがありませんが、それは正直な答えであって、抜けではありません。そこで私は教室にひっかけ問題を投げます。飼い主が犬を迎えた日付は、どこに置くでしょう? 犬にです。このモデルでは犬の飼い主は一度に1人なので、その日付は犬と飼い主の関係を記述しています。
もう一歩進めて、郵便番号から都市を切り離すこともできます。教科書ではそうします。実際には住所はひとまとまりのままにしますし、そもそもカンザスシティは2つの州にまたがっています。現実の世界は私たちの教科書を読んでくれない、というよい教訓です。
これが流れです。スプレッドシート、それから3つの問い、そしてすべての事実が一つの場所に落ち着きます。一歩下がって、作ったものを見てください。散らかった1つのリストが6つのテーブルになりました。それぞれが一つのものを記述し、キーでつながっています。
ここまで、Salesforceの言葉は一つも必要ありませんでした。犬と、その周りの人たちと、犬が覚えていることだけです。
ではSteve Truckingに当てはめてみましょう
Section titled “ではSteve Truckingに当てはめてみましょう ”犬なら手順が見えやすくなります。本物のビジネスでは、手順が重要になります。同じ間違いが、規模が大きくなると本物のお金を失わせるからです。そこで、同じ3つの問いをSteve Truckingに持っていきましょう。配送をこんなふうに管理しているとします。
| 配送 | 小売パートナー | 物流センター | 物流センターの所在都市 | クルー | トラック |
|---|---|---|---|---|---|
| 1001 | Keystone | Keystone Phoenix DC | Phoenix | Crew 12 | 117 |
| 1002 | Keystone | Keystone Phoenix DC | Phoenix | Crew 8 | 122 |
| 1003 | Keystone | Keystone Phoenix DC | Phoenix | Crew 12 | 117 |
一見、複雑なところは何もありません。でも物流センターを見てください。そこから出るすべての配送に「Keystone Phoenix DC、Phoenix」を繰り返しています。Steve Truckingは9つの物流センターで1日約3,300件の配送をしているので、それぞれから1日数百件です。その物流センターが移転したらどうなるでしょう? 何件のレコードを変え、一つ漏れたらどうなるでしょう? データは、物流センターが同時に2つの都市にあると言い出します。それが更新時異状です。最初の配送の前に新しい物流センターを登録したいときは? ある物流センターの最後の配送を削除したら、その物流センターについて何かを保存していた唯一の場所を削除してしまったのでは?
これらは同じ問題の異なる症状です。異なるものについての事実を混ぜてしまったのです。物流センターの事実は物流センターに属します。配送の事実は配送に属します。クルーの事実はクルーに属します。実践的な言葉で言えば、それが正規化です。
第1正規形:繰り返しの構造を隠さない
Section titled “第1正規形:繰り返しの構造を隠さない ”第1正規形、つまり1NFから始めましょう。ここで正規化を必要以上に難しくしてしまう人がいます。
配送に「品目」という項目があるとします。「冷蔵庫、製氷機キット、引き取り」。3つの情報を一つの項目に入れています。便利に見えます。誰かが「先月、引き取りは何件あった?」と尋ねるまでは。あるいは品目1、品目2、品目3という項目を想像してください。それでうまくいきます。品目が4つある配送が来るまでは。問題は、品目項目の数を間違えたことではありません。繰り返しの構造に気づかなかったことです。1つの配送には複数の品目があり得ます。それはモデリングすべきデータです。モジュール2で見つけた配送品目です。
1NFの実践的な教訓は、繰り返しの構造を項目の中に隠さないことです。何かが何度も起こり得るとビジネスが言ったら、耳を傾けましょう。外に出ようとしている別のエンティティがあるかもしれません。
実際の組織では、これをいつも目にします。誰かが複数の言語で説明を必要とし、Description_Englishという項目を作り、次にDescription_French、次にDescription_Germanを作ります。あるいは承認に何人か必要で、承認者1、承認者2、承認者3ができます。レビューでこれを見つけたら、手をぴしゃりと叩いて、データモデルを直してもらいます。1つか2つなら、ビジネスに本当に1つか2つしかないなら、まあいいでしょう。それを超えるなら子オブジェクトにすべきです。言語を持つ翻訳レコード、承認者を持つ承認ステップ。次の言語や4人目の承認者は、新しい項目とデプロイではなく、新しいレコードになります。
第2正規形:全体を記述する
Section titled “第2正規形:全体を記述する ”第2正規形、つまり2NFが重要になるのは、レコードが複数のものの組み合わせで識別されるときです。配送品目を例にとりましょう。独自のレコードIDを持っていますが、それぞれは配送+製品で一意です。配送、製品、数量、そして製品の説明を保存するとします。
数量はここで筋が通ります。この配送におけるこの製品を記述しているからです。しかし製品の説明は組み合わせを記述していません。製品を記述しています。それをすべての配送品目に置けば、その冷蔵庫のモデルが別のトラックで出ていくたびに繰り返すことになります。それが、その事実はどこか別の場所に属するという手がかりです。
ですから2NFの問いは、**この属性は、識別している全体を記述しているのか、それともその一部だけか?**です。製品だけを記述しているなら、製品と一緒に置きます。この特定の配送の中での製品の位置づけ(数量、設置するかどうか)を記述しているなら、配送品目に属します。多くの管理者は、「今、第2正規形を適用している」と意識して言うことはないでしょう。それでかまいません。私がずっと大切にしているのは、**この事実は実際に何を記述しているのか?**と問えるようになることです。
第3正規形:ほかの事実についての事実を保存しない
Section titled “第3正規形:ほかの事実についての事実を保存しない ”では、日々のモデリングで私が最も大切にしているものです。第3正規形、つまり3NFです。
各物流センターには、小売パートナー側の責任者がいます。パートナーポータルを使う人です。物流センターの責任者の名前を、すべての配送に直接置くとします。物流センターに新しい責任者が来たらどうなるでしょう? その物流センターからのすべての配送を更新します。また同じにおいがします。どこか別の場所に属する事実を繰り返しているのです。配送は物流センターから出発し、物流センターには責任者がいます。それは2つの関係であり、責任者の名前は物流センターに属します。
教科書の典型例は住所です。郵便番号、市、州がすべてのレコードに一緒に保存されていますが、市と州はたいてい郵便番号から決まります。同じ形、同じ問いです。
3NFの実践的な問いは、**この事実はこのものを記述しているのか、それともこのものが関係している別の何かを記述しているのか?**です。いつもこれを問うようにしてほしいのです。
では、犬のときと同じように一歩下がってみましょう。最初の配送テーブルは5つのものになり、それぞれが自分の事実を持っています。配送品目は第1正規形で、製品は第2正規形で切り出され、物流センターの所在都市と責任者は第3正規形で物流センターに移りました。
同じ3つの問い、同じ結果。すべての事実が一つの場所にあります。
1NF、2NF、3NFのシンプルな考え方
Section titled “1NF、2NF、3NFのシンプルな考え方 ”正規化だけでデータベースの講座を丸ごと一つ使うこともできます。ここではそうしません。このコースでは、実務のアーキテクトとしての理解を持ってほしいのです。
- 1NF: 項目やレコードの中に、複数の値や繰り返しの構造を隠していないか?
- 2NF: この事実は、識別している全体を記述しているか?
- 3NF: この事実は本当にこのエンティティを記述しているのか、それとも関係している別の何かを記述しているのか?
これはデータベースの教科書のための定義ではありません。設計しながら実際に使える問いです。
もちろん正規化にはその先があります。**ボイス・コッド正規形(BCNF)**は、より複雑なキーを持つモデルのために3NFのルールを厳しくしたもので、第4、第5、さらには第6正規形もあります。これらはもっとまれな種類の繰り返しを扱います。日々のビジネスのレコードよりも、珍しいキー構造から生じる種類のものです。理論はたくさんありますが、私の経験では、Salesforceの上に作るようなシステムでは頭を悩ませる価値はありません。ビジネスシステムでは、圧力はたいてい逆向きに働きます。第3正規形を超えるよりも、ユーザー、レポート、パフォーマンスのために第3正規形から戻すことのほうがずっと多いのです。それが次のモジュールです。その先の正規形があることは知っておきましょう。でも、私たちがすることのほとんどには、1NFから3NFまでで必要な考える道具がそろいます。
第3正規形を目指して設計する
Section titled “第3正規形を目指して設計する ”私の立場はこうです。ビジネスを理解し、その論理モデルを設計しようとしているときは、きれいな状態から始めたいのです。配送の事実は配送に、物流センターの事実は物流センターに、トラックの事実はトラックに、繰り返す概念は概念としてモデリングする。画面やレポートが楽になるかもしれないというだけで、ビジネス上の事実をモデルのあちこちにコピーしたくはありません。まだ、です。
しかし正規化は宗教ではありません。目的は、学術的に可能な限り純粋なモデルではありません。純粋さに夢中になりすぎて、使わなければならない全員にとってモデルが苦痛になってしまったアーキテクトを見てきました。私たちは正規化コンテストで勝とうとしているのではありません。システムを作っているのであり、そのシステムにはユーザー、レポート、連携、性能のニーズ、規模があり、そしてますますデータを読むAIがあります。それらはデータを別の形でほしがるかもしれません。
ですから私の出発点は、可能なところでは第3正規形まで設計し、必要なときには戻すことです。まず、それぞれの事実がどこに属するかを理解します。そして、そこから外れるなら、その理由を知りたいのです。答えが「その項目をほかにどこに置けばいいかわからなかったから」なら、それでは不十分です。答えが「パートナーのスコアカードがシンプルになるので意図的にこの値をコピーした。同期を保つ確実な方法もある」なら、アーキテクチャの会話をしていることになります。
ここでアーキテクトが決めること
Section titled “ここでアーキテクトが決めること ”論理モデルを正規化するとき、私が探しているのは次のものです。
- 別にモデリングすべき、繰り返しの値や構造。
- 保存されているエンティティとは別のエンティティを記述している属性。
- 多くのレコードに不必要に重複している事実と、それを食い違わせる依存関係。
- 項目の中に隠れているビジネス概念。
- 実装上の妥協をする前に、真実を表すきれいなモデル。
すべての物理システムが完璧に正規化されたままでなければならないから、ではありません。まったく逆です。次のモジュールでは、ユーザー、レポート、規模、分析、AIのために、きれいなモデルから意図的に離れます。そして、何と引き換えにしているのかを正確にわかった上でそうするのです。
