ワタシ、もともとネットワークエンジニアだったのですが、なぜか業務アプリを作ることになってしまいました。10年ちょっと前は、となりのERPチームは大変だなー、と思っていたんですが。
そして、なりゆきで始めたプログラマとしては最底辺におります。その最底辺の悩みを紹介します。
業務アプリの世界は、殺伐としています。ユーザー部署の要望が、ロジックエラーだらけで素直に実装するとエライことになるんです。ERP導入失敗はだいたい語り尽くされた感がありますが、親身なERPエンジニアが居るところほど失敗してしまうんじゃないかと思います。
もし、業務に対して「ここ違うんじゃないですか?」などと口答えをすると、ソロバンで計算してた時代の大先輩から「おまえ若造が何を言うかー」とげんこつが飛んできそうな雰囲気なのです。
そして、転職したらなぜかワタシがベトナム人と一緒に業務アプリを作ることに。そして、悩んだのはやっぱり泥臭い別のところでした。
レガシーシステムの自然キーと、いまどきフレームワークの人工キー
古いシステムは、だいたい自然キーを主キーに使っています。
具体的に言うと、0で始まったり、AとかLとかZとかの文字列型。教科書ではたぶんこんな感じだったんですね。銀行コードとかの例が分かりやすいでしょう。
統一金融機関コード
0005 三菱東京UFJ銀行
0009 三井住友銀行
固定長のデータ時代の名残なのでしょう。弊社のDBにも、そういう主キーのIDがありました。これをそのまま使い続けると、いまどきのフレームワーク(Rails)の良さが全く生きません。
いまどきのフレームワークは、人工キーで自動採番された整数型が主です。1から自動でインクリメントされていく感じです。100までいって、レコードをクリアすると1にはもどらず、1-100が欠番で101からスタートします。コレを見ると、自然キーで誤解できないように指定したほうがいいなと自分でも思います。
失敗した設計その1
Banksテーブル
id(pk) integer(ここには0005とか入らない)
name string
Peopleテーブル
id(pk) integer
name string
bank_id integer(ここには0005とか入らない)
ここで、Bank.idに0とかGとかで始まる文字列をぶち込むわけにはいかないのです。魔改造したらいきなり負の遺産になります。ためしに0005をぶち込んだら、みごとに000が綺麗に切り取られて”5"になりました。
どうやって折り合いをつけるか
伝統的な設計にもとづいてPKに自然キーを使うと、あとで非常にめんどくさいというか、Railsで使うのは無理です。
テーブル間のrelationshipを考えると、何らかの形で人工キーをつかったフレームワークのデフォルトに乗る必要があります。
Rails1.2.4時代に業務システムを最初に作った時はシステムIDとローカル設定のIDを分けてみました。
初心者なのでアホでした。もちろん、_idが予約語なので動きません。
失敗した設計その2(うごかない)
Banksテーブル
id(pk) integer
local_id string(ここには0005とか入る)
name string
Peopleテーブル
id(pk) integer
name string
bank_local_id string(ここには0005とか入る)
_idは規約でNGだよって覚えた結果、こんなふうにしました。 localidっていう接尾語、どう考えてもイケていません。あのころのワタシにはこれが限界でした。
失敗した設計その3(うごくけど、いけてない)
Banksテーブル
id(pk) integer
localid string(ここには0005とか入る)
name string
Peopleテーブル
id(pk) integer
name string
bank_localid string(ここには0005とか入る)
このダメダメなDBがずっと生き残ってるのがもう申し訳なくて、Salesforce化してくれたときは本当に嬉しかったです(すでに異動してましたが)
このシステムは野良ツールとして生をうけ、なぜか社内公式トレーニング対象になったのにだれも正式なエンジニアがアサインされずに5年くらい第一線で活躍しました。貢献をちゃんと評価してください。
自然キーはキーだと思わないほうがいい。
そしてGYAOにやってきて、あれから5年ぶりくらいに、予算を書く仕事から自分でコードを書く仕事になってしまいました。そして再度、この大して重要じゃないんだけれども、気になる問題にぶつかったのです。
そこで再度考えなおして、検索するときは自然キーで、自動でrelationshipやeager loadingするときは人工キーで行うのがちょうどいい落とし所だろうと思うようになりました。
英語が少しできるようになって、ようやくハラオチする解決策が
伝統的に、hogehogeIDと呼ばれていた番号体系の名前を、RailsのDB内部ではcodeという名前に変えてみました。
Banksテーブル
id(pk) integer
code string(ここには0005とか入る)
name string
Peopleテーブル
id(pk) integer
name string
bank_id integer(ここには12とか入る)
関連を組むと、People.bank.nameとかでRailsの仕組みを生かして銀行名が引けます。
銀行を探すときは、bank = Bank.where(code: “0005”)みたいな感じで検索すれば、昔ながらの番号体系で探しだすことができます。
エンジニアの最大の弱点は、英語でした。
さんざん悩んだオチは、「エンジニアは英語がダメ」ということでした。社内で使われてたIDは、Railsの世界で通用するIDではなかったのです。
じゃあ、どうしたらよかったかといえば、codeと読んでおけばよかったのです。そういえば銀行のコードは、「統一金融機関コード」といいました。
最初から、これがcodeだったら整数でも文字列でもなにを放り込んでも違和感ゼロです。これで、ようやくレガシーシステムを現代化する切り口が開けた気がします。
自分がコードを設計するときは、あとのエンジニアが悩まないように気楽にほげほげIDなんて名前は付けないことにします。結局、英語で生まれたコンピューター技術なので、英語で考えてればこんなアホな問題にハマることは無かったということでした。
結論:いけてるDB設計ができるように、みんな英語を勉強しよう