日常用語でnullを理解する(1)
セルコの本なんかには、nullを参照するSQLが直感に反する結果を返すことがあると書いてあるのだが、3値論理は「論理」というぐらいだから人間にとって*常に*不可解なものであるはずがないし、だったらnullがらみのSQLの挙動を直感的・日常的な用語だけで(=ドモルガンの法則とか使わないで)説明することができるはずだ...
と思って新人研修で試してみたところ良好な結果を得られたので、ブログにも書く。
どこが直感的ではないか
nullが何かすごくやばいものだとされる根拠のひとつに、
NOT INのサブクエリがnullを1行でも返すと、メインクエリの結果が常に0件になる
という現象がある。
たとえば「3値論理とNULL」には、サブクエリがnullを1つ返したために「Bクラスの生徒と年齢が一致しないAクラスの生徒」が特定できない、という例が挙げられている。
この結果が直感に反するように思われるのは、
nullというのは「値がない」のだから、19とか21と比較しても絶対に一致しないのではないか。
であれば、19歳・22歳の生徒が検索結果に含まれるのが正しいのではないか。
と感じるからだろう。
SQLの挙動を好意的に解釈すれば
人間である以上、実世界では必ず年齢があるのだから、Bクラスに年齢不明の生徒が1人でも
居たら、Aクラスの生徒全員は、データベース上は年齢不明の生徒と、実世界で年齢が一致
している可能性がある。だから「一致しない」ことを保障できる生徒はAクラスにはいない。
よって、結果表は0件になる
ということになる。これはこれで筋が通ってる思うが、あんまりすっきりしないかもしれない。
が、SQLにおける
- UNKNOWNの意味
- NULLの意味
を、それぞれ日常用語に翻訳して一度「フーン」と思っておくと、上のような理屈も「ああそうですね」て感じになる。
UNKNOWNの意味
本丸のNULLの前に、まず3値の真理表を理解しなくてはならない。
3値のAND/OR/NOTの真理表:
AND | TRUE | UNKNOWN | FALSE |
---|---|---|---|
TRUE | TRUE | UNKNOWN | FALSE |
UNKNOWN | UNKNOWN | UNKNOWN | FALSE |
FALSE | FALSE | FALSE | FALSE |
OR | TRUE | UNKNOWN | FALSE |
---|---|---|---|
TRUE | TRUE | TRUE | TRUE |
UNKNOWN | TRUE | UNKNOWN | UNKNOWN |
FALSE | TRUE | UNKNOWN | FALSE |
NOT | |
---|---|
TRUE | FALSE |
UNKNOWN | UNKNOWN |
FALSE | TRUE |
これを
「true AND unknown は unknown, true OR unknown は true」
「false AND unknown は false, false OR unknown は unknown」
...
と丸暗記してもいいんだけど、すっきりしないので、日常用語に翻訳してみる。
SQLが採用する3値論理*1のUNKNOWNは「trueかもしれないし、falseかもしれない」という意味と考えればよい。
よって、真理表のunknownに true/false を順に代入してみれば、そのマス目の真理値が何になるかがわかる。
たとえば「true OR unknown は true」である理由は。
このunknownにtrue/falseを順に代入してみると、
true OR true -> true
true OR false -> true
どっちにしろ結果がtrueになることがわかる。よって true OR unknown は true.
次に「true AND unknown は unknown」である理由。
このunknownにtrue/falseを順に代入してみると、
true AND true -> true
true AND false -> false
となり、結果もまた「trueかもしれないし、falseかもしれない」。よって true AND unknown は unknown.
「NOT unknown」はANDと同様なので省略.