「等しい」と「重複している」の違い。それらとUNIQUE制約の関係


SQLを使っていると、あたかもNULLがNULLに等しいかのように見える場面が多々ある。
例えば DISTINCT や GROUP BY で複数のNULLが1個に集約されるとか。あるいは集合演算子(UNION, EXCEPT, INTERSECT)でのNULLの扱いとか。
SQL92の解説書

標準SQLガイド (アスキーアジソンウェスレイシリーズ―Ascii Addison Wesley programming series)

標準SQLガイド (アスキーアジソンウェスレイシリーズ―Ascii Addison Wesley programming series)

によれば、NULLとNULLは等しくはないが「重複」はするのだそうだ。
列col1とcol2が等しいか、ともにNULLならば、それらは重複していると判定される。
DISTINCTやGROUP BY, 集合演算子は重複を排除するものであり、GROUP BYが複数のNULLを1行に集約するからといって、それは複数のNULLが「等しい」からではない。...ということらしい。


ではSQLの規格は、「等しいこと」と「重複」のどちらに基づいて一意性を判断するよう求めているか。
SQL92には、UNIQUE制約は「いかなる2行も、nullではない同じ値を持たないとき」に満足される、と書いてある。
つまり「重複」ではなく「等しいこと」に基づいて一意かどうかを判断せよ、ということで、やはり前回見た「NULLがUNIQUE制約に縛られない」というMySQLの挙動は、SQLの規格に適合しているようだ。