質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.23%

外部キーがnullであることによる問題点

解決済

回答 4

投稿

  • 評価
  • クリップ 1
  • VIEW 9,186

KaedeKazane

score 383

現在構築しているシステムについて

採用管理システムを構築しており、以下のようなデータベース構造を検討していました。

  • 応募者テーブル
    [ID][応募日][名前][連絡先]...
  • 面接予定テーブル
    [ID][応募者ID][日付][担当者]...

その後、どうせなら「面接予定テーブル」を「来客予定テーブル」にしてその他の来客予定も登録し、来客予定全体を管理しようという話になりました。
しかし「その他の来客予定」には関連付ける応募者情報が存在しないことになります。
そのため、以下のようなデータベース構造に変更することにしました。

  • 応募者テーブル
    [ID][応募日][名前][連絡先]...
  • 面接予定テーブル
    [ID][応募者ID][予定ID]
  • 来客予定テーブル
    [ID][日付][来客種別][担当者]...

疑問点

データベース構造については変更後のもので問題ないと考えています。
しかし変更前の構造でも、来客種別の項目を追加して「その他の来客予定」の応募者IDをNULLにすれば、同じようにシステムを構築できるように思います。
それでも構造を変更した方がいいと考えた根拠は、「必ずしも応募者と関連付くわけではないのに、応募者テーブルと紐付いているのが綺麗な構造じゃない」という漠然としたものでした。

そこで質問なのですが、変更前のデータベース構造でシステムを構築した場合、どのような問題・弊害が起こることが考えられるでしょうか。
今までは外部キーで関連付ける情報は必ず存在している状況でシステムを構築しているため、その辺りの経験や知識が不足しているのでよろしければお聞かせください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+2

もし設計段階でフィールドにNullを含まないことが確定できるのならば、
極力Nullを含まない設計が望ましいと考えます。
(外部キーで縛れるほうがよりいいですね)

例えば、値と比較する場合、SQLは伝統的にNullを対象外とします。
つまり、設計者はそのフィールドを対象に検索したい場合、
値があるのか、あるいは空値なのか、Nullなのか、
3項演算をせねばなりません。

また、取得した結果がNullの場合に、空値として扱いたい場合
変換もせねばならないでしょう。
そうなれば、SQLも煩雑になります。

このフィールドにインデックスを貼りたくなった場合、
パフォーマンスにも影響が出ます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/22 09:03

    回答ありがとうございます。
    NULLという特殊な値を持ってしまうことで、空値を含む本来の型の値とは異なる挙動を常に意識ないといけなくなる、ということですね。

    回答を見て「NULLではなく空値にすれば大丈夫では?」とも考えたのですが、
    その場合は外部結合を行うと照合先の部分がNULLとなり、他の問題は解決できても「取得後の値を変換する」という問題は残りますね。
    逆に考えれば、結合は空値でないものしか行わず、結果にNULLが含まれなければ変更前の構造でも問題ないでしょうか?

    キャンセル

  • 2016/10/22 09:28

    >逆に考えれば、結合は空値でないものしか行わず、
    >結果にNULLが含まれなければ変更前の構造でも問題ないでしょうか?

    そのあたりは一般論を用いるべきではなく、実設計で柔軟に対応するべきでしょう。
    ただ、自身の経験則から言えば、Null入らない予定だけど、
    別に縛ることもないからNull許可しとけ、なんてフィールドには
    大抵、(自分を含めた不用意な)誰かがNullを入れてしまうものなのです・・・。(><。

    キャンセル

  • 2016/10/22 09:43

    確かに、設計時は「空値でないものしか結合しないから大丈夫」と思って作っても、時間が経ってから見た時に「結合先が存在しないけど大丈夫か?」とか考えたりもしそうですね…
    事前に防止できるなら、防止するに越したことはないと思います。

    大変参考になりました。
    ありがとうございました。

    キャンセル

+2

RDBの世界ではNULLは邪悪な存在と考える方も多いようです。

私はORMを通してRDBを使う事がほとんどなので、あまり気にしなくてもORMが適当にやってくれるので「NULLダメ!絶対!!!」とまでは思わないのですが、極力避けられるところは避けるように気にかけてはいます。

なんでダメなんだー?? という話は
NULL撲滅委員会 がおもしろかったです。

同じ方が書かれている3値論理 ―― 神のいない論理 も非常に勉強になりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/22 09:12

    回答ありがとうございます。
    ORMがNULLの場合の特殊な処理を行ってくれている場合は、あまり意識なくても済みそうですね。
    しかし代わりに処理してくれているだけで、やはりNULLがそれだけ取り扱いに気をつけなければいけないことに変わりはないということですね。

    参考のURLもありがとうございます。
    まだ流し見程度ですが、読みやすくまとめられているのでじっくり読んで参考にしたいと思います。

    キャンセル

0

来客者テーブルを作って、来客者種別に「求職中」とか「取引顧客」とかいれて、
来客予定テーブルの目的種別に「面接」とか「打ち合わせ」とかいれてやれば、nullとか考える必要ない気がするが、、、

つまりer設計しません?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/25 15:02

    回答ありがとうございます。
    「面接予定テーブル」を「来客予定テーブル」に一般化したように、「応募者テーブル」を「来客者テーブル」に一般化すれば良いのでは、ということですね。
    当初の目的が採用部門で利用する応募者の管理システムだったため、その他の来客者情報もシステム内で管理する、という発想がありませんでした。

    仰る通り、来客者テーブルとして運用した方がより広く、多様な情報を管理できるシステムになると思います。
    しかし今回は応募者に関する情報管理と、来客予定に関しては応接室の空き状況が把握できればいい、ということなので質問文に記載した3テーブルで進めたいと思います。
    (その他の来客者について詳細な情報管理しているわけではないようなので、作業量が増えるという懸念もあります…)

    キャンセル

0

外部キーがNULLでないこと--- の意味解釈がDBエンジンに任せ、人依存でない場合、と
--- DBエンジンには任せず運用担当者がルールを守り場合、と
の2通りでそれぞれの功罪をよーく考える必要があります。
一方が良くて他方が悪いと常に言うことがあれば幸せですが、現実には「システムで対応できないので、肉体労働を強いられて周囲や肩書の上位の人から不興を買う」こと覚悟できないこともあるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/25 20:08

    回答ありがとうございます。
    システム側でNULLを生まないような仕組みにしておくか、NULLを生まないような使い方を利用者に求めるか、というお話でしょうか?

    システム側と利用者側、それぞれにどこまでを求めるかの線引きは難しいところですね。
    私も作業効率化のためにとシステム化した結果、そもそも処理しなければいけない仕事量が増えてしまった、という事もありました。
    システム側に求めるのか、利用者側に求めるのか、それぞれの場合にどのような影響があるのか。設計時には常に意識したいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる