Q. なぜ SQL では NULL 判定に IS 演算子を使うの?
気になったので調べた。
あいまいな解釈が含まれるので、ご指摘ありましたらぜひください。
Java, JavaScript など一部の言語では、ある値と null
が比較されたとき、false
を返すのが一般的とされています。これは、null
が Falsy な値 だとされているからです(参考)。
この考え方がベースになっていたので、「SQL ってなんでわざわざ null 判定に専用の演算子があるんだ?」と思っていました。
=
で比較するとどうなる?
SQL では、値の比較は =
演算子で行うのが通例です。
では、null
との比較に =
を使うとどうなるのでしょうか?
一例として、Oracle Database のドキュメントでは、値としては null
、評価としては unknown
が返されると書かれています。
unknown
?聞きなれないワードが出てきました。
どうやら、私たちが知っているような論理評価の方法とはすこし違うみたい。
SQL の論理モデル
一般的なプログラミング言語では、2値論理を採用しています。これは、条件式の結果を true
または false
のどちらかに限定する考え方です。
これに対し、SQL では 3値論理 という考え方が採用されています。これは、先ほどの true
false
に unknown
を追加した論理モデルになります。
null
ここで少し脱線します。
そもそも、null
とはなんでしょうか?なんとなく「からっぽの値」「未定義」みたいなイメージを持っていましたが、調べた感じは次の二つに分解できます。
- 未知: まだ判明していない情報。(例:空中で回転するコインの裏表)
- 適用不能: オブジェクトが持てない情報。(例:コインの目の色)
null
とは、あくまで上2つを示す 記号 であると解釈するのがよさそうです。
unknown
さて、本題に戻ります。
3値論理において unknown
は、「判定が不可能なこと」を示す値です。
false
が「偽、否定」を示すのに対し、unknown
は「判定不能」を示します。やや似た概念(というか今まで同義として扱ってきた)なので、すごく混乱します。
そして、この論理値は前述のとおり null
との比較演算などでよく現れます。
unknown
は必要なのか?
なぜ なぜ unknown
は必要なのでしょうか?
通常のプログラミング言語と同じ false
で代用することの何が問題なのでしょう?
ここからは自分なりの解釈になるのですが、null
はあくまで「記号」でしかないと考えます。
ほかの値が「紙に書かれたデータ」だとすると、null
は「紙すら存在しない」もしくは「紙を置く空間すらない」ことを示す値です。これは上で示した「未知」「適用不能」に該当します。
SQL 上では、文字列数字真偽値などの様々な「値」と、null
という「記号」を明確に分離することを目的として unknown
が用いられる、と考えます。
一例として、コインの裏表を true
と false
で考えてみます。まだ空中で回転しているコインは null
とします。
このとき、図らずとも「コインが裏の状態(false)」と「コインの裏表が確定していない状態(null)」が同じだと判定されてしまいます。これは困った。
こういった「複数の意味をひとつの単語に対して課すこと」は、わたしたちの意図しない場所で思いもよらない論理エラーを引き起こす可能性があります。これを防ぐために3値論理が存在し、安全性を担保しているのではないか?と結論付けます。
これらを踏まえたうえで、あえて「この値は 未知/適用不能 な状態か?」という状態を検査する場合を考慮して IS
演算子が用意されているのではないか?と思っています。
参照
Discussion