(Translated by https://www.hiragana.jp/)
第8回 SQLにおける論理演算~なぜ真理を隠すのか~ (1)各DBの真理値型のサポート | gihyo.jp

SQLアタマアカデミー

だい8かいSQLにおける論理ろんり演算えんざん~なぜ真理しんりかくすのか~ (1)かくDBの真理しんりがたサポート

はじめに

真理しんり論理ろんり演算えんざん重要じゅうようせい

プログラマやSEのみなさんは、真理しんり真偽しんぎというものをごぞんじのこととおもいます。ほとんどの言語げんごっている基本きほんてきなデータがたで、数学すうがくしゃGeorge Booleの名前なまえにちなんで「BOOLがたとか「BOOLEANがたともばれています。コンピュータを利用りようしていると、BOOLEANがたつtrueしんとfalseにせの2つのと、NOT、AND、ORという3つの演算えんざんだけからるシンプルな演算えんざん論理ろんり演算えんざんおこなうことがおおくあります。これはプログラミング言語げんごだけでなく、コンピュータの回路かいろ基礎きそにもなっている演算えんざんです。

SQLにおける真理しんり論理ろんり演算えんざん

SQLにも、真理しんり論理ろんり演算えんざん存在そんざいします。存在そんざいするどころか、WHEREやHAVINGは、それ全体ぜんたい論理ろんり演算えんざんのカタマリです。だから真理しんりはSQLの根幹こんかんをなす重要じゅうよう要素ようそっていいのですが、それにもかかわらず、SQLとリレーショナルデータベースは極力きょくりょくこの真理しんり論理ろんり演算えんざんをユーザからかくそうとする傾向けいこうがあります。標準ひょうじゅんSQLに正式せいしきのデータがたとして真理しんり追加ついかされたのは、SQL-99でした。SQLの誕生たんじょう[1]から25ねんのことです。しかも、真理しんりがたをサポートしているDBMSもまだおおくありません後述こうじゅつ⁠。

では、なぜSQLとRDBは真理しんり存在そんざいかくそうとするのでしょう?理由りゆうは、そこにうしくらところがあるからです。真理しんりは、ときにSQLの致命ちめいてき欠陥けっかんとまでばれるほどのおおきな問題もんだいかかえた領域りょういきです。

本稿ほんこうんではじめてこの話題わだいについてることになるひとは、かなり混乱こんらんした印象いんしょうけるかもしれません。

それは一部いちぶには、筆者ひっしゃ力不足ちからぶそくによるものです。しかし、より本質ほんしつてきには、そもそもはじまりからして混乱こんらんしているからなのです。SQLも、そしてデータベースのかく実装じっそうも、この問題もんだいたいする態度たいど混乱こんらんをきわめていて、しかもいっこうに収拾しゅうしゅう気配けはいせません。

それでも、SQLにとって真理しんり論理ろんり演算えんざん重要じゅうよう技術ぎじゅつ要素ようそであることにわりはありません。本稿ほんこう最後さいごで、SQLを論理ろんり演算えんざん観点かんてんから使つかいこなすといかに便利べんりかを解説かいせつします。

読者どくしゃ対象たいしょう
  • 真理しんりえばtrueとfalseしかないとおもっているひと
  • 「3論理ろんりっていたけど、だい3のをNULLだとおもっているひと
  • SQLで真理しんり論理ろんり演算えんざん存在そんざい意識いしきしたことのないひと
稼働かどう環境かんきょう
  • すべてのリレーショナルデータベース
.

かくDBの真理しんりがたのサポート

DBによりサポートじょうきょうあつかかたことなる

真理しんりがたれつつテーブルをつくるのはとても簡単かんたんで、つぎのようにデータがたをBOOLEANがた宣言せんげんするだけです。

  • CREATE TABLE BOOL_TEST (bl BOOLEAN);

これで、真理しんりがたれつblをつテーブルがつくられる……かどうかは、じつ実装じっそう依存いぞんです。主要しゅようなデータベース製品せいひんのうち、現時点げんじてんでこのDDLData Definition Language実行じっこうできるのは、PostgreSQLとMySQLのみです。ベンダーの3製品せいひん(Oracle、SQLServer、DB2)では、いずれも真理しんりがたをサポートしていないためエラーになります1⁠。

1 BMS 真理しんりがたのサポートじょうきょう
DBMS真理しんりがたのサポート
PostgreSQL 8.3サポートする。ただし、unknownをNULLで代替だいたいする
MySQL 5.1サポートする。ただし、unknownはサポートせず、内部ないぶてきには0/1の整数せいすうとしてあつかわれる
Oracle 11gサポートしない
SQL Server 2008サポートしない(ただし、0/1のるBITがた存在そんざいする)
DB2 9.5サポートしない

しかも、PostgreSQLとMySQLも、真理しんり完全かんぜんにサポートするわけではないのです。どういうことかというと、真理しんりというからにはもちろんtrueとfalseがあって、その部分ぶぶんのサポートにはどちらも問題もんだいありません。MySQLはこれを0/1で代替だいたいしているというこまかい問題もんだいがありますが、些細ささいなことです。したがって、どちらのDBでもつぎのINSERTぶん問題もんだいなく実行じっこうできます。

  • INSERT INTO BOOL_TEST VALUES (true);
    INSERT INTO BOOL_TEST VALUES (false);

しかし、ここからが厄介やっかいはなしなのですが、SQLの真理しんりには、上記じょうき2つののほかに、unknown不明ふめいという3番目ばんめがあります。MySQLはこのだい3をサポートしませんし、PostgreSQLはこれをNULLで代用だいようするというあきらかに間違まちがった独自どくじ仕様しよう採用さいようしています[2]⁠。

つぎのINSERTは、PostgreSQLでもMySQLでもエラーになります。

  • INSERT INTO BOOL_TEST VALUES (unknown);

なぜunknownが存在そんざいし、NULLとはあつかいがことなるのか

なぜSQLがunknownという奇妙きみょうっているかという理由りゆうは、本稿ほんこうでは詳細しょうさい省略しょうりゃくしますが、重要じゅうよう結論けつろんだけをべると、NULLとunknownはまったく別物べつものであり、これらを混同こんどうしてはならない、ということです。

というのも、unknownというのはそもそも、ではないNULLと通常つうじょう比較ひかくできないために(しかたなく)まれた真理しんりであるからです。じゃあNULLはなになのか、という疑問ぎもん当然とうぜんるとおもいますが、これにたいするこたえは、NULLとは「ここにはがない」というぶん(statement)だ、というものです。ただ、画面がめん表示ひょうじじょう⁠ここにはがない」という文章ぶんしょうでははばるので「NULL」という簡潔かんけつなマークで代用だいようしているだけです。これがなんとなく人間にんげんにはデータののようにえてしまうのは、ただの錯覚さっかくです。

したがって、せっかく真理しんりがたをサポートするという先駆せんくてき仕事しごとをしてくれたPostgreSQLにはわるいのですが、NULLでunknownを代用だいようしては本末転倒ほんまつてんとうです。

ぎゃくにこの観点かんてんからると、なぜデータベースがいずれも真理しんりがたという基本きほんてきなデータがたのサポートに消極しょうきょくてきか、という理由りゆうもほぼ推測すいそくがつきます。それは、unknownがあるからです。

なか大半たいはんのプログラマやSEは、真理しんりといえばtrueとfalseの2しかないとかんがえています。そこに3つSQL独自どくじ真理しんりがた導入どうにゅうしたら、混乱こんらんまねくのは必定ひつじょう(ひつじょう)です。なにしろ、2しめすように、3論理ろんり演算えんざんは2論理ろんり演算えんざんくらべて非常ひじょう複雑ふくざつで、すっと直観ちょっかんてき把握はあくできるものではありません。ANDとORの演算えんざんわせすうは、2論理ろんりの22=4から、32=9とばい以上いじょうえてしまいます。

それにくわえ、3のunknownがNULLと勘違かんちがいされやすいときています。こうしたいくつもの悪条件あくじょうけんによって、どのデータベースも、SQLに真理しんりなかったことにしたいという気持きもちがまれても、無理むりからぬところはあります。

2 3論理ろんり真理しんりひょうあみ部分ぶぶんが3論理ろんり特有とくゆう演算えんざん
図2 3値論理の真理表(網掛け部分が3値論理特有の演算)

おすすめ記事きじ

記事きじ・ニュース一覧いちらん