• ベストアンサー

外部キーだけのテーブル(主キーがない?)

データベースのテーブルについておたずねします. 主キーがなくて,そのかわりに外部キー(と主キー以外の列)しか持たない テーブルも可能だと聞きました. テーブルには主キーが必ずあるものだと思っていましたが, どのような使いかたをするのでしょうか. どうやら,最初からデータがあるわけではなく, 追加されるタイミングがわからないデータを格納する場合に作っておく, ということらしいのですが,なんのことかよくわかりません. データベース関連書籍をいくつか調べましたが, 主キーのないテーブルの説明などは見当たりません. また,この悩ましい問題を与えてくれた知り合いに訊ねましたが, テーブル構成などの具体的なことは, 企業内のことなので,教えてもらえませんでした. 何か具体的な例を交えながらご説明いただければと思います.

質問者が選んだベストアンサー

  • ベストアンサー
  • m_chappy
  • ベストアンサー率29% (32/107)
回答No.2

難しく考える必要はないと思いますよ。主キーというのがそのテーブルの行をユニークに規定する独立したIDと考えると、その設置有無は必要性で判断すれば良いことです。不要でも設置して構いませんが、それは分かり易さとシステムリソース、レスポンス、メンテナンス性との兼合いでしょう。 では、好例ではありませんが、一つ具体例をあげてみましょう。 日本語が下手でごめんなさい。よ~く読んで、ER図を書いてみてください。 とある組立工場を思い浮かべてください。そこで生産される製品の条件を以下とします。 ・製品は複数の部品から構成される。 ・部品は複数の製品に使用される。 ・部品は複数の仕入先から調達される。 ・部品の仕入先は製品によって規定される。 ・製品を構成する部品は、部品毎に仕入先が異なる。 ここで登場する実態(エンティティ)は、 ・製品 ・部品 ・仕入先 の3つですね。各々の実態の関係は、 ・製品:部品=N:N ・部品:仕入先=N:N ・製品:仕入先=N:N となり、N:Nの関係ばかりですね。 さて、この関係でリレーションを張ってみましょう。単純に考えると各実体(テーブル)の構成項目は以下になりますね。 ・製品=製品ID+製品情報 ・部品=部品ID+製品ID+仕入先ID+部品情報 ・仕入先=仕入先ID+仕入先情報 ここで問題になるのは、部品テーブルの部品情報ですね。同じ部品でも仕入先毎に複数の行が発生するので、データの重複になります。メンテナンス性からこれは望ましくありません。リソース的にも不利ですね。 そこで、リレーションを一つ実態に昇格させましょう。製品別部品別仕入先テーブルを作るのです。その結果各テーブルは、 ・製品別部品別仕入先=製品ID+部品ID+仕入先ID ・部品=部品ID+部品情報 になります。これで、データの重複を排除できます。この時、製品別部品別仕入先テーブルには外部キーしか必要ないですね。敢えて主キーを付けても活用されません。 ひとつの例でしたが、こんなもんでどうでしょう?

puplix
質問者

お礼

丁寧な説明をありがとうございました. このあとも,上の例を参考にしながらいろいろ本を読んで調べていくうちに, だいぶわかってきました. MSACCESSのサンプル(Northwind)における受注明細テーブルでは, 主キーを連結キーとして設定してありますが, これが実は外部キーなのだと思います. とにかく,どうもありがとうございました.

その他の回答 (5)

  • stork
  • ベストアンサー率34% (97/285)
回答No.6

storkです。 ymmasayanさんより指摘を受けました。 回答#4は、ちょっと言葉が足りなかったようです、すみません。 補足します。 >正規化すると、m_chappyさんのようにすべて1:nの >テーブルになるが、重要性が低いので非正規化したと >いうことではないでしょうか。 <修正> 正規化すると、m_chappyさんのように1:nのテーブルになります。 puplixさんのご質問のケースでは、重要性が低いので非正規化したためそのようなテーブルが出来上がったのではないでしょうか。

puplix
質問者

お礼

