「レガシー脳」

あんまり技術的なつっこみをすることではないけど。

例のシステムを作ってて、SQLのORDER BYで使うカラムの値にNULL値を許していたことに気がついた。今までそーゆー設計を避けて来てたんだけど、その方が論理的に正しければそう作るのがいいわけで。

この時、NULL値は最初に来るのが普通なのか、後に来るのが普通なのか。

PostgreSQLはNULL値がORDER BYのカラムにあった時は、「そのカラムの最高値」となるように処理するものがデフォルトなのだけど、逆であることが必要なことも少なくない。私のように

覚えきれないデフォルトは明記する

クセのある人もいると思う。たとえば、Cの演算子の順序とか、「ついうっかり」を避けるために括弧を明記したりする。まぁ、「2倍する代わりに左シフト」とかセコい高速化を手でやってた時代についてしまったクセではあるのだけど。

でまぁ、そんな習慣があるから「ORDER BYのカラムの値にNULL値を含むことがあったら、上に来るか下に来るか明記したい」と思ったわけだ。どうせ書いておいてもパーザの負荷がちょこっと増えるだけだ。

ぐぐると、そんなものの答えはいくつか出て来るし、PostgreSQLをキーワードに入れなければ、他のRDBMSでのやり方も出て来る。それは当然だ。

Oracleの場合、’NULLS (FIRST|LAST)’なる書き方があるようだ。まー、用ないけど。

PostgreSQLで探すと、いろいろ「器用なクエリ」が出て来る。気になる向きは「order by null」とかでぐぐってみるといい。「xx is null」をORDER BYの「NULLがあるかも知れないカラム」を指定する前に書けとか、「coalesce」を使う方法とか出て来る。検索結果の上位に来るのは、そんなQ/Aだったりする。

「今時のPostgreSQL」での正解は何かと言えば、おそらくはOracleと同じ’NULLS (FIRST|LAST)’をORDER BYで指定すること。手元では普通に動いたんで、「なんだ、あるじゃん」って思ったのだけど、どうも8.3以降の機能らしい。

なんつー話は、前フリ。気になったのは、この「器用なクエリ」が検索の上位に来てしまうことだ。

「検索の上位に来る」ってのは、いろんな事情やらテクニックやらのことをとりあえず忘れておけば、「それだけ信用することが出来て、ポピュラーである」という意味だ。「いや、現実そうじゃないし」って声はあるんだけど、少なくともそれを目指して検索アルゴリズムは改良されている。無茶なSEOをしなけりゃ、これは

だいたいあってる

ことだし、漠然とみんなそう思っている。「わかってる人」から見れば、「いや、そうじゃないし」って言えるのかも知れないが、普通は「わかってない」から調べるものなので、検索結果を鵜呑みにしてしまう人がいてもおかしくないし、鵜呑みにしないまでも検索結果の正当性と順序は関係があると思ってもおかしくない。だいたい、そうでなかったら結果の順序に意味ないし。

まー、そんなわけで何も知らなかったら、’NULLS (FIRST|LAST)’よりも、「器用なクエリ」の方が一般的で正しい方法だと誤解する人がいてもおかしくない。

‘NULLS (FIRST|LAST)’がPostgreSQLに入ったのは、どうも8.3かららしい。

PostgreSQL 8.3 に関する技術情報

「8.3」と聞いて、「なんだ最近じゃん。最近ならしょうがないよね」と一瞬思ったのだけど、リリースノートを見れば、2008年の初め頃のリリースだ。つい昨日のような気がしてたけど、結構前なのだ。だったら素直に’NULLS (FIRST|LAST)’を使えよと。ネットの情報もそう書き直されるべきだろうと。

ところが知らない人達は、検索結果として上位、あるいは多数派に見える「器用なクエリ」の方を使ってしまうだろう。

SQLのテストは面倒臭い。「正しく動く」ことも大事だけど、「パフォーマンス」も抜きには語れない。また、たいていはそれなりの規模のデータが相手だから、機能の実装の信頼性も大事だ。普通、昨日今日実装された機能なんてのは、使わないもんだ。ましてやFLOSS…

また、SQLのような「職人技」の世界だと、新しいものはなかなか入って行かない。つまりまぁ、「COBOLer化」だ。

COBOLは「負の遺産」なんかじゃない

だから言わんこっちゃない

で、こういった世界では「実績」とか「パフォーマンス」とかってことで、つい保守的であることを肯定してしまう。おそらく、「器用なクエリ」を使う人達や、それを継承して行く人達の何割かは、

古来から使われているものが、なんとなく安心

と思ってるんじゃないかとゆーフシがある。

まぁ、リリースされてすぐの機能は避けた方がいいことが多いし、SQLならパフォーマンスを意識した書き方は避けられない。とは言え、既に実装されて3年以上もたつ機能ではあるし、Oracleと互換性もある’NULLS (FIRST|LAST)’を避ける必要性はもはやない気がするし、いまだそれを使うのが普通だと思うのなら、それなりの説明がされてしかるべきだろう。

「常識」ってのは、適当なところで棚卸ししなきゃいけないんだよ。そうしないと、知識がレガシーになるだけじゃなくて、レガシーであることを肯定してしまう、「レガシー脳」になってしまう。