失敗から学ぶRDBの歩き方 メモ
SQLアンチパターン メモ に続いて、同じくRDB運用のアンチパターンがまとまった『失敗から学ぶRDBの正しい歩き方』の内容を章ごとに軽ーくメモしておきます。
1章 データベースの迷宮
テーブルやカラムには意味のある名前を付けよう。
2章 失われた事実
履歴データを残しておく。パフォーマンスとのトレードオフなので、仕様上許容できるならログや遅延レプリケーションでも十分。
3章 やりすぎたJOIN
そもそも不要なJOINをしない、JOINの対象になる行を減らす。
4章 使えないINDEX
BTree Indexの構造を理解して、レコード数の推移を把握した上でINDEXを使おう。
5章 フラグの闇
DB側で状態を保つのは避けよう。
6章 ソートの依存
ORDER BYはWHEREで絞ってソート対象のレコードを減らしたり、ORDER BY狙いのIndexを使って効率よく使う。
7章 隠された状態
5章と大体同じ。idの値から状態を取れるみたいな、一つのデータが複数の意味を持たないような設計にすべき。
8章 JSONの甘い罠
正規化の余地がある場合や特定のKeyによる検索、参照整合性を保ちたい場合はJSONデータ型の使用は避ける。
9章 強過ぎる制約
正規化とUNIQUE制約、NOT NULL制約で十分なケースがほとんど。DB側の制約としてでなく、アプリ側の規約での対応も検討すべし。
10章 転んだ後のバックアップ
バックアップは実際にリストアできることを確認するところまでがバックアップ。常に誰でも作業できる状態にしよう。
RPO(Recovery Point Objective): いつ時点のデータを復旧できるか
RTO(Recovery Time Objectvie): 復旧にどれくらい時間がかかるか
RLO(Recovery Level Objective): 実際にどこまで復旧させるか
11章 見られないエラーログ
見るべきエラーログが発生した時点で確実に見れる、見やすい状態で記録されているかどうかか確認しよう。
12章 監視されないデータベース
こちらも監視を作って終わりではなく、定期的に振り返って改善を進めていくのが大事。リリース状況と重ねて考えられるので、アプリ開発者と一緒にやるべき。
13章 知らないロック
ロックはレベル(排他、共有)と粒度(表、行)の組み合わせ。MySQLではギャップロックとネクストキーロックの挙動を手を動かして理解することが大切。
14章 ロックの功罪
ロックを理解するにはトランザクション分離レベルを理解する必要がある。並列度を高めつつ一貫性を保つためのロックを適切に使おう。
15章 簡単すぎる不整合
非正規化はデメリットが大き過ぎるので良くない。
16章 キャッシュ中毒
レスポンスタイムを改善したくなるまでは、過剰にキャッシュしすぎない。
17章 複雑なクエリ
1つのデカい複雑なクエリではなく、責務を分けたいくつかのクエリに分けるほうがいい。それでもクエリが書きにくい時はテーブル設計がよくない。
クエリを読む時は構文評価の順に読むといい。
FROM
ON
JOIN
WHERE
GROUP BY
HAVING
SELECT
DISTINCT
ORDER BY
TOP(LIMIT)
18章 ノーチェンジ・コンフィグ
configはコード管理して、チューニングを行いやすいようにしよう。
19章 塩漬けのバージョン
DBのバージョンアップに割く工数をケチるよりも、バージョンに追従していくメリットが絶対的に大きい。ビジネスサイドに訴求するために、小さな実績を積み重ねていくことが大切。
20章 フレームワーク依存症
アクティブレコード、DAOとドメインロジックを分けて実装する、疎結合にすることで保守性の高いコードになる。
フレームワークは初速が出る一方、あとからリファクタリングする計画を立てておくのが大切。