Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。
あるシステムにDB(データベース)を実装しようとする場合、RDBMSにOracleを使うかMySQLにするかPostgreSQLを選択するかってのもあるけど、まず実際どういうDBにするのか設計すると思う。Sig.の場合、設計時のコンセプトは次の2つ。
- 重複を避ける
- 求めるデータを「特定できる」ようにする
DB設計を厳密に行う手法には「リレーションの正規化」というものがある。これはデータの一貫性を維持し、不整合と冗長性を避け、効率的なアクセスを可能にするための設計手法。単に正規化ともいう。正規化には幾つか段階があるけど、実務の際には第三正規形までに止めて、それで十分とする場合が多い。その場合のポイントは、大まかに3つ。
- 繰り返しを避け、分割する
- キーと非キーに分ける
- キーとなりうる項目を分割する
あらかじめSQLでデータを取得することに慣れていると、設計から入るより楽に覚えられると思う。
定義
- 第一正規形
- データの繰り返しグループを排除した形。繰り返し部分を複数のテーブル/レコードに分割する。
- 第二正規形
- 第一正規形から「キーから非キー」への関数従属性を整理した状態。候補キーに対して他の値が完全従属し、キーがこれ以上分解できない状態。
- 第三正規形
- 第二正規形から「非キー属性間」の関数従属性を取り除くことによって得られる。第三正規形では、キー以外の項目も全部眺めて、キーにできる項目を、片っ端からキーとして別の表に分離していきます。
関数従属: 「ある項目が定まると他の項目が定まる」という関係のこと。Aという値を定めるとBという値が決まる場合、「A→B」と表記し、「BがAに関数従属する」という。
手順
↑初期のDB案。アルバム名と価格が繰り返されている。
↑第一正規形。商品単位で分割し、レコードのキーとなる番号を追加。
↑第二正規形。商品番号に従属する各項目を、別のテーブルに分割。
↑第三正規形。アーティスト名はキーとして使えるので、分離する。こうすれば、アーティスト名からアルバム一覧を得ることができるし、そういった利用法も考えられるので分ける意義がある。
多重度
テーブルとテーブルが「1対多」であるか「多対多」であるか、といった関係性もまた重要になる。例えばSNSっぽく次のような場合。
グループは複数のメンバーを抱え、メンバーは複数のグループに所属できる。このとき、グループ・テーブルとメンバー・テーブルは「多対多(many-to-many)」の関係にあると言える。
一般的に多対多のリレーションは構築が難しい。たとえば「グループA」に所属している「メンバーの一覧」を出したい場合はどうするか。各メンバーのレコードからグループAの「グループID」に相当するキーを探し出し、一致すればリストに加える。ここで面倒なのは、メンバーがグループに幾つでも所属できる場合。
たとえば所属できるグループが「3つまで」と定められているなら、メンバー・テーブルのカラムに「所属グループ1」「所属グループ2」「所属グループ3」といった意味合いのカラムを用意すれば事足りる。しかし幾つでもとなると、メンバーが新しいグループに所属するたびにカラムを作成しなければならなくなる。
できないことはないけど、これはマズい。なによりスマートじゃない。ユーザがアクションを起こすたびにDBの構造が変化することになるし、殆どのユーザが1つか2つのグループにしか所属していないとしても、99個のグループに所属するメンバーが一人いるだけで、全てのメンバーに99個のカラムが用意されることになってしまう。明らかに資源の無駄遣い。ではどうするか?
「所属」という関係性を記録するテーブルを用意してやれば良い。「グループ」と「メンバー」は所属テーブルを通して接続する。「グループと所属」「メンバーと所属」はいずれも「1対多(one-to-many)」の関係にある。
こうすればメンバーの所属グループが幾つ増えようと「所属テーブル」のレコードが増えるだけ。その逆も然り。この状態では、「所属テーブル」に対して検索をかけてやれば、所属メンバーの数でも所属グループの一覧でも簡単に得ることができる。
そんな一例。
Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。
4 Comments
以前仕事でDBの設計をしたときに使用したツールがあるのですが、
リレーションを考える上でとても重宝したので参考までにどうぞ。
ただリレーションを記録するXMLがなぜか破損して
悲惨な目にあったりもしたのであまり信用はできないかも。。。
DBDesigner
http://www.aglabo.com/agl/proevo/software/fabforce/
http://dbdesigner.iimp.jp/ 2007–09–17 02:06
> DBDesigner
おぉ~、ちょうど次から使おうと思ってたんですよ!
今のところはExcelで書いてたんですけど、これはリレーション記述できるわSQL文吐けるわで、注目してました。使い勝手はどないでしょ? 2007–09–19 05:30
カラムごとにコメントがかける機能は結構重宝しました。
実際に使ったときは、SQLを吐き出すのではなく、
データベースに直接DBDesignerがアクセスして
テーブルを同期させるということを行っていたのですが、
そこがちょっと不安だったかも。
あとPostgreSQLは対応してなかった気がします。(使ってたのはMySQL)
あと気になったのが、細かいことは覚えていませんが
操作性が悪いところが少しあったと思います。
テーブルのコピペをしようとしてできなかったんだっけかな・・・。
「見る」ツールとして使うなら十分じゃないかと思います。 2007–09–20 01:44
ふむふむ、同期は怖いですね... しかし見やすく、
SQL文吐き出せるってのは、やはり魅力的。
次から使ってみまっす。
Excelとどっちが使い勝手良いかな? 2007–09–25 13:44