• ベストアンサー

ER図の外部キー

はじめまして ER図の書き方でFK(外部キー)として記載できるもしくは そう呼べるのはinnodbでの環境に限るのでしょうか? mysqlでmyisamにて構築しているのですが 例えば注文テーブルに商品IDや顧客ID、受注スタッフID、発注スタッフID等の カラムがあったとして、そらぞれのカラムは商品テーブル、顧客テーブル、 スタッフテーブルのプライマリーキーです。 この場合、商品IDは外部キーと呼べるのでしょうか。 また発注スタッフIDが必ず登録されているとは限らないのですがこれも外部キー と呼べるのでしょうか。 よろしくお願いします

  • MySQL
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.1

 実装としての外部キー制約と、モデリングをしている時の外部キーとしての表記は分けて考えましょう。  モデリングをしている時に、属性間の関係を設計する時には、採用するデータベースシステムが外部キー制約をサポートしているかに関わらず、ちゃんと関係を明記するべきです。  ER図に記載された関係を、実データベースで制約として明記できるかどうかは、実装の時に考えることで、これは、ER図が完成してから評価することです。  外部キーの要件は、次の通り。  ・参照する側の属性に指定された値は、必ず参照される側の属性の値として存在しなくてはいけない。  ・参照する側の属性に指定された値で、必ず参照される側の列が一意に定まらなくてはならない。  発注スタッフIDが存在するとは限らないと言うことは、一つ目の要件に反します。この関係が外部キー制約として実装されているとすると、そのような発注スタッフIDを持つレコードは、注文テーブルに登録することが出来ません。  商品IDについても同じように考えてください。

sooooochin
質問者

補足

早速の回答有難うございます。 私の説明が悪かったのですが、発注スタッフIDが存在しないというのはスタッフのマスターテーブルにはあります。ただ受注はしたが未発注の場合などのように、注文テーブルにはNULLで登録されるレコードがある場合のことです。これも外部キーと表記してもよいという事でしょうか。 よろしくお願いします

その他の回答 (1)

  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.2

 あぁ。そういう事ですね。  なら、ありです。  外部キー制約をかけた子表(参照する側)の該当属性に対してNULLを禁止することはありません。・・・本来NULLの意味からすると、NULLはいかなる値とも等しくないので、当然外部キー指定のある属性値にはなり得ないのですが、これは、許容されています。  ただし、select 文で内部結合を使って、注文テーブルとスタッフテーブルを結合すると、その発注スタッフIDがNULLのレコードは、結果として帰ってこないことに注意が必要です。内部結合では、結合対象のいずれかのフィールドがNULLだと、どのような結合条件であったとしても、必ず条件が不成立となるからです。これは、NULLを対象とした比較演算子の結果から導かれます。  

sooooochin
質問者

お礼

ご丁寧な回答頂き、助かりました。 どうもありがとうございました。

