[DBデザイン#21] 関係の概念:1対多を理解する

今回から数回に分けて、改めて関係の概念を整理しましょう。理解すべきことは、1対多、1対1、そして多対多がどんな状況なのかということです。すでに何度も説明している通り、リレーショナルデータベースは表形式のデータを多数扱うことが得意であり、複雑なデータは複数の表にうまく分割することで扱うことができるのです。そこで、システム化しようとしている世界の中で、特に1対多の関係にある表を見つけ出すことが非常に重要になります。ただ、そのためには、1レコードが何なのかということを決定しなければなりません。1レコードの基準が決まれば、それらが1対多なのかどうかということが決まりますが、実際の設計では、基準が揺らぎ、その都度検討は必要になります。つまり、決めたことが間違っていることもあるわけで、行きつ戻りつ設計は進むことになります。

今までのところで、いくつも1対多が出てきていますので、その概念を再掲しましょう。1つの商品が複数の販売機会において販売されるという事実を考えれば、商品と販売明細が、1対多の関係になります。それをER図的に示すとこう書きます。設計図自体は必要なことだけを記述してシンプルに記述する方が何かと便利なのですが、設計者はもちろん開発に関わる人たちはこれを逆に読み解けるようになっておかないといけません。線を引いてあるもの同士は原則として直接関係があり、この場合は、線で引かれることにより販売においては商品が指定されることを意味しているとも言えるでしょう。線の一方が烏の足跡のようになっていますが、それが「多」の側を示しています。「1」の側は単なる線です。この書き方は改めてまた説明しましょう。

ここで、それぞれの表で行が追加される状態、つまり、レコードが追加されていく様子を図にしてみました。前の図はER図なので、箱はエンティティ、つまり表の存在そのものを記述します。一方、以下の図はオブジェクト図的なもので、箱は1レコードと考えてください。ここでダイアグラムの解釈を切り替える必要がありますが、設計時にはそういう頭の切り替えは頻発します。これは慣れるしかなく、言い換えれば、それぞれの図の前提を把握した上で読解しないといけないということでもあります。このダイアグラムでのレコードとレコードの関連は、原則「1対1」を意味する単なる直線のみになりますが、1つのレコードから複数の線が引かれる点が「1対多」の意味になるのです。以下、レコードが何もないところからレコードが順次増えるということを想定して、表の中にあるレコードの関連を図にしています。

全ての商品は、何度も販売されるので、最後の商品Aのように、1つの商品が複数の販売明細に登場します。この事実が1対多の根拠です。商品Bを見れば、1つの商品に対して1つの販売明細2にだけ関係があるので、この商品だけを見れば1対1です。ですが、商品全体にわたって、1対多の関係を持つものがあれば、この関係は1対多と呼びます。いわば、1対多の可能性があれば、1対多であると認識するのです。実際どうなっているのかということよりも可能性で考えます。極端に言えば、レコードが全く存在しなくても1対多であると表現します。

実際にこうしたレコード間の関連をどうすれば構成できるのかについては、すでに説明していますが、この場合では以下のようになります。まず、1側の商品の表に、特定の商品を参照可能な「商品ID」のフィールドを確保します。商品の特定が可能になるには、商品の表の商品IDに重複があってはいけません。また、レコードとして同じ商品が複数の行に登場してはいけません。このような商品IDフィールドを主キーフィールドと呼びますが、キーフィールドの概念については改めて説明します。数値にするのは検索が安定しているからです。文字列だと全角だの半角だのということがあって間違いやすいから、一般には数値を使います。一方、多の側の販売明細でも、ここでは同じ名前の商品IDフィールドを用意しました。そして、商品名などを記載するのではなく、商品IDの値を書き込みます。ここでは商品Aは2つの販売で登場するので、商品IDフィールドには同じ値の101が2つのレコードに登場しますが、これがまさに「多」の意味でもあります。こうした主キーフィールドを参照するフィールドのことを外部キーフィールドとなどと呼びます。

ここでは商品の表が、主キー以外は商品名しか存在しないので、販売明細側の商品IDの代わりに商品名に置き換えれば、利用者が参照したい表の形式に近付くとも言えますが、正しくは以前に説明したように、販売明細の列が増えるのが表の結合の処理です。つまり、商品IDによって参照される商品の表の1レコードが、販売明細の右側に追加されるのです。この方法により、たくさんの販売明細から特定の商品が常に参照されることになります。こうした結合した表は、原則として一時的に作られて、例えば、明細一覧として画面に出ますが、通常はそれはその時に見せて終わりで、また次に同じ画面を呼び出すと、現状のデータに応じて結合した表を作り直し、画面に表示します。

ということで、1対多についてはほとんど復習のような感じですね。次回は1対1、そして引き続いて多対多についての説明を行いましょう。