ishikawa_pro's memorandum

若手webエンジニアの備忘録です.

Swift Node.js Docker AWS etc...色々やります。

MySQL5.7のJSON型について調べた

こんにちは。
今日はMySQLJSON型を使う機会があったので、勉強したメモです。
基本的には、ドキュメントの内容を引っ張ってきて書いてます。
英語苦手なので解釈間違ってるかも。

dev.mysql.com

調べた経緯

業務で新しい機能を作っていて、テーブル定義のレビューの際に、それJSON型でいいんじゃないかと言われたのがキッカケです。
JSON型が使えるのは知っていましたが、実際に業務で使えるものなのか、どういう時に使えばいいかなどを全然知らなかったので、ちょっと勉強してみました。
今回は、とりあえずJSON型とは、について調べました。
ちょっと長くなりそうだから実際に使うのは次の記事で。

JSON

  • 効率的にJSONドキュメントにアクセスできる。
    • String型のカラムにJSONフォーマットの文字列を入れるよりも効率的。
    • JSON formatになっているかvalidationされる
  • JSONカラムに格納されたJSONドキュメントは、ドキュメントの要素に高速な読み取りアクセス可能な内部フォーマットに変換される
  • 格納するのにLONG BLOBかLONG TEXTとほぼ同じスペースが必要
    • 格納できるサイズはmax_allowed_packet で指定されたサイズに制限される
  • NULL以外のデフォルト値を含めることはできない
  • create, operation, searchなどのJSON値の操作は、関数を利用できる

特徴

JSONカラムの値を読み出す時、ドキュメント内の前後の値を全て読み込まなくても、サブオブジェクトやネストされた値に、キーまたは配列インデックスで直接アクセスできるように構造化されているため、テキスト表現からパースする必要がなく効率よく取り出せる。

indexについて

  • 他のバイナリ型同様にindexは貼れない。
    • JSONカラムの値からgenerated columnsを作って、そこにindexを貼ることで対応できる。

使い道

JSON型はNoSQLっぽく使えそうだから乱用しそうになりますが、generated columnsにしかindexが貼れないので適当なJSONを入れまくって雑に使うようなことは避けたほうが良さそう。多分そういう時は、ドキュメント指向DBとかが良いと思う。(ドキュメント指向DBが雑に使っていいという訳ではないです。)

今回は、今後カラムが増える可能性がある(増えない可能性もある)が、その度にalter tableをしたくないからテーブル設計をどうするか、というのが主題でした。
最初は、色々話をしてクラステーブル継承を使って解決しようとしていましたが、属性が増えて結合するテーブルの数が増えると辛くなるよ、と言われて半構造化データとしてJSON型を使うことにしました。

その他JSON型を選定した理由として、

  • サーバーサイドがnode.jsでJSONとの相性が良い
  • sequlize(ORM)がJSON型に対応している
  • 格納するデータが不揃い
  • generated columnsに貼ったindex以外で検索することがない

などです。
JSON型を使ったことがなかったので、RDBJSONという正規化されてないデータをそのままぶち込むようなことをしてもいいのかという、疑問と不安でよく調べもせずに選択肢から外してたので今回はとても勉強になりました。

次回は、実際に使う感じの記事を書こうと思います。