SQLアンチパターン 第5章を読んで

SQLアンチパターンwww.oreilly.co.jp

を読んでの要約、感想です。

目的

同じ属性を持ちつつも、例えばSmartphoneというオブジェクトがあるとして方やandroid_version、方やios_versionを持っている場合に対応したいというのが今回の目的です。

アンチパターン

別テーブルをつくり属性を行に格納してしまうというものです

smartphone_idos_versionos_version_value(VARCHAR)
1android_versionoreo
2ios_version12
3blackberry_version7.1

いちいちSmartphonesテーブルに列を増やさなてくてもいいですし、急なOSの登場にも耐えられます。

デメリット

  1. 対象の行を指定してから取り出すして使う必要がある。(これは織り込み済みのデメリットの気もしますが)
  2. 行に属性がはいるのでデータ型なんかは整合性はとれず文字列をいれるしかありません。もしくはデータ型に対応するカラムをたくさん用意するかです。
  3. 行として属性をもっているので内部結合しようと持っていない属性を指定してしまうと結合できず、何も取り出せないので外部結合するしかありません。必然的に扱う行の数は多くなります。

使用してもいい場

SQL以外の非リレーショナルな技術をつかう時とあります。確かに。

解決策

  • シングルテーブル継承

サブタイプの数が限られていれば

smartphone_idnameosandroid_versionios_version
1iphone6iosoreonull
2honor9androidnull12

ActiveRecordを使うような単純な設計の時◯です。

  • 具象テーブル継承

変化する属性ごとにテーブルをつくります。

smartphone_idnameosios_version
1iphone6ios12
smartphone_idnameosandroid_version
2honor9androidoreo

nullがなくなります

  • クラステーブル継承
smartphone_idios_version
112
smartphone_idandroid_version
2oreo

共通要素を元テーブルで持ち、違う要素をそれぞれ別のテーブルに切り出すというものです。その名の通りクラス継承と同じ形です。

  • 半構造化データ
smartphone_idnameosversion_attributes
1iphone6iosandroid_version: oreo
2honor9androidios_version: 12

LOB列を作りそこにJSON等の形式で格納してしまおうというものです。SQLでアクセスできなくなるので流石に無理がある気がします。

感想

メタデータを格納させると大変だよという章だと思いました。現実的にはシングルテーブル継承が一番使いやすいかなと思います。