📖

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

2021/11/12に公開

「SQL アンチパターン」を読んだので、そこから気づいた学びなどを備忘録として簡単にまとめます。

https://www.oreilly.co.jp/books/9784873115894

読んだきっかけ

業務で雰囲気で SQL を書いたりテーブル設計をしていたので、ちゃんと学んでみようと思って読んでみました。

気づき・学び

特に印象に残った章について記載します。

1 章 ジェイウォーク(信号無視)

「カンマ区切りフォーマットのリストを格納する」やつです。
最近業務でやりかけたやつだったので、やらなくてよかった。。という気持ちになりました。。

2 章 ナイーブツリー(素朴な木)

ここで解決策として紹介されている「閉包テーブル」は、業務で扱っているプロダクトのテーブル設計に使われているけど、あまりよく理解していなかったので勉強になりました。

3 章 ID リクワイアド(とりあえず ID)

自分も ID はとりあえず用意していました。。
複数テーブルを紐付ける交差テーブルにまで ID はいらないのは確かになあと納得しました。

5 章 EAV(エンティティ・アトリビュート・バリュー)

「何を格納するか」は列として表現するのが普通ですが、柔軟性をもたせるためにあえて行で表現しちゃうアンチパターンです。
ここに出てくる解決策も業務で扱っているプロダクトのテーブルに出てくるので、勉強になりました。

9 章 ラウンディングエラー(丸め誤差)

SQL というよりはコンピューターサイエンスの話なのかなという感じがしました。
小数値を扱う場合は FLOAT ではなく NUMERIC を使うのが推奨されていました。

11 章 ファントムファイル(幻のファイル)

DB には参照先パスを格納しておき、ファイルはオブジェクトストレージに保存するのが定石だと思っていたのですが、そうするとトランザクション管理などが難しくなるのは確かにと納得しました。
BLOB 型などを使えば DB にファイルも格納できます。

12 章 インデックスショットガン(闇雲インデックス)

インデックスは必要なところに適切に使いましょう。
そのための指針として、MENTOR の原則というのがあります。

16 章 プアマンズ・サーチエンジン(貧者のサーチエンジン)

全文検索したいときは、それに適した技術を使いましょう。安易にLIKEを使うとデータ量が大きくなった時に性能が劣化します。
解決策として、DB に付属している、あるいは DB 以外の全文検索エンジンを使いましょう。MySQL のフルテキストインデックスや、ElasticSearch などです。

17 章 スパゲッティクエリ

業務で扱っているプロダクトの SQL で 1000 行超えのやつがあって、(HiveQL だということもあって)まあ何か事情があってこうなっているんだろうとは思っていましたが、とはいえやはりよくないよなあと再認識させられました。
少しの修正で予期せぬ影響出たりマジでメンテが大変なので、分割したい。。。

18 章 インプリシットカラム(暗黙の列)

SELECT * (ワイルドカード)はやめましょう。
もちろん、ちょっとした調査とかに使うアドホックな SQL だったらよいですが、本番稼働するアプリケーションで使うのは安全性の観点からやめましょう。

19 章 リーダブルパスワード(読み取り可能パスワード)

平文でパスワードを保存するのは絶対にやめましょう。
SQL に限った話ではない気がします。

20 章 SQL インジェクション

Prepared statement 使いましょうというアレです。
「ただしそれだけで全部解決できるわけではないので、ちゃんとレビューもしましょう」と書かれていたのは当たり前だけど印象的でした。

あとは、アプリケーションコードを書くときは素で SQL を扱うのではなく、信頼できるライブラリを使うのも大切な気がします。

21 章 シュードキー・ニートフリーク(疑似キー潔癖症)

レコードの削除などで id に欠番ができたとしても、そこに別のレコードを追加するのはやめましょう。
たとえば、削除したはずのユーザーがまだ存在しちゃっているみたいなことになりかねません。

23 章 ディプロマティック・イミュニティ(外交特権)

SQL だからといってバージョン管理しないでいいとか、そんなことは決してないです。
アプリケーションコードと同等に扱いましょう。

25 章 砂の城

サービスを安定稼働させるには、あらゆることを事前に想定して対策したり、何かあってもすぐに対策してそれを検証できるテスト環境を用意しておきましょう。
SQL に限った話ではない気がしますが、特に大規模データを扱うような場合は性能面でのテストをできる環境をあらかじめ用意しておくのは大切な気がしました。

Discussion