mof-brown

ずっとモフモフしてたい

「SQLアンチパターン」を読んだ

今更ながら、会社にあった「SQLアンチパターン」を読んだ。

SQLアンチパターン

SQLアンチパターン

いくつかドキッとするようなアンチパターンが合って勉強になったが、
中には、そもそもその設計だと実現できないからやらない、っていうパターンもちらほらある。
アプリケーション開発の章は常識的な内容なので、本書を手にとった方・気になっている方には退屈だと思う。

データベース論理設計のアンチパターン

カンマ区切りフォーマットのリストを格納した列を定義する

データの整合性の担保ができない、インデックス検索できないなどの問題がある。
非正規化の一例ではあるので、よく検討した上で採用するのであればOK。

階層構造

単一階層を持たないのであれば、「常に親に依存する」形でもOK。
複数階層を表す場合は、「経路列挙」か「閉包テーブル」を採用する。
(経路列挙の方が実装は楽)

全てのテーブルに ID 列を用いる

ORM の都合で用意する必要があったりもするケースバイケースで。
ActiveRecord では primary_key の設定が可能。

外部キー制約を使用しない

DB 分割を考慮した場合でも、制約を使用した方が良いのであれば使用する。

汎用的な属性テーブルを使用する

システムのメタ情報とかに使う分には問題ないと思う。

二重目的の外部キーを使用する

普段からやらない。

複数の列を定義する

tag1tag2tag3 みたいな列定義について。
普段からやらない。

テーブルや列をコピーする

t_sales_2015t_sales_2016 みたいな運用について。
普段からやらない。

データベース物理設計のアンチパターン

FLOAT データ型を使用する

丸め誤差が発生する可能性があるので、NUMERIC/DECIMAL 型を使うこと。

限定する値を列定義で指定する

ミドルウェアが確定しているなら、別に ENUM 使っても良いと思う。

物理ファイルの使用を必須と思い込む

普段からやらない。
容量の問題が無ければ、基本は BLOB 型で DB に格納する方向にしている。

闇雲にインデックスを使用する

普段からやらない。

NULL を一般値として使う

可能であれば NOT NULL 制約か DEFAULT を定義するようにしている。

非グループ可列を参照する

SELECT id, max(xxx) ... GROUP BY で取得した各行に対して、xxx 以外の列を取得する方法について。
普段からやらない。

データをランダムにソートする

RANDOM 関数を使ったランダム処理について
普段からやらない。アプリ側で処理する。

パターンマッチ術後を使用する

like 検索について。
データ件数を考慮して、問題ないのであれば使ってもOKでは。

複雑な問題をワンステップで解決しようとする

複雑な SQL で一発で情報を取得する事について。
普段からやらない。1個ずつ投げた方が早い。

ショートカットの罠に陥る

SQL 構文の省略による弊害について。
ORM 使うことが多いので、特に問題とはならない。
直接 SQL 書くときは注意する。

アプリケーション開発のアンチパターン

パスワードを平文で格納する

普段からやらない。

未検証の入力をコードとして実行する

SQL インジェクションの話。 パラメータを使って SQL を組み立てることはNG。

隙間を埋める

ID 列が連番になっていない時に、空いたIDを再利用するなど。 普段からやらない。

肝心な部分を見逃す

ただのクソコード。

SQL を特別扱いする

DB 側も、アプリケーションコードのようにバージョニングしたりテストしたりしましょうという話。 最近は ER図やマイグレーションスクリプトを管理している。

モデルがアクティブレコードそのもの

まさに今一番悩んでいるところ。 ファットモデルを避けるために、DDD を採用して サービス層を作るのが良いと思ってる。

想定不足

ベンチマークを取る、テスト環境を作る、例外を考慮して実装する、バックアップは万全にしておく、マシン自体が死ぬことを想定しておく。