「重要性が低いので非正規化した」かどうかはわかりませんが, 非正規化についても必要でしょうから, 引き続き勉強していきたいと思います. どうもありがとうございました.

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.5

No.4のstork さんの回答には誤解があるようです。 > 正規化すると、m_chappyさんのようにすべて1:nのテーブルになるが、重要性が低いので非正規化したということではないでしょうか。 部品表を2つに分けて、「製品別部品別仕入先表」を作り出したのは、あくまでも正規化であって、非正規化では有りません。m_chappy さんの言われる通り、重複を避けるために「リレーションを一つ実態に昇格させた」ので明らかに正規化です。本来の実態との間に違和感があり、又、データベースが複雑になったように見えるのも事実ですが、この事から単純に非正規化と断定できるものではないはずです。

puplix
質問者

お礼

非正規化については今後勉強していくつもりですが, いまは正規化についてとことん身に付けようと思っています. どうもありがとうございました.

  • stork
  • ベストアンサー率34% (97/285)
回答No.4

正規化すると、m_chappyさんのようにすべて1:nのテーブルになるが、重要性が低いので非正規化したということではないでしょうか。 すべてを正規化すると、細かいテーブルがたくさん出来るので、簡略化したのだと思います。 ここで注意したいのは、『最初から正規化しなかった』と『重要性が低いので非正規化した』は結果が同じもしくは非常に似ていることが多いです。 しかし『最初から...』の場合は、データに対する認識がユーザと設計者の間で食い違っている場合があるので注意してください。システムの柔軟性が損なわれるおそれがあります。

puplix
質問者

お礼

お盆にDBの勉強をはじめたばかりなので, 非正規化については,まだまだ先のことになりそうです. とにかく,回答をありがとうございました.

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.3

RDBの表には主キーが必ず必要だと言う話と、主キーの宣言を行うかどうかと言う話を分離する必要があるように思います。 No.2のm_chappy さんの言われる「主キーというのがそのテーブルの行をユニークに規定する独立したIDと考えると、その設置有無は必要性で判断すれば良いことです。」と言うのはそれを言われていると思います。 m_chappy さんの上げられた「製品別部品別仕入先テーブル」の例では 製品別部品別仕入先=製品ID+部品ID+仕入先ID の主キーは、「製品ID+部品ID」で必要十分であるわけですが、あえてこれを主キーというかどうか、又、主キー宣言するかどうかということだと思います。 私は「主キーがない」のではなく「主キーはあるが、それを意識する必要がないし、主キー宣言も不要だ」と言うべきだと思っています。

puplix
質問者

お礼

どうもありがとうございました. 主キーひとつとってみてもなかなか深いなぁと, 考えさせられました.

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.1

あまり具体的な例をあげることができませんが。 通常、RDBは「1:n」や「m:1」となります。 が、「m:n」を設ける必要がある場合、実際には「中間テーブル」を作成し、 「1:n」と「m:1」の関係を作成します。 このときの「中間テーブル」が、外部キーを持ち主キーが存在しない、では なかったかな?

puplix
質問者

お礼

最初この回答を読んだときなんのことかわからなかったのですが,皆さんの回答をあわせて読んでいくうちにわかってきました. どうもありがとうございました.

