<HOME  <お願い事項   <Access2002 TOP   <Access2000 TOP   <サイト内検索
 MS-Access97超入門>主キーとは何のために?



■主キーとは何のために?

さて、ちょっと難しい問題です。

主キーのことについて、Accessのオンラインヘルプをたどってみると、以下のような解説があります。

使用する主キーを設定する

Access などのリレーショナル データベース システムでは、クエリー、フォーム、およびレポートを使って、別のテーブルに格納されている情報の検索および収集を高速に実行できるという機能が重要になります。これを実現するには、格納されたレコードを一意に識別するフィールドまたはフィールド セットが各テーブルに設定されている必要があります。この情報をテーブルの主キーと呼びます。テーブルの主キーを設定すると、一意性を保証するために、主キー フィールドには重複する値や Null 値を入力できなくなります。

Access で定義できる主キーには、オートナンバー、単一フィールド、複数フィールドの 3 種類あります。

オートナンバーの主キー

レコードをテーブルに追加するたびに、オートナンバー型フィールドに連続番号を自動的に入力するように設定できます。オートナンバー型フィールドに主キーに割り当てることは、主キーを作成する一般的な方法です。主キーを設定せずに新規作成したテーブルを保存しようとすると、主キーを作成するかどうかを確認するメッセージが表示されます。[はい] を選択すると、オートナンバー型の主キーが作成されます。テーブルでデータベース レプリケーションを使用する場合は、このほかにも注意が必要です。詳細については、 をクリックしてください。

単一フィールドの主キー

ID 番号や部品番号など、一意の値を持ったフィールドを主キーとして割り当てることができます。主キーとして割り当てたフィールドに重複する値や Null 値が含まれている場合は、主キーとして設定されません。重複クエリーを実行して、どのレコードのデータが重複しているかどうかを確認することができます。重複しているデータをまだ編集できない場合は、オートナンバー型フィールドを追加して主キーに設定しておくか、複数のフィールドに主キーを設定しておきます。

複数フィールドの主キー

単一フィールドでの一意性が保証できない場合は、2 つ以上のフィールドを主キーとして割り当てることができます。この状況は、多対多リレーションシップで 2 つの別のテーブルを関連付けるのに使用するテーブルでよく使用されます。その例として、ノースウィンド データベースの [受注明細] テーブルで、[受注] テーブルと [商品] テーブルを関連付けています。[受注明細] テーブルの主キーは、[受注コード] フィールドと [商品コード] フィールドの 2 つのフィールドからできています。[受注明細] テーブルでは、多数の商品と多数の受注を一覧表示できますが、各商品は 1 つの受注につき 1 つしか一覧表示できません。したがって、[受注コード] フィールドと [商品コード] フィールドを結合すると適切な主キーが設定できます。

別の例として、在庫データベースでは、2 つ以上のフィールド (パートおよびサブパート) のフィールド パート番号が使用されています。

メモ 複数フィールド主キーとしてフィールドを結合する場合に、適切な選択かどうか確かでないときは、オートナンバー型フィールドを追加して、主キーを割り当てます。たとえば、氏名の [姓] フィールドと [名] フィールドを結合して主キーを作成すると、データが重複する場合があるので、お勧めしません。

なんだか難しいこと書いてありますね。。。

データベースというものは、並べ替え/整列を高速に行うために、目印となるフィールドをひとつ定めておくものであり、
Accessの場合はそのフィールドのことを主キーと呼んでいるというわけです。


こんなテーブルがあります。

このテーブルは、今はこんな風にぴしっと表の形をしていますが、べつにいつもこういう風に表の形の状態でパソコンディスクに保存されているわけではないんです。

テーブルを開くとか、このテーブルを基にしたクエリーを開くとか、そのクエリーを基にしたフォームやレポートを開くとか、そういうときにはじめてレコードごとにぴしっと整列するわけです。

これはもう肉眼で確認することのできないレベルのお話なので、みなさんの想像力に委ねる他ないんですが、普段はこんな風に表のカタチに整列しておらず、もっとバラバラにだらだらと保存されてるわけです。

校庭に小学生が200人くらい散り散りになって遊んでいるとします。先生のホイッスルで、きちんと整列しないとなりません。

