しいたげられたしいたけ

空気を読まない 他人に空気を読むことを要求しない

Accessに関して備忘的に

(その1)ウィザードで作ったフォームやレポートは、元となるテーブルやクエリを変更したら作り直し。

ふつうAccessのオブジェクト*1は、

テーブル
クエリ
フォーム   レポート
マクロ
という順で作ると思う。またフォームやレポートは、ウィザードで作ることが多いはずだ。
そして、フォームやレポートを完成させてから、元となったクエリやテーブルを変更したくなることも、当然ありうるはずだ。
ところが、クエリやテーブルを修正しても、その結果はそれらを元に作成したフォームやレポートには反映されない。多少の手直しならツールバーの「プロパティ」からできることもあるが、いろんなところに情報が埋め込まれているらしく、またそれらの場所を効率よく見つける方法も(あるのかも知れないけど)知らないので、結局は修正したクエリやテーブルを元にウィザードで作り直した方が早い。
特にプリントアウトに使うレポートの場合、それはそれはリキ入れて作りこんだ後で元のクエリを変更したくなる場合が、ままある。そういうときは泣くしかない(T_T)

(その2)正規化の主キーとAccessの主キーは別物

まずは正規化のおさらい。例えば次のようなデータベースを正規化するとしよう。

学生CD氏名授業CD授業名成績
000A学生AR000授業R50
S001授業S100
000B学生BS001授業S100
T002授業T10
リレーショナルデータベースは、1行1レコードが原則。「第一正規化」というのは、空欄をコピペで埋めてこの原則に反する行をなくすことである。これは単純作業で特に問題はないはず。
学生CD氏名授業CD授業名成績
000A学生AR000授業R50
000A学生AS001授業S100
000B学生BS001授業S100
000B学生BT002授業T10
問題は次の「第二正規化」で、第二正規化を行うに先立って、項目間の従属関係を調べる必要がある。
項目間の従属関係というのは、ある項目と別の項目の間に「1対多」の関係が成り立つかどうかということだ。言い換えると、ある項目が決まると自動的に別の項目が決定されることがあるかどうかということだ。
図の例では学生CDが決まると学生名は必ず一つ決まる。逆にレアケースだが同姓同名ということもあるので、学生名が決まると学生CDが決まるとは限らない。同様に、授業CDが決まると授業名も決まるが、授業名が決まっても担当教員が違うなど違う授業だというこうともあるので、逆は言えない。
ところで「成績」なのだが、これは「どの学生が」「どの授業を」受けた際の成績かという二つのことが決まって、初めて決定される。すなわち「成績」は「学生CD」と「授業CD」という二つの項目に従属する。
「主キー」とは、リレーショナルデータベースで、他の項目がすべて従属する項目または項目の組のことである。
図の例の場合、主キーは「学生CD」と「授業CD」である。この二つのうち一つか、またはその両方が決まると、他の項目はすべて決まる。
第二正規化」とは、複数の主キーを持つリレーショナルデータベースのうち、主キーの一部にだけ従属する項目を別の表として独立させることである。こうすることによりデータの重複を取り除くことができる。
学生CD氏名
000A学生A
000B学生B
授業CD授業名
R000授業R
S001授業S
T002授業T
学生CD授業CD成績
000AR00050
000AS001100
000BS001100
000BT00210
本当は次に第三正規化というのがある。主キー以外に従属関係のある項目を別の表として独立させることだが、今回の話題には関係ないので省略する。検索すれば解説サイトがいっぱい出てきます。
えらく長くなってしまった。もうすこし簡潔に書けないものか。何が言いたいかというと、正規化で言う主キーは複数のことがありうる。つか正規化の練習問題で出てくるデータベースでは、主キーはまず複数である。
さて、上の表をAccessのテーブルにしようとすると、Accessは「主キー」の設定を要求してくる。
「学生CD」と「氏名」の表は「学生CD」を、「授業CD」と「授業名」の表は「授業CD」を、それぞれ主キーに指定してやればよい。ところが「学生CD」・「授業CD」・「成績」の表で、「学生CD」と「授業CD」を同時に主キーに指定することはできない。結局オートナンバーを使って
NO学生CD授業CD成績
1000AR00050
2000AS001100
3000BS001100
4000BT00210
のように主キーとなる項目を別に作ってやるしかない。
Accessの主キーは一つのテーブルに一項目なのだ。
なんでこうなっているのかは知らない。多分、整列とか検索とか統合とかのAccessの内部処理の必要に迫られてのことだろうと想像はできるが。
それはさておき、一言で結論を言ってしまえば、小題に掲げたとおり正規化で言う主キーとAccessで言う主キーは別物だということなのだが、毎度毎度これで頭が迷宮に入ったようになってしまう。
例えば第一正規化だけが完了したデータベースをAccessのテーブルとして入力して、オートナンバーで主キー項目を設定したら、第何正規化まで完了したことになるのか?
NO学生CD氏名授業CD授業名成績
1000A学生AR000授業R50
2000A学生AS001授業S100
3000B学生BS001授業S100
4000B学生BT002授業T10
いろいろ悩んで一応自分の中ではなんとか納得できるよう整理をつけたつもりではいるのだが、それを他人にわかるようにきちんと簡潔に説明できるかと問われると、残念ながら自信はない。

*1:オブジェクトというのはどこで出てきてもわかりにくい言葉だけど、Accessの場合「テーブル・クエリ・フォーム・レポート・マクロの総称」と循環定義するのが一番わかりやすいような気がする