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

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

ただいまの
回答率

89.24%

nullは撲滅?

解決済

回答 3

投稿

  • 評価
  • クリップ 4
  • VIEW 2,458

jk233

score 53

前提・実現したいこと

日々の仕入データに対して、任意のタイミングで別システムへの連携(CSV出力)を行う仕組みを検討しています。

(仕入データ)
仕入No 仕入日付 数量 単価 商品CD CSV出力No
1      5/1  10 100  102   1
2      5/3  20 300  105   1
3      5/12  5 100  102   2
4      5/10  30 500  101   
5      5/3  -10 300  105

CSV出力Noに数字が入っていれば、別システムへ連携(CSV出力)済みを意味します。
なお、性能のためにCSV出力データも別に保持します。

(CSV出力データ)
CSV出力No 件数 合計金額
1      2   7000
2      1    500

仕入データのCSV出力Noカラムについて、どのように設計するか悩んでいます。

案1 nullを許容する

(仕入データ)
仕入No 仕入日付 数量 単価 商品CD CSV出力No
1      5/1  10 100  102   1
2      5/3  20 300  105   1
3      5/12  5 100  102   2
4      5/10  30 500  101  null
5      5/3  -10 300  105  null

案2 nullの代わりに0を入れる。

(仕入データ)
仕入No 仕入日付 数量 単価 商品CD CSV出力No
1      5/1  10 100  102   1
2      5/3  20 300  105   1
3      5/12  5 100  102   2
4      5/10  30 500  101   0
5      5/3  -10 300  105   0

案3 仕入データに持つのではなく別テーブルに切り出す。

(CSV出力Noデータ)
仕入No CSV出力No
1      1
2      1
3      2

どのようにするのが良いでしょうか。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+4

kaputarosさん、ttyp03さんとも案3・別テーブルを作るのはまずやらないとはおっしゃっていますし、私もまずその選択肢は選びませんが、一点認識しておくべきは、この案3が教科書的には最も正しい方法であるということです。
http://nippondanji.blogspot.jp/2013/11/blog-post.html
DBスキーマの正規化において、「NULLが登場するカラムがあるなら、それは別テーブルに切り出すべき情報なのだ」は基本中の基本です。そのことをきっちり押さえた上で、それ以外のもう少しやりやすいやり方(もしくはパフォーマンスの出るやり方)を選んでいく必要があります。

案1と案2の違いは、「どんなエラーを未然に防ぎたいか」によって決まってきます。
案1・NULLを使用するのはどんなエラーを起こし得るか? それはWHERE句の書き間違いです。NULLは通常の値とまったく異なる挙動(NULLの伝播)を起こしますから、ちょっと複雑な問い合わせロジックを書こうとしたときに意図と異なる挙動を引き起こすことがあります。
案2・0を代入するのはどんなエラーを起こし得るか? それは、存在しないCSV出力番号を誤って格納してしまうこと、データ不整合です。0というCSV出力データにないIDを持とうとすると、テーブル間の外部キー参照がかけられなくなりますから、不整合を未然に防げません(案1や案3ならば外部キー参照をかけることが前提になります)。

WHERE句の書き間違いが怖いか、データ不整合をチェックできないことが怖いか、それによって案1と案2を選択してください。どちらも怖い、となったら迷わず案3です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/05/30 13:06

    リンク先が大変勉強になりました。
    SQLを書いた経験が乏しいため、WHERE句の書き間違いの方が怖いです。
    今回は案2で行こうと思います。

    キャンセル

  • 2016/05/31 12:46

    SQLに強くなるために押さえておきたいエンジニアの人は二人いて、一人がこのブログの奥野幹也さん、もう一人がミックさんといって、おそらく「NULL撲滅」というタイトルを付けているということはミックさんのウェブサイトはもうお目を通しておられるのでしょうね。
    お二人とも書籍・雑誌の執筆がいろいろあります。書店で手に取ってみてください。

    キャンセル

0

別テーブルである必要はないと思います。
1つのテーブルで済んだほうが、副問い合わせが減ってSQLの処理速度も速くなりますし。

nullだと想定外の動きをすることもあるそうで。
データベースのINT型項目にNULLはNG?

入力区分のカラムを追加して、そこで判断するのも手かと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/05/30 13:03

    入力区分のカラムを追加することを検討してみましたが、(メリットもあると思いますが)冗長になってしまうような気がするので、今回は見送ろうと思います。
    ありがとうございました。

    キャンセル

0

案1~3、いずれの案でも問題ないと思います。
ただ案3は冗長な気がするので、自分では選択肢に入れません。
さて、質問としてはNULLを使った方が良いのかどうか、ということでしょうか。
撲滅、とまで言っているので、NULLの存在意義のようなことでしょうか?

例えば今回のように0は未出力、0以外は出力済み、とフラグのように定義づけられるものはNULLを使わなくても良いでしょう。
金額などはどうでしょうか。
金額の場合、0円という値と、未入力(登録)という値は別物ですから、NULLを許容するケースもあるでしょう。
もちろん金額の場合でも、今回の質問のように、入力済みフラグみたいなものを設ければ、0と入っていても未入力扱いにすることはできます。
どちらが使いやすいかは、作ろうとしているシステムによると思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/05/30 13:02

    CSV出力Noが0になることは理論上ないので、「0は未出力」というルールにしようと思います。
    ありがとうございました。

    キャンセル

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

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

同じタグがついた質問を見る