質問: MySQLのvarchar データ型の初期値指定を、「NULL」「空文字」何れにするか、で迷っています。 それぞれ「メリット」「デメリット」としてどんなものが挙げられますか? またこの件について言及しているコーディングルール的なものはありますか? **質問経緯** これまでは、(NULLはあまり使用しない方が良い、と以前どこかで見た気がするので)「空文字」指定していました。 しかし、int型のデフォルト値にNULLを指定しているので、整合性を考えると、varchar 型もNULLへ変更した方が良いかな、と思い、質問しました。 MySQL 5.7
回答: MySQLのNULLについては、メリットデメリットというよりも、 NULLの仕様を把握して、適切に運用するほうが良いと思います。 アプリケーションやその実装方法さらには利用している計算言語やフレームワークにより NULLの仕様がある場面ではメリットだが、別の場面ではデメリットになるということが良くあります。 MySQLのNULLについて理解を深めて、どの場合にメリットになるのかデメリットになるのか考えてみるとよいと思います。 NULLの特徴的な仕様としては空文字とNULLは違います。 例えば ``` INSERT INTO my_table (phone) VALUES (NULL);# 電話を持っていないので電話番号が存在しない INSERT INTO my_table (phone) VALUES ('');# 電話を持っているが、番号がわからない ``` nullを使わないで表すと余計にフラグ用のフィールドを用意する必要があります。 さらには電話を持っていない状態かつ電話番号が存在するというよくわからない状態も発生しうるでしょう。 ``` INSERT INTO my_table2 (has_phone,phone) VALUES (0, '');# 電話を持っていないし電話番号が存在しない INSERT INTO my_table2 (has_phone,phone) VALUES (1, '');# 電話を持っているが、番号がわからない ``` なので「存在しない」「空」「データあり」の3つの状態(3値論理)を表現したいときは余計なフィールドがなくて非常にすっきりします。 ``` # 電話を持っていない人を検索する場合 SELECT * FROM phone IS NULL # 電話を持っている人で電話番号がわからない人を検索する場合 SELECT * FROM phone phone = '' # 電話を持っている人で電話番号がわかる人を検索する場合 SELECT * FROM phone phone <> '' ``` ただ「電話を持っていない」=「電話番号わからない」とみなせるシステムの仕様であれば わざわざNULLを使う必要はないでしょう。「空文字」と「データあり」で表現したほうがシンプルでいいと思います。 そのほかにも論理演算ではNULLが混じるとすべてNULLになりますので、計算をする場合は事前にNULLを除外する必要があります。さらには集約関数でもNULLは除外される場合があるので要注意です。 なので論理演算が必要がフィールドであったり、または集約関数で後ほど解析などに利用したい場合は、常にNULLのデータを意識する必要があります。それがコストがかかりそうだなということであれば最初からNULLを利用しないでデータを作ったほうがトータルのコストがかからず運用できる場合もあるでしょう。 また言語やフレームワークにおいてもNULLの扱いが変わってくるので、NULLが扱いやすそうかどうか確認することも大事です。※余談ですが人にもよるところはあると思います。私自身NULLを極端に嫌う人も何人かいました。 質問中にあるコーディングルールというかDB設計のルールというのが正しいですかね? DB設計のルールは一般化されているものはあまりなくて、どちらかというとアンチパターンなんかで表現されることがおおいですね。 SQLアンチパターンではよくNULLを「普通の値として扱わない」と出てきます。NULL自体を普通の値として扱おうとすると無理があり、NULLというのはあくまで「存在しない」という意味以外には利用するべきではないとされています。