MySQLにおける「NULL」って「ただ値が無いだけ」じゃなかったのね

MySQL
誤解してました







(2020年のボツネタのサルベージです。なんでボツにしたのかはわからない)


NOT NULL

新規にテーブルを作成する機会があり、ある要素は必ず入力されるがある要素は入力すべき数値が未取得で空であることがある、という状況でした。当初、両方とも「NOT NULL」でカラムを作成したんですがこれはあくまで「手癖」であって、なぜそれでいいのかわかってませんでした。そして考える、あれ、空になることを想定しているカラムならNULLの入力を許可した方が良いのではないかと。


ドキュメントにこう書いてありました。


NULL 値は「データなし」を意味します。 NULL は大文字と小文字のどちらでも記述できます。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 9.1.7 NULL 値

概念的には、NULL は「存在しない不明な値」を意味し、ほかの値とは多少異なる方法で扱われます。

(中略)

NULL を操作するときによくある間違いは、NOT NULL と定義されたカラムにはゼロや空の文字列は挿入できないと想定することです。 これらは実際に値ですが、一方 NULL は「値がない」ことを意味します。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 3.3.4.6 NULL 値の操作


わーお。つまり私は初心者だということですねー。MySQL触ってもうすごい時間経つのに全然わかってなかったです。恥ずかしい。



NULLは「空」ではない

  • NULL → その要素がわからない。または定義されていない。
  • 空文字 → その要素がない。


ドキュメントの例を見つつ現実に即して考えると、顧客リストを作るときの「電話番号がない」と「電話番号がわからない」の間にはそう大きな違いはない。知りたいことは「電話で連絡を取れるかどうか」であって、電話番号がなかろうがわからなかろうが、電話で連絡が取れないことには変わりがないから。


でもデータとして扱おうとするとちょっと変わってきます。


MySQL に限らず、SQL のNULL の仕様には何回か「えっ」と驚くことがあったのでメモしておこうと思います。5.1 版の日本語マニュアルがなかったものについては、4.1 のマニュアルを参照しました。

MySQL のNULL ではまったことあれこれ – LukeSilvia’s diary


かなり古い記事なので今は当てはまらないこともあるのかも知れないけど、考えることが増えるのは間違いないです。単純に「電話で連絡が取れない」ことを知りたいだけであれば、「NOT NULL」にしておいた方が無難かな。


このあたりは大昔に書いていた「nullと結合するとnullになる」という話とも関係がありそうですね。


[MySQL] nullと結合するとnullになる



NULLが「不明」ならば、それと連結した文字列が「不明」になるのは当然のことですよね。「af***35」と一部伏せ字にされた文字列があったとして、そこに「4w8」という文字列を連結したところで全体は「af***354w8」となって不明に変わりがない。だからNULLと連結しても不明になる。当時は「ドキュメントにそう書いてあった」までで理解が止まってましたけど、つまりはそういうことでした。なるほどそうだったのか。JavaScriptにおけるundefinedに似てる?



知らないことって多いですよね

いやーもう、日々勉強です。幸い、技術者というのは知らないことや新しく知ることだらけなのでそういう方向の欲求が満たされることはなく、永遠に楽しめるので良いですよね。また明日もきっと新しい何かを学ぶんでしょう。大事ですよね。ええ。