関連するQ&A

  • 外部参照してるキーを主キーにすることは可能?

    DB設計について質問なんですが、テーブル1のA列を主キーとし、テーブル2のA列から外部キーでA列を参照したとします。 この時、テーブル2のA列を主キーとして設定することは可能なんでしょうか。 (テーブル2の方で列Aと列Bを組み合わせて主キーにしたいのです。要は二列でデータがユニークになるように設計したい) 使用しているDBはPostgreSQLです。 以上、宜しくお願い致します。

  • 外部から取り込んだテーブルに主キーを設定するには

    外部から取り込んだテーブルに主キーを設定するには sql server 2000 のデータベースにsqlserver 2008 express editionをインストールしたPCで別のデータベースのテーブルをインポートウィザードにて取り込み、そのテーブルに主キーを設定しようと、新しいログイン名で-ログイン-セキュリティ-ユーザー-プロパティの画面でセキュリティ保護可能なリソースを選択し、オブジェクトの列の権限にて更新、選択、等許可に設定しても、テーブルの変更が(主キーの設定)ができません。 この変更は、もともと無理なことなのでしょうか。そうだとしたら他にテーブルの列設定を変更する方法はないのでしょうか どうかご教授お願いします。宜しくお願いします。 PC os XP pro (sql server 2008 express edition) サーバー WINDOWS 2000 server SQL server 2000

  •  テーブルA(主キー有り)とテーブルB(主キー有り)をLEFT OUT

     テーブルA(主キー有り)とテーブルB(主キー有り)をLEFT OUTER JOINで外部結合したテーブルが 読み取り専用になっていて、データの更新ができないのですが、更新出来る方法が解らずに、困っていま す。この結合したテーブルのデータを更新できるようにするにはどのようにすればよいのでしょうか、お助け 願います。 SQL SERVER 2008 EXEPRESS EDITION をインストールしたPCからSQL 2000 serverのデータベースに アクセスしています。

  • 外部キー

    アクセスのテーブルの主キーは 外部キーとも言うのですか?

  • 主キーが多ければ検索が速い?

    http://okwave.jp/qa/q7785075.html こちらの質問を見て思ったのですが 主キーがあれば検索が早くなるとの事ですが テーブルには複数の主キーが設定できますが 主キーが多ければ多いほど検索が早くなったり データベースとして最適になるのでしょうか?

  • Accessの主キーについて

    お願いいたします。 Accessの主キー設定について教えてください。 主キーの役割は、テーブルの中のレコードを区別 するための機能だと思いますが、 フィールドのデータ型をオートナンバー型にして おけば主キーの設定は必要ないのではないでしょう か? 主キーを設定する理由としては、参照整合性のため に行うという考え方で良いでしょうか? また、複数の主キーを設定するという場合のテーブ ル構成はどのような場合のシステムなのでしょうか? どうぞ教えてください。

  • phpmyadminの外部キー設定について

    phpmyadminでデータベースを作成しているのですが、外部キーを相互に参照し合っているテーブルがあります。 一方のテーブルにデータを入れようとすると、参照先の外部キーにそのデータはありません、とエラーが出るし、もう一方のテーブルにデータを入れようとしても同じエラーが出ます。 調べたところ、遅延制約というのがあるようですが、それをphpmyadminで設定する方法が分かりません。 sql文を直接入力するしかないのでしょうか。 設定の方法や、他の方法をご存知の方はぜひご教授ください。

  • 主キーって

    データベースにでてくる、『主キー』の概念が全く理解できません。 いろんなところでいろんな説明をみるのですが、何故これが必要なのか、これはいったいなんなのか、とてもわかりやすく教えていただけるかたいましたらお願いします。

  • MDB内既存テーブルに主キーのフィールド追加は可能か?

    DAOでMDBにアクセスするシステムなのですが、 テーブル仕様変更に伴い、既存のテーブルに新規に主キーとなるフィールドを追加します。 当テーブルはすでに主キーは複数存在しています。 現在は CreateIndex("PrimaryKey")を行ったのですが、 「既に主キーは既に存在しています」と表示されてしまい、異常終了をしてしまいます。 単にフィールド追加することは容易なのですが、主キーとなると、だめみたいです。 この場合は、どのようにすれば良いのでしょうか? 大変申し訳ございません。 ご教授よろしくお願い致します。

  • 主キーの値を自動更新することはできますか

    Accessで、あるテーブルの主キーとなる列から、一対多の関係で別のテーブルがあります。 テーブル1 主キー a01  あああ a02  いいい a03  ううう … テーブル2 主キー  b01   a01 かかか b02   a05 ききき b03  a01 くくく … こういうイメージなのですが、あとから「a01」等を、全部「g01」などのように変えて、なおかつテーブル2のデータを更新することはできるでしょうか。