[DBデザイン#13] 実例から考える: 関係と意味

前回の記事では、納品書をもとに、そこからそこから1対多の関係見つけました。何度も出ていますが、1対多の関係、あるいは1対1の関係を見つけるというのが設計での大きな目標でもあります。この関係は、双方向で見たときに1対多なのか1対1なのかを判断します。そして、多くの場合は、1対多の関係は、異なる表で表現することが可能です。言い換えれば、異なる表で表現する方が効率が良い場合はもちろんですが、異なる表に表現しないと記述ができないような場合もあります。1対1の場合は、同一の表にまとめられるということが一般的です。つまり、関係を導くことで、データベースの設計として記述可能な関係性が得られるのです。

ここで、販売明細はいきなりこれは表だからという理由をつけましたが、もう少し詳細に考えてみると、例えば、商品名は「いろいろな商品がある」のだから、納品書に対して商品名は、1対多の関係になります。また、同様に単価もそうです。単価の場合、偶然異なる製品で同一価格ということもあるかもしれませんが、商品ごとに単価は異なるという原則を考えれば、納品書と単価も1対多です。そして個数はどうでしょうか?個数は整数なので、全部1ということもあるかもしれませんが、同一の商品を考えてもその時々、つまり納品書によって個数が違うことを考えれば納品書に対して1対多です。前回の図の1つを再掲しましょう。この図は次回もきっと登場します。

ただ、販売明細を1対多で考えるのはちょっと分かりづらいのですが、ここで重要なことは、商品名・単価・個数という情報が1塊となっている点です。この3つの組み合わせに、納品書がどれかという情報を付け加えると、原則として、システムに2つとないセットになります。これは、通常は納品書の明細に商品が重複して登場しないことを原則としています。実はこの考え方は集合論の定義でもあるのですが、それはさておいて、商品名・単価・個数は一塊なので、その塊を表の1行として、つまり1レコードとして把握して、納品書と販売明細は1対多の関係にあるということを導き出します。その1対多の関係を実現するために、「納品書ID」という方法で、販売明細の各行がどの納品書に結合するのかを記録するという方法が一般的です。

このように、表になってしまったものを個別で考えるとかえって分かりにくいかもしれません。「表として整っている」ということをまずはヒントとして使い、その中で、各データがどんなふうに振る舞うのかを考えることがポイントになります。

販売明細の金額は、「単価×個数」で求められます。ということであれば、金額は、販売明細の1レコード内の情報から求められる「計算フィールド」ということになります。SQLでは、ビューを使う方法が一般的です。FileMakerだと計算フィールドという機能があります。つまり、金額は、販売明細の一員として扱えるということが成り立ちそうなので、販売明細のフィールドとします。ただし、SQLの世界では、計算フィールドという考え方がないので、設計上は式を考えておくのが理想的ではありますが、SQLでのテーブル定義には計算フィールドは登場しないので、ER図に明示しづらいとも言えます。いずれにしても、商品名や個数のような、実データに関わるフィールドではないということを意識できるようにしておくのが設計上は重要です。一般には途中の段階でどこに計算式を実装するかを検討することになるからです。

一方、合計や消費税などはどうでしょうか? これらは納品書に1つなので、納品書と1対1に対応することから、合計は、納品書に存在するフィールドと考えられます。しかしながら、これも計算で求められそうです。販売明細の金額の合計で求められるので、計算フィールドであると言えるでしょう。ただし、この場合は、納品書の側にあるにもかかわらず、販売明細のデータを使って計算が必要です。ここで2つの表が関係していないと、販売明細のどのデータを使って計算すればいいかが分かりません。逆に、納品書から見て関連している商品明細、つまり納品書の明細リストにあるものが取り出せなければなりません。もちろん、これは、「納品書ID」が同一のものを検索することで取り出すことができます。リレーショナルデータベースではこのような関連を利用して、別のテーブルのデータを取り出し、計算結果を示すということも可能です。こうした機能があるので、「合計」は納品書のフィールドとして存在可能ということになります。ただし、関連する表との関連が確実に取れないといけないということになります。その前提の上で、式を記述することができるのです。

今回は細かいことをあれこれ書いていますが、実際の設計では、慣れた方はこのような内容はおそらく反射神経的に理解はしているところです。むしろそこをすっ飛ばさないと細かいところに気も時間も取られて前に進めないと思われるところでしょう。ですが、1つ1つの事象が何を意味しているのかをしっかり吟味しないと、やはり見落としが出てきます。そうした作業の中で、システムが扱う世界の1対多の関係を発見していくという作業が、データベースの設計においては重要なことになるのです。