SSブログ

SQLやC言語でのNULLって何? [SQLポケリ]

本日は、NULLの話題である。SQLやC言語をやっている人にはお馴染みのNULL。JavaやJavaScriptにもnullがあるね。そのヌルのお話である。

WikiによるとNULLの語源はドイツ語であるみたい。詳しくはWikiに行って読んで欲しいのだが、私は何となく英語なんじゃない?って思ってた。ふーん意外。

NULLは値じゃない

Wikiを見てみると、NULLは値じゃないみたいなことが書いてある。NULL値って言うのは変、みたいなことも書いてある。
そうなのか、この際だちょっとよく考えてみよう。

C言語のヌルポインタ

C言語やっているときは、ヌルポインタとかよく言う。ポインタ変数にNULLを代入するとヌルポインタができあがる。ヌルポインタを参照すると即エラーになる。某掲示板で有名になったヌルポである。ヌルポインタを略したのがヌルポだけど、正確にはJavaのNullPointerExceptionを略したものなのでちょっと違うかもだがそう遠くはない。

で、C言語で言うところのヌルポインタはちゃんと値を持っている。
だってNULLはマクロだし。

#define NULL (0)


って書いてあるよ。
だから、以下のコードではポインタ変数がヌルポインタとして初期化される。

#include <stdio.h>

int main()
{
    int *pointer = NULL;
    return 0;
}


普通にやってますよね。

 ヌルポインタで初期化する とか
 ヌルポインタで戻ってきた とか
 ヌルポインタを参照した とか
 ヌルポインタでSEGVくらった とか
 ヌルポ とか

よく言うと思います。

ここで、C言語におけるヌルって何?と言う疑問を投げてみようと思う。
   後でSQLにおけるヌルって何?もやるのでその前振りです。

C言語でヌルっていえば、stdio.hにマクロ定義されている「NULL」がヌルだよね、やっぱり。
C言語ではポインタにしかNULLは代入しない。普通はね。
intの変数に代入できなくもないが、あまり見たことがない。0に初期化したいだけなら普通にint i=0;って書くし。

ヌルポインタにおけるヌルはstdio.hで定義されているマクロのNULL。
ちゃんと値もある、そう0がヌルの正体である。

そう断言しよう...本当か?...それでいいのか...


ヌル文字列
そういえば、C言語には「ヌル文字列」って言うのもあるなぁ。他の言語でも空文字列のことをヌル文字列って言うかも?C言語だけだったか。

まぁ、よしとしよう。この場合のヌルは「空っぽ」であることを意味するものだよね。

確かに、C言語はヌルターミネートの文字列形式なので、文字列データの最後には「ヌル文字」が入っていることがお約束である。ヌル文字は数値としては0の文字。数値0はビットが全部0になるので、2進数でも000000...になる。

何にせよ「C言語のヌル文字は0である」って言うことは間違いない。

 ヌルターミネート  文字列の最後に0を入れて終端させる
 ヌル文字      コードで書けば'¥0' やっぱり0なんじゃない

と言うことはヌルは0なのか?
C言語においてはだけどね。




SQLでのヌル



さて、ここからはSQLに頭を切り替える。SQLはリレーショナルデータベースを操作するプログラミング言語である。SQLにはポインタは無いが、NULLはある。しかも、ちゃんとした(?)NULLがあるのである。

SQLを使っている人達は、

 データがNULL とか
 結果がNULLだよ とか
 NOT NULL制約 とか
 NULLは検索できない? とか
 計算結果が表示されないよ? とか
 プライマリキーにはNULLは含められない! とか

よく言ってます。というかよく言ってましたし、今はよく書いてます。

SQLやデータベースにおけるNULLっていうのは特別なんです。SQLの生みの親であるE.F.コッドさんが「こだわったところ」なんでしょうね多分。
E.F.コッドさんとは友達ではないし、よくわからないので「多分」って付いていますが、多分合ってます。

SQLでのNULLは0と同じではない。C言語でのヌルポインタはアドレス0を指すようなポインタだし、ヌル文字はコード0の文字だし、マクロのNULLは0で定義されているし...
というわけでC言語においては「ヌルは0だ」と考えてもそう問題にはならない。

ところが、SQLでNULLを0と考えてはいけないのである。その根拠を列挙していきたいと思う。

NULLは計算できない

SQLでは、NULLを計算することができない。NULLが0であればNULL+1の計算結果は1になるはず。実際やってみるとNULL+1の計算結果はNULLになる。

NULLは検索できない

SQLでは、比較演算子を使ってNULLを検索することができない。WHERE column=NULLのようにしてもcolumnがNULLである行を検索することはできない。NULLが0であればなんか検索できそう。
ちなみにそれでは困ることもあるので「IS NULL」を使えば検索できるようになっている。WHERE column IS NULLと書けば検索可能。

C言語の場合はヌルポインタであるかどうかを==演算子で比較することができるし、エラーチェックなんかでやたらにやっているはず。やはり、この点が大きく違う。

NULLはNULLと等しくない

これは「検索できない」と同じかも知れないが、条件式NULL=NULLの結果はUNKNOWNである。NULLが0ならTRUEになりそうなもの。

NULLは小さくも大きくもない

比較演算子で大小関係を調べることができる。しかしNULLと比較しても大小関係はわからない。NULLが0ならとりあえずは比較できそう。
ソートすれば先頭か末尾にNULLが出てくるが、これはデータベース依存。大小関係が決定できないので便宜上しょうがなく先頭か末尾にまとめて出しているだけ。

NULLは集計時に無視される

SUMで合計を集計するときにNULLを0としても結果は変わらない。しかし、AVGで平均を計算する際にNULLを0としたら微妙に結果が違ってくる。

他にもありそうではあるが、ここまでとしよう。

SQLでのNULLは「空っぽ」を意味するもので0ではない。SQLではテーブルのセルや演算を行うときの一時変数に「有効なデータが格納されているかどうかのフラグ」を持っていると考えれば理解しやすいと思う。
SQLにおいてNULLは値ではなく状態を意味するもの。データが格納されていない状態がNULL。なのでやはり「NULL値」っていう表現はSQLの場合は適切ではない。

C言語では変数にそんなフラグを持たせるのは無駄と考えたのであろう。当時はメモリ容量だって少なかったからね。しょうがないのでヌルポインタやヌル文字は0とすることでごまかした。
なので、C言語においては

 NULL値を便宜的に0としている

みたいなフレーズがあってもおかしくない気がする。マクロのNULLは0で定義されていて値があるわけだし。

でも「NULL値」ってよく言ってるような気もするなぁ。

本日は以上とする






サイト内を検索

nice!(0)  コメント(0) 
共通テーマ:日記・雑感


Copyright Atsushi Asai Google+朝井淳
[改訂第4版]SQLポケットリファレンス

[改訂第4版]SQLポケットリファレンス

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2017/02/18
  • メディア: 単行本(ソフトカバー)

イラストで理解 SQL はじめて入門

イラストで理解 SQL はじめて入門

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/05/16
  • メディア: 単行本(ソフトカバー)

[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)

[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2015/03/03
  • メディア: 単行本(ソフトカバー)

Access クエリ 徹底活用ガイド ~仕事の現場で即使える

Access クエリ 徹底活用ガイド ~仕事の現場で即使える

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/05/25
  • メディア: 大型本