なに順にならぶ?背の順?地域別?クラス別?

あらかじめ決めておかないと、整列するのに時間がかかりそうですよね。
まあ、いつかは何かしらの順番でそれなりに整列するかもしれないですけど、できればあらかじめ「ここではクラス別に整列します」とか、決めておいてほしいもんですよね。

「クラス別」と決めておいたらどうでしょう。
ホイッスルが鳴ったら、まずクラス委員が前列に整列して、その後ろに生徒がひとりずつ整列していく。
多分クラス委員にとってもクラスのみんなにとっても先生にとっても、よい方法じゃないでしょうかね。

でも、そんな決まり作らなくても、整列くらいそのうち何とかなるでしょう。なくてもいいけど、あった方がいい、というくらいに捉えてしまって差し支えないと思います。


主キーの最たる目的は、私たちではなく、データベース側、Access側の都合なんです。
リレーショナルデータベースの世界では、物理データの集まりにキーフィールドを設けるのは当たり前のことで、「主キーが必要なのはなぜ?主キーは作らないといけないの?」という疑問も、もしかしたら発生しないのかもしれません。


では、いくつか主キーの例を見てみましょう。

例えば、下のテーブルで行くと、主キーは[学籍番号]になります。

ふつう、学校では、就学している学生に対して、学生手帳みたいなのを渡して、それには学生ひとりひとり違う番号がついてるんじゃないでしょうかね。
社員番号とか、会員番号とか、そういうのも同じですね。

データベースとかコンピュータ操作を離れて考えてみたとき、同じ学籍番号を持つ生徒が複数存在しえるなら、学籍番号の意味はあんまりないんじゃないでしょうか。

とすると、「学生一覧」みたいな名簿的なテーブルの中では、[学籍番号]というフィールドの中の値は、何百レコード入力されても重複しないはずですよね。
とすると、テーブルの中でレコードは「10005のレコード」「10008のレコード」「10020のレコード」・・・と、この[学籍番号]を頼りに整列することができるわけですね。

[学籍番号]を主キーとするためには、

1.ダブらない

2.必ず入力される

という条件をクリアしないとなりません。この中の値を基準に整列するんですからね。ダブっているならまだしも、入力されてない、空っぽ、なんてもっての外です。

顧客台帳とか会員名簿テーブルとか、そういうテーブルの中では大概「顧客番号」とか「会員番号」みたいなフィールドを設けるでしょう。それを主キーにすればよいはずです。


さて、では下のテーブルはいかがでしょう。

「何月何日、誰が、いくら稼いだか」という情報を、日々どんどん追加入力していくタイプのテーブルです。
伝票入力しているみたいな感じですね。

こういうテーブルをトランザクションテーブルなんて呼んだりします。

学籍番号は、とりあえずダブりますよね。
今日もあしたも明後日も稼いでくれば、3回入力されるし、もし、1日4回くらい小刻みに報告してきたとしたら、
相当な件数になるはずです。

主キー向きのフィールドは、なさそうですねぇ。
受付番号とか伝票番号みたいなのがあればいいんですけどね。ないですもんね。

こういう時、オートナンバー型のフィールドを主キーにするケースが結構あるようですね。


ただ、主キーは空っぽはだめなんですよね。あとから主キーを慌てて付けるときは、注意しないといけないです。

なんでって?だって、今から下の要領で新しく主キーになり得るフィールド作っても、作っただけじゃ中身は空っぽなんですよ。
レコード入力したときはそのフィールドなかったんですから。

だから、いきなり主キーにせずに、一度オートナンバー型のフィールドを設けた状態でテーブルを保存し、データシートビューに切り替えて中身を確認します。

番号、自動的に採番されてます?

[番号]のフィールドに何かしら重複しない数値が入力されれば、このフィールドを主キーにしても問題ないですよね。

さて、ヘルプの中に「テーブルに格納されている情報の検索および収集を高速に実行できる」という一文がありましたね。
これを実現させるために、主キーのような、重複しないフィールドを設けるのだ、と、まあそんな感じのようです。

では、主キーのないテーブルは、本当に処理が遅くなるのでしょうか。具体的にどういう影響が出るんでしょう。

