🛢️

RDB における Null のこと、全然わかっていなかった

2024/08/25に公開

概要

SQL学習の一環で 達人に学ぶSQL徹底指南書 第2版 を読み進めております。

この中で Null について詳解されているのですが、「自分は全く Null のことを知らなかったんだな」と思うほど、 Null について色々と知ることが出来ました。

自分の理解を整理する目的で、記事に落とし込んでみます。

先にまとめ

  • Null は、値ではない
    • 値ではないため、 xxx == Null のように、 Null を値のように直接 = 等で比較できない(文法エラーが発生する)
  • 値に Null が含まれると、SQLが直感に反する振る舞いをする
    • 値でない Null を比較述語で比較すると、必ず unknown という値になる
    • unknown は、SQLにおける第三の真理値(boolean)であり、unknown が倫理演算に紛れ込むと、直感に反する振る舞いに繋がる
    • 直感に反する => 第三の真理値の登場によって、我々が良く知る true / false の2値による論理演算が通用しなくなる

Null は、値ではない

SQL における Null は「未知」または「適用不能」を表す。

  • 「未知」: 現時点では不明 ... というニュアンス。
  • 「適用不能」: 値を設定する意味がないことを示す。「無意味」や「論理的に不可能」というニュアンス。

SQL における Null は、「値が存在しない」事を示す記号に過ぎない。
そして、Null は値でも変数でもない。
そのため、 xxx == Null のように、 Null を直接他の値や変数と比較述語で比較することはできない(比較を試みると、文法エラーが発生する)。

変数が Null か比較する場合は、 is Null と書く必要がある。

(わざわざ Null だけ is Null といった特別な書き方が用意されているのは、 値ではない Null を何とか比較するため ... と解釈できるかも)

値に Null が含まれると、SQLが直感に反する振る舞いをする

Null は、比較述語で比較すると、必ず unknown という値になる。
この unknown は、SQLにおける第三の真理値(boolean)。
true , false 以外の真理値が入り込むため、直感に反するような挙動に繋がる。

以下は、 truefalse に加え、 unknwon を含めた真理値表。

(書籍より抜粋)

  • t ... true
  • f ... false
  • u ... unknown

◆3値論理の真理値表(NOT)

x Not x
t f
u u
f t

◆3値論理の真理値表(AND)

AND t u f
t t u f
u u u f
f f f f

◆3値論理の真理値表(OR)

OR t u f
t t t t
u t u u
f t u f

このように、第三の真理値が存在することで、真理値の計算がやや複雑化する。
そして、 SQL にて検索で表示されるのは true のみであり、 unknown となる行は表示されない。
以上より、直感に反する振る舞いを観測した場合は、真理値が unknown になっている可能性がある。

unknown が絡む論理積(AND) に対する自分なりの理解

ここでは、 unknwon を「未知」(現段階では不明の値)として解釈する。

true AND unknown の解釈

片方が true で、もう一方が unknown (未知)の場合、 unknown(未知) の真偽値によって式の評価結果が変化し得る。

  • unknowntrue だと、 true AND true となり、全体として true
  • unknownfalse だと、 true AND false となり、全体として false

つまり、 unknown(未知)の値がはっきりしないと、全体として truefalse かわからない。
(言い換えると、 unknown の値が truefalse かはっきりすれば、演算結果がはっきりする)

そのため、 true AND unknwounknwon (unknown側の真偽値がはっきりするまでわからない)になる。

false AND unknown の解釈

片方が false なら、 unknown (未知の値)の真偽値に関わらず、 AND演算全体としては必ず false になる。
そのため、 false AND unknownfalse になる。

unknown が絡む論理和(OR) に対する自分なりの理解

ここでも、 unknwon を「未知」(現段階では不明の値)として解釈する。

true OR unknown の理解

片方が true なら、 unknown (未知の値)の真偽値に関わらず、 OR演算全体としては必ず true になる。
そのため、 true OR unknowntrue になる。

false OR unknown の理解

片方が false で、もう一方が unknown (未知)の場合、 unknown(未知) の真偽値によって式の評価結果が変化し得る。

  • unknowntrue だと、 false OR true となり、全体として true
  • unknownfalse だと、 false OR false となり、全体として false

つまり、 unknown(未知)の値がはっきりしないと、全体として truefalse かわからない。
(言い換えると、 unknown の値が truefalse かはっきりすれば、演算結果がはっきりする)

そのため、 false OR unknwounknwon (unknown側の真偽値がはっきりするまでわからない)になる。

感想

今までは、 "Null を排除するようなテーブル設計を行ってきた" & "それで何とかなっていた" & "大規模なテーブルを扱ったことがない" ため、Null を意識する(≒Null で苦しみ、Nullのことを深く知ろうとする機会)がありませんでした。

本書にて "Nullは値ではない"から始まり、 Null が絡むことで第三の真偽値が登場するなど、全く知らない世界を知ることが出来、大変勉強になりました。。

3値理論の真理値表も最初は戸惑いましたが、 unknown を、「今は分からない値」と解釈して真理値を考えてみると、自分なりに納得の行く形で理解できました。

(自分なりの理解の節を参照)

次は、 unknown が紛れ込む可能性まで考慮された SQL を書く方法へ、学習をつなげていきたいです。

また、書籍全体では、まだまだ 20%程度しか読み終えていませんが、既に多くの学びを得ることが出来ています。

他の章も楽しみです。

Discussion