- ベストアンサー
外部キーだけのテーブル(主キーがない?)
データベースのテーブルについておたずねします. 主キーがなくて,そのかわりに外部キー(と主キー以外の列)しか持たない テーブルも可能だと聞きました. テーブルには主キーが必ずあるものだと思っていましたが, どのような使いかたをするのでしょうか. どうやら,最初からデータがあるわけではなく, 追加されるタイミングがわからないデータを格納する場合に作っておく, ということらしいのですが,なんのことかよくわかりません. データベース関連書籍をいくつか調べましたが, 主キーのないテーブルの説明などは見当たりません. また,この悩ましい問題を与えてくれた知り合いに訊ねましたが, テーブル構成などの具体的なことは, 企業内のことなので,教えてもらえませんでした. 何か具体的な例を交えながらご説明いただければと思います.
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
難しく考える必要はないと思いますよ。主キーというのがそのテーブルの行をユニークに規定する独立したIDと考えると、その設置有無は必要性で判断すれば良いことです。不要でも設置して構いませんが、それは分かり易さとシステムリソース、レスポンス、メンテナンス性との兼合いでしょう。 では、好例ではありませんが、一つ具体例をあげてみましょう。 日本語が下手でごめんなさい。よ~く読んで、ER図を書いてみてください。 とある組立工場を思い浮かべてください。そこで生産される製品の条件を以下とします。 ・製品は複数の部品から構成される。 ・部品は複数の製品に使用される。 ・部品は複数の仕入先から調達される。 ・部品の仕入先は製品によって規定される。 ・製品を構成する部品は、部品毎に仕入先が異なる。 ここで登場する実態(エンティティ)は、 ・製品 ・部品 ・仕入先 の3つですね。各々の実態の関係は、 ・製品:部品=N:N ・部品:仕入先=N:N ・製品:仕入先=N:N となり、N:Nの関係ばかりですね。 さて、この関係でリレーションを張ってみましょう。単純に考えると各実体(テーブル)の構成項目は以下になりますね。 ・製品=製品ID+製品情報 ・部品=部品ID+製品ID+仕入先ID+部品情報 ・仕入先=仕入先ID+仕入先情報 ここで問題になるのは、部品テーブルの部品情報ですね。同じ部品でも仕入先毎に複数の行が発生するので、データの重複になります。メンテナンス性からこれは望ましくありません。リソース的にも不利ですね。 そこで、リレーションを一つ実態に昇格させましょう。製品別部品別仕入先テーブルを作るのです。その結果各テーブルは、 ・製品別部品別仕入先=製品ID+部品ID+仕入先ID ・部品=部品ID+部品情報 になります。これで、データの重複を排除できます。この時、製品別部品別仕入先テーブルには外部キーしか必要ないですね。敢えて主キーを付けても活用されません。 ひとつの例でしたが、こんなもんでどうでしょう?
その他の回答 (5)
- stork
- ベストアンサー率34% (97/285)
storkです。 ymmasayanさんより指摘を受けました。 回答#4は、ちょっと言葉が足りなかったようです、すみません。 補足します。 >正規化すると、m_chappyさんのようにすべて1:nの >テーブルになるが、重要性が低いので非正規化したと >いうことではないでしょうか。 <修正> 正規化すると、m_chappyさんのように1:nのテーブルになります。 puplixさんのご質問のケースでは、重要性が低いので非正規化したためそのようなテーブルが出来上がったのではないでしょうか。
お礼
「重要性が低いので非正規化した」かどうかはわかりませんが, 非正規化についても必要でしょうから, 引き続き勉強していきたいと思います. どうもありがとうございました.
- ymmasayan
- ベストアンサー率30% (2593/8599)
No.4のstork さんの回答には誤解があるようです。 > 正規化すると、m_chappyさんのようにすべて1:nのテーブルになるが、重要性が低いので非正規化したということではないでしょうか。 部品表を2つに分けて、「製品別部品別仕入先表」を作り出したのは、あくまでも正規化であって、非正規化では有りません。m_chappy さんの言われる通り、重複を避けるために「リレーションを一つ実態に昇格させた」ので明らかに正規化です。本来の実態との間に違和感があり、又、データベースが複雑になったように見えるのも事実ですが、この事から単純に非正規化と断定できるものではないはずです。
お礼
非正規化については今後勉強していくつもりですが, いまは正規化についてとことん身に付けようと思っています. どうもありがとうございました.
- stork
- ベストアンサー率34% (97/285)
正規化すると、m_chappyさんのようにすべて1:nのテーブルになるが、重要性が低いので非正規化したということではないでしょうか。 すべてを正規化すると、細かいテーブルがたくさん出来るので、簡略化したのだと思います。 ここで注意したいのは、『最初から正規化しなかった』と『重要性が低いので非正規化した』は結果が同じもしくは非常に似ていることが多いです。 しかし『最初から...』の場合は、データに対する認識がユーザと設計者の間で食い違っている場合があるので注意してください。システムの柔軟性が損なわれるおそれがあります。
お礼
お盆にDBの勉強をはじめたばかりなので, 非正規化については,まだまだ先のことになりそうです. とにかく,回答をありがとうございました.
- ymmasayan
- ベストアンサー率30% (2593/8599)
RDBの表には主キーが必ず必要だと言う話と、主キーの宣言を行うかどうかと言う話を分離する必要があるように思います。 No.2のm_chappy さんの言われる「主キーというのがそのテーブルの行をユニークに規定する独立したIDと考えると、その設置有無は必要性で判断すれば良いことです。」と言うのはそれを言われていると思います。 m_chappy さんの上げられた「製品別部品別仕入先テーブル」の例では 製品別部品別仕入先=製品ID+部品ID+仕入先ID の主キーは、「製品ID+部品ID」で必要十分であるわけですが、あえてこれを主キーというかどうか、又、主キー宣言するかどうかということだと思います。 私は「主キーがない」のではなく「主キーはあるが、それを意識する必要がないし、主キー宣言も不要だ」と言うべきだと思っています。
お礼
どうもありがとうございました. 主キーひとつとってみてもなかなか深いなぁと, 考えさせられました.
- bin-chan
- ベストアンサー率33% (1403/4213)
あまり具体的な例をあげることができませんが。 通常、RDBは「1:n」や「m:1」となります。 が、「m:n」を設ける必要がある場合、実際には「中間テーブル」を作成し、 「1:n」と「m:1」の関係を作成します。 このときの「中間テーブル」が、外部キーを持ち主キーが存在しない、では なかったかな?
お礼
最初この回答を読んだときなんのことかわからなかったのですが,皆さんの回答をあわせて読んでいくうちにわかってきました. どうもありがとうございました.
お礼
丁寧な説明をありがとうございました. このあとも,上の例を参考にしながらいろいろ本を読んで調べていくうちに, だいぶわかってきました. MSACCESSのサンプル(Northwind)における受注明細テーブルでは, 主キーを連結キーとして設定してありますが, これが実は外部キーなのだと思います. とにかく,どうもありがとうございました.