日常用語で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と同様なので省略.

NULLの意味は

次回はNULLを日常用語に翻訳する。
そして、SQLが想定しているNULLの意味と、現場で使われているNULLの意味がずれている例を示して、こういうデータモデリングをしたらNULLの意味がそれこそ不可解になってしまう、だから、RDBに実装するならこんなモデルにしない方がいい、ということまで書いて終わりの予定。

*1:Wikipediaを見ると、3値論理にも何種類かあって、それぞれ真理表が異なるらしい