Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
SQLアンチパターン読書会4章:キーレスエントリ(外部キー嫌い)2013/6/13(木)@makopi23
24.1 目的: DBのアーキテクチャを単純化する外部キーを使用しない主な理由1. データの更新が、参照整合性制約と衝突する。2.DB設計の柔軟性が極めて高いので、参照整合性制約をサポートできない3. データベースが外部キーのために作成するイ...
34.2 アンチパターン:外部キー制約を使用しない 外部キー制約を使用しないと➢データベース設計がシンプルになる...?➢ 柔軟性が高まる...?➢ 実行速度が早くなる...? 代償(トレードオフ)➢開発者が、参照整合性を保証するためのコー...
44.2.1 完璧なコードを前提にしている (1/2)● 参照整合性を保証するための解決策➢データの関連付けを常に維持するためのコードを書く。➢ 変更を適用する前に追加のSELECTクエリを実行し、変更によって参照が壊れないことを確認する。✔ ...
54.2.1 完璧なコードを前提にしている (2/2)● この解決策の欠点➢ 確認クエリを実行した直後に、別の場所で誰かにDBを更新された場合に不具合が生じる可能性が出る。➢「確認+更新」の間、テーブルロックをかければ上記の問題は解決するが、性...
64.2.2 ミスを調べなければならない● 間違った解決策➢壊れた参照をチェックするスクリプトを書く●なぜダメなのか➢ すべての参照に対してスクリプトが必要となる➢数百ものチェックを毎日、何回も実行しなくてはならない➢壊れた参照を検出したとして...
74.2.3 「私のミスではありません!」● データベースに関するすべてのコードが完璧であることは、まずありえない。➢ すべての更新ロジックに対し、参照整合性を担保するための対処を施したか確認するのは、簡単ではない。(複数のアプリが同一のDBに...
84.2.4 「キャッチ=22」なUPDATE● 子の行が依存する列をUPDATEする際のジレンマ➢親の行を更新するまで、子の行の更新はできない➢ 親の更新も、参照する子の値を更新する前に実行できない● 親と子を両方同時に変更する必要があるが、...
94.3 アンチパターンの見つけ方 次のような言葉を耳にしたらアンチパターンの兆候があることを示している。➢ あるテーブルには存在するけど、もう1つのテーブルには存在しない値を調べるクエリは、どう書けばいい?➢ あるテーブルの値が、別のテーブ...
104.4 アンチパターンを用いても良い場合● 外部キーをサポートしていないデータベース製品を使わざるを得ない場合➢ MySQLのMyISAMストレージエンジン➢ バージョン3.6.19未満のSQLite● 外部キーを用いた関連付けを行えない、...
114.5 解決策:外部キー制約を宣言する 参照整合性の強制の利点➢データの不整合を検出してから修正するのではなく、DBへの登録時点でミスを阻止できる。➢既存のコードも、その場限りのクエリも、同じ外部キーに従うようになる。➢ うっかり見逃して...
124.5.1 複数テーブルの変更をサポートするカスケード更新CREATE TABLE Bugs (-- 他の列. . .reported_by BIGINT UNSIGNED NOT NULL,status VARCHAR(20) NOT N...
134.5.2 オーバーヘッド、…にはなりません●外部キー制約によって、多少のオーバーヘッドが生じるのは事実。●しかし、以下に挙げるように、ほかの選択肢と比べると、外部キーの方がより効果的➢ 挿入、更新、削除の際に、チェックのためにSELECT...
14まとめ● 外部キーは簡単に使え、パフォーマンスも改善する。● 単純か複雑化に問わず、あらゆるデータの変更における参照整合性の維持に役立つ。データベースでのミスの発生を未然にデータベースでのミスの発生を未然に防ぐために、外部キー制約を用いまし...
15参考図書 書籍「データベースリファクタリング」第8章:参照整合性リファクタリング➢外部キー制約の追加➢計算カラムへのトリガーの追加➢外部キー制約の削除➢カスケード削除の導入➢ハードデリートの導入➢ソフトデリートの導入➢履歴のためのトリガー...
16データベースリファクタリング:第8章遅延制約チェック制約の妥当性のチェックは、トランザクション終了時まで遅延できる。– 遅延制約:制約が満たされているかどうかのチェックがコミット時にしか実行されない。遅延制約違反があると、コミット時にその...
Upcoming SlideShare
Loading in …5
×

SQLアンチパターン読書会 4章 キーレスエンエントリ(外部キー嫌い)

7,354 views

Published on

2013/6/13(木)
SQLアンチパターン読書会のアジェンダ資料です。

Published in: Technology
  • Be the first to comment

SQLアンチパターン読書会 4章 キーレスエンエントリ(外部キー嫌い)

  1. 1. SQLアンチパターン読書会4章:キーレスエントリ(外部キー嫌い)2013/6/13(木)@makopi23
  2. 2. 24.1 目的: DBのアーキテクチャを単純化する外部キーを使用しない主な理由1. データの更新が、参照整合性制約と衝突する。2.DB設計の柔軟性が極めて高いので、参照整合性制約をサポートできない3. データベースが外部キーのために作成するインデックスが、パフォーマンスに影響すると考えている。4. 外部キーをサポートしないデータベース製品を使っている5. 外部キーを宣言する構文を調べなくてはならない。
  3. 3. 34.2 アンチパターン:外部キー制約を使用しない 外部キー制約を使用しないと➢データベース設計がシンプルになる...?➢ 柔軟性が高まる...?➢ 実行速度が早くなる...? 代償(トレードオフ)➢開発者が、参照整合性を保証するためのコードを書く責任が生じる。
  4. 4. 44.2.1 完璧なコードを前提にしている (1/2)● 参照整合性を保証するための解決策➢データの関連付けを常に維持するためのコードを書く。➢ 変更を適用する前に追加のSELECTクエリを実行し、変更によって参照が壊れないことを確認する。✔ 例1:行を挿入する前に、親の行が存在することを確認する。✔例2:行を削除する前に、子の行が存在しないことを確認する。
  5. 5. 54.2.1 完璧なコードを前提にしている (2/2)● この解決策の欠点➢ 確認クエリを実行した直後に、別の場所で誰かにDBを更新された場合に不具合が生じる可能性が出る。➢「確認+更新」の間、テーブルロックをかければ上記の問題は解決するが、性能問題など別の問題に直面する。
  6. 6. 64.2.2 ミスを調べなければならない● 間違った解決策➢壊れた参照をチェックするスクリプトを書く●なぜダメなのか➢ すべての参照に対してスクリプトが必要となる➢数百ものチェックを毎日、何回も実行しなくてはならない➢壊れた参照を検出したとしても、修正できるとは限らない
  7. 7. 74.2.3 「私のミスではありません!」● データベースに関するすべてのコードが完璧であることは、まずありえない。➢ すべての更新ロジックに対し、参照整合性を担保するための対処を施したか確認するのは、簡単ではない。(複数のアプリが同一のDBにアクセスすることもある)➢ あるユーザが、SQL実行ツールや自ら書いたスクリプトによって直接DBを変更し、参照を壊してしまう可能性がある。DBDBにアクセスするすべてのアプリとスクリプトがにアクセスするすべてのアプリとスクリプトが正しく変更を行ったかどうかは、信頼できない!正しく変更を行ったかどうかは、信頼できない!
  8. 8. 84.2.4 「キャッチ=22」なUPDATE● 子の行が依存する列をUPDATEする際のジレンマ➢親の行を更新するまで、子の行の更新はできない➢ 親の更新も、参照する子の値を更新する前に実行できない● 親と子を両方同時に変更する必要があるが、2つの異なる更新処理を同時に実行することは不可能
  9. 9. 94.3 アンチパターンの見つけ方 次のような言葉を耳にしたらアンチパターンの兆候があることを示している。➢ あるテーブルには存在するけど、もう1つのテーブルには存在しない値を調べるクエリは、どう書けばいい?➢ あるテーブルの値が、別のテーブルへの挿入に使われていることを簡単にチェックする方法はある?➢外部キー?データベースの実行速度を遅くするから、使ってはならないと教わったのだけど。
  10. 10. 104.4 アンチパターンを用いても良い場合● 外部キーをサポートしていないデータベース製品を使わざるを得ない場合➢ MySQLのMyISAMストレージエンジン➢ バージョン3.6.19未満のSQLite● 外部キーを用いた関連付けを行えない、極端に柔軟なデータベース設計を扱わなければならない場合
  11. 11. 114.5 解決策:外部キー制約を宣言する 参照整合性の強制の利点➢データの不整合を検出してから修正するのではなく、DBへの登録時点でミスを阻止できる。➢既存のコードも、その場限りのクエリも、同じ外部キーに従うようになる。➢ うっかり見逃していたコードが、この制約の強制を逃れることがなくなる。➢不要なコードを書く手間を省く。➢ DBを変更した場合でも、すべてのコードが同じように適切に動作することを保証する。➢ コードの作成だけでなく、修正や保守の時間も大幅に削減してくれる。
  12. 12. 124.5.1 複数テーブルの変更をサポートするカスケード更新CREATE TABLE Bugs (-- 他の列. . .reported_by BIGINT UNSIGNED NOT NULL,status VARCHAR(20) NOT NULL DEFAULT NEW,FOREIGN KEY (reported_by) REFERENCES Accounts(account_id)ON UPDATE CASCADEON UPDATE CASCADEON DELETE RESTRICT,ON DELETE RESTRICT,FOREIGN KEY (status) REFERENCES BugStatus(status)ON UPDATE CASCADEON DELETE SET DEFAULTON DELETE SET DEFAULT);
  13. 13. 134.5.2 オーバーヘッド、…にはなりません●外部キー制約によって、多少のオーバーヘッドが生じるのは事実。●しかし、以下に挙げるように、ほかの選択肢と比べると、外部キーの方がより効果的➢ 挿入、更新、削除の際に、チェックのためにSELECTクエリを実行する必要がない。➢複数テーブルの変更を防ぐために、テーブルをロックする必要がない。➢他の方法のように孤児が生じてしまうことがないので、データ品質管理用スクリプトを定期的に実行する必要がない。
  14. 14. 14まとめ● 外部キーは簡単に使え、パフォーマンスも改善する。● 単純か複雑化に問わず、あらゆるデータの変更における参照整合性の維持に役立つ。データベースでのミスの発生を未然にデータベースでのミスの発生を未然に防ぐために、外部キー制約を用いましょう。防ぐために、外部キー制約を用いましょう。
  15. 15. 15参考図書 書籍「データベースリファクタリング」第8章:参照整合性リファクタリング➢外部キー制約の追加➢計算カラムへのトリガーの追加➢外部キー制約の削除➢カスケード削除の導入➢ハードデリートの導入➢ソフトデリートの導入➢履歴のためのトリガーの導入
  16. 16. 16データベースリファクタリング:第8章遅延制約チェック制約の妥当性のチェックは、トランザクション終了時まで遅延できる。– 遅延制約:制約が満たされているかどうかのチェックがコミット時にしか実行されない。遅延制約違反があると、コミット時にそのトランザクションは取り消される。– 即時制約:チェックはそれぞれの文が終わった時点で実行される。制約違反があると、その文は即時にロールバックされる。Oracle 11g:http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05765-03/data_int.htm#66501

×