テーブルの設計 その3”テーブルの正規化”
■ はじめに
今回から、本格的なテーブルの設計段階に入ります。
誰から教わったわけでもなく、とある本一つを読んで、自分なりに消化して、実践で徐々に磨いて、今に至るので、完全に自己流です。
正しい手法とは言えませんが、短期間で小規模なシステムを作る時の参考になればと思います。
なお、一般的なテーブルの正規化の目的と手法は・・・
| 正規化の目的
冗長性を排除
更新時の例外を回避
モデルを正確に表現
保守と検索をシンプルに
| 正規化の手法
統合
分割
複製
集計
では、前回の続きを。
■ 情報の名前と項目の内容が一致しているか?
テーブルの名前は、とても大切です。
テーブル名を読むだけで、どんなデータ(情報)が格納されているか妄想ができるように工夫してください。
オレンジの矢印のところに、データが格納されるので、格納する名前をもう一度考えます。
少し、考え直しした方が良さそうです。
まだ、仮段階ですが、名前を変更してみます。
(仮)ではありますが、とりあえずテーブル名を変更する。
いくつか「???」があります。
これは、システムを運用した後、
・何人で使用するのか?
・登録・更新・削除の頻度は?
・他のテーブルに与える影響は?
・開発難易度(開発期間)はOK?
・データの保存期間は?
・トラブル時のリカバリは?
これらの注意事項を、深く考慮して決定します。
でも、これを考えるのは後の話。
ここでは、とりあえず、必要なテーブルとして定義して進めていきます。
■ 項目の見直し
テーブルの名前と項目の名前に違和感がないかを確認します。
もし、違和感を感じたら、項目を移動させたり、新しいテーブルを作る構想をします。
先ずは、必要とされると判断したテーブルに対して項目を書いていきます。
ここで、テーブル定義書を書いていきます。
でも、まだまだ(仮)状態です。
間違っても良いの。兎に角、詳細を目で確認できるようにします。
■ ER図(仮)
でました。ER図。
この絵が描けないと、データの正確性、整合性、論理的、効果的なデータ設計ができません。
テーブル定義書(仮)で書いた項目をペタペタと貼り付けて、並べるだけで、なんと、ER図の完成?ですw
テーブル定義書ができれば、簡単な作業です。
こうやって、ER図を描くことによって、テーブルとテーブル間に、矛盾があったり、無駄があったり、色々可視化されていきます。
もう、アチコチ不自然です。
例えば、運賃を計算させるためには、運賃入力には、「都道府県」という項目が無いと計算できないことに気付くと思います。
そんな思考で、「○○を計算、○○を検索、○○を代入」には、どうするかを考えて、項目やテーブルを追加・変更・削除していきます。
■ 計算・抽出ができるように考える
初期のテーブル設計では、色々不具合があることは明らか。
例えば、口数について考えます。
基本的に宅配料金は、一箱に対して金額が発生し、出荷先に複数口がある場合、口数ごとに運賃が異なるので、インポートしたデータに対して、単純に運賃を記録するのはNGなことに気付きます。
また、運賃計算は、基本的にサイズ(縦+横+高の和)と配達先の地域の組み合わせで料金が設定されています。
ただ、住所には、地域が無いため、代替案が必要になってきます。
さらに、重量で料金が変動するから、重量でも運賃が計算できるように、工夫が必要になります。
「運賃」という一見簡単に計算できそうな数値ですが、意外に複雑です。
要件定義に「運賃は自動計算させる」とあります。
「運賃」を自動計算させるための、仕組みを深く考える必要があります。
■ テーブルのデザインを是正
運賃を計算して、R/3にアップする為に、テーブルを分割、作成し、ついでに、不要な項目を削除しました。
ここの段階で、運賃計算は簡単ではないことがわかります。
また、口数が増える(2個口以上)場合、荷姿も様々なので、例外的な梱包状態でも対応できるように設計。
最初の単純なテーブル構造とは、かなり違うと思うはず。
| テーブルを分割すると判断するポイント
これは有名(ベタ)な考え方ですが、「固有」を維持できるかを考えます。
今回の事例では、一つの出荷伝票に対して、複数の口数(梱包)ができるケースが出てきます。
冗長的な構造になると、レコードを複数作る事になります。
ある一つの出荷伝票を探す時、複数のレコードが抽出されることに。
基幹システム(R/3)には一つの出荷伝票しかないので、運賃は、複数の口数の梱包の運賃の合計値をアップロードする流れになります。
ユーザー側のUI設計を少しここで考えます。
レコードをその都度複製することは、良くない事は、容易に想像できます。
そこで、出荷伝票の情報と運賃のテーブルを分ける方が得策と判断できます。
出荷伝票は出荷先を保存することがメインで、別のテーブルに、運賃や荷姿の情報を保存し、運賃の合計値を算出しやすくしたのです。
また、運賃テーブルも、2個のテーブルに分割しました。
配達先の都道府県、配送業者、サイズの料金表と、重量からサイズに変換する表に分割しました。
料金表から重量を外したわけです。
重量で料金が変化するケースは「例外」と位置づけしました。
テーブルを分割することによって、計算が単純になるケースが多いです。
ただ、テーブルを分割してしまうと、演算処理がネックになるケースがあるので、時と場合によって使い分けします。
| 一番の鬼門 テーブル設計
note で、テーブルの設計の記事を書いているのに、理不尽な事を書きます。
正直、テーブルの設計は、勉強して習得できるものではない。
失敗して失敗して、良い設計を盗んで盗んで、経験と実績で習得するしかないです。 本を読んで出来るなら、だれも苦労しません。
ある程度のテンプレ的なテーブル設計はありますが、実務のデータやデータ特性、実務の流れ、会社ルールで、アレンジすることが多いです。
しかも、事務職の人が実務の片手間で作るシステムなので、出来る限りシンプルに設計しないと、開発コストが上がってしまうので、テンプレがそのまま利用できるかは、疑問を持った方が良いです。
会社にも、Accessを使える人は、数十人はいると認識しています。
ただ、情シス以外の人で、Accessでシステムを作れる人は?
となると、俺以外いるのか?ってなります。
しかし、まだ完全ではありません。
まだ、次のテーブル設計段階があります。それは、次回に記事にします。
■ まとめ?
運賃って、配達元の地域(関東やら中部やら中国などの)から地域とサイズ(縦+横+高の和)が基本ですが、重量とサイズの表がって、重量がサイズに変換する必要があるんですよね。
サイズが小さくても、重量で、実際のサイズより大きい計算がされる仕組みなんです。
実は、このロジックを理解するのに、苦労した記憶です。
本当は、基本的なテーブル設計の考え方を表現できれば良かった。
ここは、文字での表現が難しい。
記事では「計算・抽出ができるように考える」の章で、簡単に表現しました。
もう一つの表現を加えるのなら、「各テーブル間の矛盾が発生しないようにする」を付け加えれば良かったのですが、このシステムのデータって、外部インポートして、結果は、システムに返すシステムなので、この考えがほぼ皆無なんですよね💦
てなわけで、テーブルの設計の記事ですが、実は、まだ半分くらいです。
まだまだ、考えなきゃならない事があります。
ここまで読んでくれて、嬉しいです。
ワイの経験したことが、ちょっとでも感じてくれれば嬉しいです。
この記事が気に入ったらサポートをしてみませんか?