関連するQ&A

  • ER図が分かりづらい・・・

    例えば、四半期テーブルが 四半期ID 於年月日 至年月日 販売情報テーブルが、 販売情報ID 受注時期 納入時期 とあって、販売情報テーブルの受注時期と、納入時期フィールドには、 それぞれ、四半期テーブルの四半期IDを入れるような場合、 ER図ではどうなるんでしょうか? どうにも、ER図って、どのフィールドとどのフィールドが繋がっているのか、 直感的でなくて分かりづらいです。 Clay Database Modelingというツールを使って書いているのですが、 特にこのような場合、二つのリレーションの矢印が重なってしまって意味不明になります。 なにかもっとわかりやすい標準的な図の書き方や、 図を書くためのツールってないのでしょうか?

  • リレーションシップと外部キー制約について

    ■最終的にやりたいこと ・なるべくコード(SELECT文など)を見ずに、「DB」「テーブル定義者」「ER図」等からテーブル間の関係性を把握したい ■具体例 ・投稿一覧。「userテーブル」「postテーブル」 ・「postテーブル」の「user_id」カラムは、「userテーブル」の「id」カラムに対応 ※簡易な場合はある程度想像は付くのですが、ちょっと複雑な構成になると途端に苦労するので、何か良い方法はないかと思い、質問しました ■質問 ◆「リレーションシップを組む」際、「外部キー制約」はかけるのでしょうか? 例えば、上記「投稿一覧」DBを構築する際では、どうするのでしょうか? 1.普通、「外部キー制約」をかける 2.普通、「外部キー制約」をかけない 3.どちらでも良い ◆「外部キー制約」は何の為にかけるのでしょうか? ・「SELECT&JOIN」でデータ取得出来るのであれば、「外部キー制約」と「リレーションシップ構築」に関係性はないと思うのですが、そういう認識で合っているでしょうか? ・参照先データが削除されたら整合性がとれなくなる場合のみかけるものでしょうか? ◆「リレーションシップを確認」する目的で、「外部キー制約」をかけても良いのでしょうか? ・「データ削除の整合性」ではなく、「リレーションシップを確認」する目的で外部キー制約」をかけても良いのでしょうか? ◆「外部キー制約」以外に、「リレーションシップを確認」する方法はあるのでしょうか? ・コード(SELECT文など)を見ずに、テーブル間の「リレーションシップを確認」する方法としては、「外部キー制約」以外に何かあるのでしょうか? ・そもそも、「外部キー制約確認」=「リレーションシップ確認」という考えは正しいのでしょうか?

    • ベストアンサー
    • MySQL
  • 複数テーブルに同一の外部キーやカラムがある場合

    例えば、ホテルテーブル、レストランテーブル、映画館テーブルなど施設別のテーブルが多数あり、 そのそれぞれが、所在エリアを示すエリアIDを持つ場合、テーブル1つずつにエリアIDを外部キーとして持たせるか、施設テーブルという抽象的なテーブルを作り、そこにエリアIDを持たせ、具体的なホテルテーブルなどは施設テーブルと1対1で結びつけるべきか、迷っていますが、どちらがいいでしょうか? エリアID以外にも共通のカラムがあります(名称、住所など)。 今後、具体的な施設テーブルは増える可能性があります(遊園地テーブルなど)。 また、エリアID以外にも共通の外部キーも増える可能性があります(所有会社IDなど)。 そう考えるとテーブル1つずつにリレーションを付けるとER図が線だらけになる気がします。 しかし抽象テーブルを作ると、データを取ってくるたびに毎回JOINしないといけないのが気になります。 ご意見お願いします。

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

    外部キーの設定方法について テーブルCのカラムCについて、テーブルAのカラムA、またはテーブルBのカラムBにある値しか受け付けないように、外部キーの設定を行いたいのですが、方法が分かりません。 テーブルAのカラムAとテーブルBのカラムBとをUNION したビューを作成してみましたが、ビューにはプライマリィキーを設定することが出来なく、外部キーは作成できませんでした。 何か、回避策を教えてください。 よろしくお願いします。 データベースは、ANSI標準サポートのタイプとして、考えてください。

  • 外部キーを持つテーブルを作成しようとするとエラーがでます

    XAMPPバージョン1.5.4 MySQLバージョン4.1.16 という環境で、my.cnfでInnoDBを使えるように設定しています。 そして CREATE TABLE admin_roles (id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(12) NOT NULL) ENGINE = InnoDB; という非参照列idを持つadmin_rolesテーブルを作り(成功し)、さらに role_idを外部キーとしてadmin_user_roleテーブルを作成しようとすると、 Error Number: 1005 Can't create table '.\test\admin_user_role.frm' (errno: 150) CREATE TABLE admin_user_role (userid VARCHAR(12) NOT NULL, role_id BIGINT DEFAULT 0, FOREIGN KEY (role_id) REFERENCES admin_roles(id) ON DELETE CASCADE) ENGINE = InnoDB; というエラーが出てしまいます・・・ admin_user_roleの記述のどこが間違っているのでしょうか?

    • ベストアンサー
    • MySQL
  • Access、同じテーブルの2つの項目対他のテーブルで1つの項目のリレーションは可能?

    Accessで販売管理をしています。 以下のテーブルを作成し(*は主キーです)、 [売上T]  [商品M]  [顧客M]  [受注T] *売上NO  *商品ID  *顧客ID1  *受注NO 商品ID   商品名    *顧客ID2  商品ID 日付    顧客ID1     顧客名    受注日 金額    顧客ID2            受注金額        受注先1        受注先2 参照整合性にチェックを入れリレーションでつないでいます。 リレーションシップは下記のとおりです。 [売上T]商品ID―[商品M]商品ID―[受注T]商品ID [商品M]顧客ID1及び2―[顧客M]顧客ID1及び2―[商品M]受注先1及び2 ここで顧客と受注先が重複することもあるので、顧客Mから顧客ID及び受注先IDの2つのテーブルにリレーションシップを設定しているのですが、 クエリで  [受注T]受注NO及び受注金額、[顧客M]顧客名で抽出したところ、 5000件以上[受注T]にデータがあるはずのものが、1200件ほどしか抽出できませんでした。 ちなみに[顧客M]と[受注用顧客M]というまったく別のテーブルを作成し、 [商品M]受注先1及び2―[受注用顧客M]顧客ID1及び2 とリレーションを作成し、クエリで抽出するとうまくいきました。 しかしこの方法だと、[顧客M]と[受注用顧客M]という2つのテーブルを管理しなければならなくなるので面倒です。 そこで質問です。 同じテーブルの2つの項目対他のテーブルの1つの項目とでは、うまくリレーションが設定できないのでしょうか。 もし出来ない場合、[顧客M]と[受注用顧客M]の2つのテーブルを管理しなければならない訳ですが、 なんとか簡単に管理できる方法(ひとつのテーブルを変更すると簡単にもうひとつが変更できる設定)はないでしょうか。 非常にわかりにくく長い文章で申し訳ありません。 VBA等はさっぱりわかりませんので、普通の設定の範囲内で、できるかどうかよろしくお願いします。

  • こんな場合のER図はどうなりますか?

    こんにちは。データベースの勉強を始めて間もない者です。 例えば、ある中学校の1つのクラスの振る舞いを、ER図で表現することを考えます。各生徒をあらわす「生徒」テーブルを作ります。主キーは出席番号とします。 主キー以外には、名前、生年月日、得意科目、、、などを入れるのですが、「ライバル」という属性も入れたいと思います。自分(今、対象としている生徒)から見てライバルだと思うクラスメイトにあたるものです。 生徒によっては0人だったり多数だったりするので、「生徒」テーブルから出し、「ライバル」テーブルを作り、「生徒」:「ライバル」=1:0以上のリレーションをはります。「ライバル」テーブルの主キーは親の生徒の出席番号(外部キー)とライバルだと思われた生徒の出席番号のペアでいいや、と思ったのですが、ここで問題に気づきました。 出席番号1さんがライバルだと思っているのが、出席番号3さん、5さんとします。3さんは1さんのことをライバルと思っていませんが、5さんは1さんのことをライバルだと思っています。この時の「ライバル」テーブルは、主キーに1と5のペアを持つレコードが2つできてしまって問題になるのでしょうか?それとも、外部キーが異なるので問題はないのでしょうか? 問題があるとすると、どのようにテーブルを定義すればよいのでしょうか。さっきの例では「ライバル」テーブルに1と3のペアをキーとするレコードが1つできますが、これも「1から3へ」という意味が消えないような設計をしたいのですが、よくわからなくなりました。

  • CakePHP テーブル名カラム名の規約について

    CakePHP初心者です。 product(商品) product_category(商品カテゴリ) と言うテーブルがあったとします。 それぞれには、主キーと名称(商品名/商品カテゴリ名)を持つとします。 更に、productにはproduct_categoryの外部キーを持つとします。 これらを規約に合わせると、 // テーブル名 products product_categories // products のカラム id(PK) product_name product_category_id(FK) // product_categories のカラム id(PK) product_category_name に、なると思います。 ここで質問なのですが、カラムの product_name と product_category_name は、 productName と productCategoryName のように、 キャメルケースにする事は、何か問題がありますでしょうか? (主キーや外部キーにならないカラムであっても、 アンダースコア区切りにしないと、不具合やデメリットがあるのでしょうか?) どうぞ、よろしくお願いいたします。

    • 締切済み
    • PHP
  • ER図について

    ER図を書く練習をしています。 就職するために会社に申請し、審査後に応募者(申請者)を受け入れる(合格)か拒否するか(不合格)を決めるケースを想定してER図を描きました。焦点は、「合格/不合格の情報をどのテーブルに持たせるのがよいか」です。添付のURLに(1)、(2)の2つのケースを考えて書いてみました。いずれのテーブルもものすごく簡単に書いたので突っ込みどころは満載だと思いますが、あくまでも、合格/不合格の情報をどこに持たせるかだけに特化したものと考えてください。 (1)http://www.dotup.org/uploda/www.dotup.org15911.jpg.html (2)http://www.dotup.org/uploda/www.dotup.org15912.jpg.html 申請書テーブルは、申請者から受け取った書類を管理するテーブルです。受け取った日や、本件のステータス、結果を応募者に送信したかなどの情報を持ちます。イベント系(トランザクション系)のテーブルです。 (1)のやり方 申請者テーブルには申請者の情報そのものを書類から入力するリソース系(マスタ系)のテーブルです。名前、年齢、前職。。その他諸々を保持します。ここに、合格か不合格かをok_ngというbooleanで持たせることとします。 (2)のやり方 (1)と同様、申請者のテーブルはあるのですがok_ngという属性を持たせずに、代わりに別リソース系テーブル「合格者」を作ります。申請者と合格者の関係は1対1です。お互いがお互いのプライマリキーを参照する外部キーを持ちます。申請者テーブルと合格者テーブルのオプショナリティは必須対任意とします。つまり、申請者のうち、合格した人のみが合格者テーブルに登録されるということです。 上記2点の設計は、どちらも有効でしょうか?有効だとするとメリット、デメリットなどありますでしょうか? (2)のやり方を書いた理由は、とある本に飛行機の「乗客テーブル」と「マイレージプログラム加入者テーブル」のER図があり、その関係が丁度本件の「申請者テーブル」と「合格者テーブル」のような関係になっているのを見た事があるからです。コメント等あれば宜しくお願いします。

  • 外部キーの使い方

    例えば下記のような2つのテーブルがあり、注文票にはメニューのID(外部キー)だけを入れて、料理名や価格は別で持つとします。 ----------------------------------------- ■注文票table ID(int),メニューID(int) ----------------------------------------- ■メニューtable ID(int),料理名(text) ----------------------------------------- ・この2つのテーブルから以下のような出力を得たい時 且つ ・一度のselect文で出力を得る場合、 select文はどのように書けば良いでしょうか? もちろん「select * from 注文票table」だと「料理名」ではなくて「料理ID」が出てきてしまうのですが。。。 ---------------------------------------- ■テーブルID,料理名 ----------------------------------------