🦔

RDBで配列型の活用

2023/11/18に公開

開発しているプロダクトはBIのようなもの、データをあれこれ集計することが多く、いきおいエンティティ間の関連はテーブル設計でかならず現れます。

そのなかでも 1:n 関連や n:m 関連について、集約関係ではないものをオーソドックスにモデリングすると中間テーブルを作ることになると思いますが、いまの設計では配列型を活用することにしています。

たとえばユーザが商品を購入する、というモデルを普通に作るとこんな感じだと思います。一回の購入で複数の商品を購入できるとなると OrderDetail のような関連ができますよね。

一般論として「非定型データは使用すべきでない」といわれていることは知っていたので、最初に設計に入れるときはかなり悩んだものですが、やってみるとこれが実に自然な形に実装することができて、いまではすっかり抵抗なく選択肢として活用しています。上の例だとこんな風にテーブルを1つ減らせます。

いまのシステムでは PostgreSQL を使用していますが、配列型に対する演算子や手続きも豊富で、困ったことはありません。集計に BigQuery も使っていますが、こちらも配列型に対応しています。データの受け渡しに Parquet 形式ファイルを使っていますが、こういった近代的なデータフォーマットであればやはり配列型をサポートしています。つまり、少し前の「配列型は使うな」という格言を裏付けていた当時の事情は、いまでは過去になったものもありそうです。

もちろん、濫用すると破綻することは明らかで、ポイントはその関連が将来的に属性値をもちそうかどうかだと思います。実は上の例の購買の場合は、実際には取引ごとに割引額とか出てくるので配列にしないほうがよさそうです。要は、単なる n:m 関連の論理モデルを物理モデルにするために生じた仕方のないものなのか、その関連自体が意味のある情報として存在しているかで、もし意味のある関連なら配列型の使用は適切ではないと考えています。また別の観点で、配列型を対象にインデックスも使えるみたいですが、まあ厳しいチューニングが必要なときに複雑なことすると面倒なことになりそうだなと思います。


注意点はあるものの、テーブルの数が増えていくと徐々にシステムの見通しが悪くなるので、配列型も使いようかなと思っています。ちなみに別の非定型型である JSON 型は相当注意が必要で、モデリング不足を JSON で埋め合わせようにすると問題が悪化するというのは先日学習しました。

Discussion