Open9

Goで数万行のJSONと渡り合う方法を調べる

Kaikei EzakiKaikei Ezaki

目的

  • DB自体のリファクタリングも含めて、並行して検討すべきだが、まずはGoで巨大なJSONをどのように扱っていくのが良いか。
  • そして、それらと渡り合って単体テストのカバレッジを向上させる方法を調査するのが本スクラップの目的とする。

前提

  • かなり前からの既存プロダクトとそのDBが、巨大なJSONを1フィールドに保存して操作している。
  • そこへGoを導入しリプレースを行なっているが、自身のスキル不足もあり、構造体にバインド、その巨大な構造体をリレーするような関数を多数実装してしまった。
  • これではモックを作成したり、単体テストが実装できない。
  • この講演資料を読んで、単体テストやリファクタリングが急務だと気がついた。
Kaikei EzakiKaikei Ezaki

MySQLのJSON_EXTRACT機能を使えば、要素に簡単にアクセスできるかもしれない。
そこでデータを絞って、最小限の構造体へのバインドをすることで、前述のモックすら書けない現状を打破できるかもしれない。

https://hit.hateblo.jp/entry/MYSQL/8.0/JSON

Kaikei EzakiKaikei Ezaki

MySQL 5.7.9以降のJSON関連機能を利用すれば、既存の数万行ものJSONを簡単に分割できることがわかった。知らなかった…
残りはMySQL側の負荷の問題で、おそらく問題なさそうだが要検証。

Kaikei EzakiKaikei Ezaki

実行計画をみる限り、コストも大したことなさそう。
でも↑の記事などでもあるように、まずは正規化せよ、とのことらしい。

Kaikei EzakiKaikei Ezaki

現時点での結論(今後改善して変わるかも)

  • まずDBのテーブルを第3正規化まで実行する。
    • その過程で正規化すると厄介なものに関してはJSONのまま残す。
  • それが難しいなら、JSON_EXTRACT()などの関数で、巨大なJSONを分割して取得すべき。
    • そうすれば構造体の複雑さが減ってテストがしやすくなるはず。
    • リファクタリングをしていたらユニットテストの前に他の箇所の改修が入り、ユニットテストをかけていない。