読者です 読者をやめる 読者になる 読者になる

mysql テーブル設計 カンマ区切りのカラムについて考察

例えば商品の属性とかレコードに紐づくデータが沢山あってレコード毎にデータ作ると色々面倒なケース。

DB設計の基本について 例えば一つのレコードが複数のカテゴリに… - 人力検索はてな
MySQLでカンマ区切りの値を登録してみる | シスデイズ技術ブログ
まさにこういうケース。基本はやはり忠実に正規化するのがベターらしいが、場合によってはカンマ区切りにするのもあり。ただカンマ区切りにしてしまうとjoinが面倒になるぽい。柔軟なのはやはり正しく正規化する方なんだと思う。

正規化した場合の問題について
まず正規化した場合、上の例でいうとAカテゴリとBカテゴリに属するレコードを取得する(AのみBのみは除く)となった場合、一番シンプルなのがgroup_concatでカンマ区切りにした結果に対してfind_in_setで絞り込む方法では無いかと思う。

しかし他のテーブルと結合したいと(group_concatでgroup byしてさらにの他のテーブルのカラムでgroup byしたい場合等)なった場合、いったんgroup_concatして、その結果を副問合せとかで結合、という手順を踏まないといけなくなるため、最初からカンマ区切りのデータであればその辺がシンプルになるはず。

データが膨大な場合は、「いったんgroup_concatして」すら出来なくなると思うので、最初からカンマ区切りならそのまま別テーブルと結合して、別テーブルの条件で絞り込んだデータに対してfind_in_setをすれば良い訳だから、データ量によってはパフォーマンスが圧倒的に変わると思う。

とはいえjoinが出来ない(面倒な)のも痛いしな~、両方用意して使い分けるのもありかもしれんけどな。片方更新したらもう片方も更新しないといけないから、その辺は覚悟せなあかんくなる。

全ての要件を満たす方法が無いとなると、後は何を優先させるかだな。パフォーマンスなのか開発工数なのか保守性なのか。ただ絶対に守らないといけないことが1つあって、それは「シンプルである」ということ。これだけは絶対に外してはいけない。

よく考えた結果、テーブル結合が発生する場合は副問合せはどうしても必要になるけど、サブクエリにするタイミングをずらすことで正規化でもパフォーマンス落とさずにできるかも。もうちょっと検証してみる。

結論
自分のSQLがダメだっただけで、やっぱり正規化でパフォーマンス落とさずに対応することができた。なので正規化のデメリットはデータ数が増えることくらいではないかな。でもそれはシステム化すれば大した問題ではない。なのでカンマ区切りにはやっぱりしないこと。

資産形成におすすめのFX口座はこちら。
http://s2fx.com/ranking/856.html