見る人によって結果の変わる不思議なビューで、周りを驚かせちゃおう


こんにちは、三苫です。

時々、複雑なシステムをリリースするとき新旧両方のシステムを同時に稼働し続けないといけないという状況に陥ること、ありますよね。

さらに、そのシステムは設定マスタみたいなテーブルがあって、システムはその設定値を読んで稼働するという事も、ありますよね。

さらにさらに、新しいシステムと古いシステムで、同じ設定マスタの同じレコードを読まなければいけないんだけど新しいシステムと古いシステムで別の値じゃないと動かない・・・なんてこともありますよね。

さらにさらにさらに、そういう場合たいていは新しいシステムのほうはプログラムを改修してその問題を回避できるようにするのが筋なんだけど、該当箇所の修正をするとシステムの再テスト工数が膨大になり現実的ではないというケースも泣きたいほど多いですよね。

※実際にはそんなに多くないと思います。

要件

  • 新システムと旧システムで同じクエリを発行し、同じレコードを見なければならない。
  • ただし、旧システムでは「X」という値を受け取り、新システムでは「Y」という値を受け取れなければならない。
  • 接続ユーザ名は変えることはできない。
  • 新システムと旧システムでサーバーのIPは異なる。
  • システムの RDBMS は PostgreSQL とする。

つまり、簡単に言うとこういう事。

何を言っているのか

期待する動き

できるかな~。

実現方法

まずもともとの設定テーブルの初期状態を以下とします。

物理テーブルのままでは要件を満たすことはできませんので、VIEWにしないといけないことはすぐに思いつきます。けれど、VIEWにしたところで接続元を条件に加えることができないと結果を出しわけることができません。

しかしPostgreSQLは話の分かるやつです。 inet_client_addr() を使うことでリモート接続のアドレスを取得することができるのでこれを条件に使えそうです。
https://www.postgresql.jp/document/9.4/html/functions-info.html

大体こんな風にしたらいけるんじゃないかな?UNION ALL のところがポイントですね。

これで接続元によって結果が変わるという何とも不思議なビューが完成しました。

テストしてみましょう。

すごい!接続元のサーバーによって結果が変わってますね!
これでプログラムを改修せずにリリースできる!

実現はできたけど

と、ここまで実現方法を考えたのはいいのですが「お、おかしい!このテーブル接続するサーバーによってSELECT結果が変わる!?タスケテ!!」みたいなはまり方をする同僚の姿しか思い浮かばなかったこともあり、この方式を採用するのは(私の社内の評判的に)リスクが大きかったため断念しました。

みんなが思いつかなかったトリッキーな技で物事を解決するのはいつだって楽しいことです。ただし、その驚きがチームの混乱、怒りに変わらないかどうかを見極めることも大切です。

私は「PostgreSQL、やっぱりスゲーぜ」というはてブが一つでもつけば、それだけで満足です。むしろそれだけが今回の記事の勝利条件です。

※MySQLでも user() が user@hostname を返すので同じことを実現できると思います。

以上、新旧システム混在方法検討会の現場からお送りしました。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です