左のテーブルは[番号]を主キーにしています。右のテーブルは主キーなしです。件数は同じ5006件。

でも、このふたつのテーブルを開くときも、学籍番号で検索するようなクエリーを開くときでも、これを基にしたフォームやレポートを開くときも、
どちらもまったく処理速度には違いはありませんでした。

多分、5000件くらいでしたら、主キーがあろうとなかろうと、大概の処理では、われわれ使う側にとっての影響はたいしてないのだと思います。
あくまでも内部的に、Accessサイドから見ると、主キーを作っておいてほしいものだ、ということじゃないかと・・・。

どうしても主キーの意味が理解できない、という方は、そんなふうに解釈してみてください。

もちろん、クロス集計クエリーとか、そういう処理は、件数が多くなるとかなり遅くなります。
でも、集計処理なんかは、だからといってやめるわけにもいかないし、仕方がないってこともありますよね。


主キーは、ひとつのテーブルにひとつとは限りません。

例えば、下のようなテーブルの場合・・・。

データシートビューでの表示だとわかりにくいですけど、ちょっとした注文表だと思ってください。
1枚の注文表に、いくつかの品物を書き込むことができるとします。注文表には全部[伝票番号]が振られてます。

で、A001の伝票で、ちくわとえんどうまめを注文しました。え?ちくわ452個もどうするんだって??まあいいじゃないですか。

と、A001の伝票に枝番をつけて、「A001の1行目がちくわ、2行目がえんどうまめ」という具合になります。
テーブルの構造としては以下のようになるわけです。

と、オートナンバー型の主キー用のフィールドを別個に作ってもいいんですけど、よく考えてみると、伝票番号+枝番で、絶対重複しないですよね。
A001の1は、絶対一回しか出てこないはずです。

このテーブルというか、ここにデータを入力するときの注文表の伝票をイメージすると、「伝票番号」+「枝番」という感じでふたつ組み合わせて主キーにすれば、
処理の内容にもあいそうじゃないですかね。特別主キー用のフィールドを作るとなると、その分余分にスペース取りますし、この際無駄は極力省くということで・・・。

主キーを複数指定するためには、まず複数のフィールドを選ばないといけません。
画面左端の「セレクタ」部分を、キーボードのCtrlキーを押しながらクリックしたり、下向きにドラッグすることで、複数行選択することができるはずです。
で、主キー設定のツールボタンをクリックすればOK。


とにかく、主キーとは、テーブルの中のレコードが迅速に整列するために必要な設定なのだと解釈してください。
主キーとなるからには、中の値は重複してはなりません。また、入力がなされない、空っぽの状態でもいけません。

そのテーブルに絡む処理から推測して、必ず入力がなされ、重複せず、各レコードの中の中心的存在となるフィールドを主キーにします。

トランザクション系のテーブルや、処理の中で仕方なくちょこちょこっと踏み台のように使うテーブルなど、上記のような主キーとなり得るフィールドが存在しないテーブルの場合は、無理に主キーを設定する必要はないでしょう。

ただ、読み書きが頻繁に行われたり、1万件2万件と件数が多くなる可能性が高いような、使用頻度の高いテーブルの場合は、何か考えた方がよいでしょう。
処理全体を見渡して、[伝票番号]とか[受付番号]などといったフィールドを設けていった方が、そのテーブルのためだけでなく、データベース全体にとっても有効な場合もあると思います。

また、とにかくデータを突っ込むだけの作業用テーブルの場合は、オートナンバー型のフィールドも有効でしょう。とりあえず主キーとなるフィールドに、重複しない値が必ず入りますからね。でも、オートナンバー型のフィールドは、私たちには操作できませんので、「これを伝票番号の変わりにしよう」という考えは、少々危険です。その場合はやっぱりなんかルールを決めて、ちゃんと伝票番号を入力するようにしましょう。

でも、多分、主キーはぜんぜんなくても、そんなに処理速度自体は変らないと思います。

主キーはリレーショナルデータベースの中の機能ではなくて考え方のひとつですので、いろいろ試してご覧になって、最終的には、みなさん独自の解釈の仕方でかまわないんじゃないかと思います。なんて書くと、ちょっと語弊がありますけれど・・・。