DoorKeeper
http://sqlap.doorkeeper.jp/events/4356
以下の書籍をターゲットとした読書会なのです。
![]() | SQLアンチパターン (2013/01/26) Bill Karwin 商品詳細を見る |
場所は御徒町(湯島)の株式会社アルティネットさんです。
参加者は8人かな。
『SQL アンチパターン』読書会、本日は「四章 キーレスエントリ」を読んでいます。この章は大阪のイベントで最も盛り上がったアンチパターンです #sqlap
— Takuto Wada (@t_wada) June 13, 2013
和田さん、今回も参加で頼もしい限りです。
ちなみに今回のアジェンダ当番は私でした。なので、簡単なスライドを事前に作成し、当日簡単に説明しましたー
以下、個人メモ。
■遅延制約チェック(スライドP.16)
・全部を参照整合チェックでやろうというのは性能上悪くなる危険性がある。
・それを防ぐために、遅延制約を使うことでコミット時まで制約チェックを遅らせる判断はありえる。
・ただ、やりすぎは危険。
・遅延制約は「ANSI SQL-92規格」で入ってきている。
■実際のプロジェクト現場における外部キー制約
・外部キー制約を付けたプロジェクトを見たことがあるか?という参加者への質問に対し、約半数が「No」。。。
・外部キー制約を付けない1理由:「既存システムが参照制約を張ってないいから、張らないまま今まで来た」
■外部キー制約を付ける/付けないの判断
・外部キー制約を使用しない理由は無い。ツッコミどころが無い。
・パフォーマンスの制約がでるまで、外部キー制約を使わないのはもったいない。
・ハイトランザクションになったら、参照性よりパフォーマンスが大事、ということもありえる。
→ その時になってはじめて外部キー制約を外す、という判断を下すのが良い。
■既存DBへの外部キー制約の追加
・まずデータクレンジングをしましょう。
・DBに同じデータが2行あるなら、片方が重複ミスのはず。それは人間しか判断できない。
・そういう重複データを消してからでないと、外部キー制約は追加できない。
・そういう手作業をやりたくないから、外部キー制約を使うのである。
・舌打ちしながらデータ直した経験がある人なら外部キー制約は追加すべき。
■外部キーを付けない理由
(1) 親データが無くなるかもしれない
→ でもそれは、モデリングとして「親がいなくてはいけない」としたのがそもそも強すぎる。
(2) テストデータ入れるのがめんどくさい
・これが一番多いかもしれない
(3) 業務フロー上、子テーブル側からデータが先に入る仕様になっている
・業務仕様上、詳細データから先にDBに入って、次に親伝票がDBに入るフローなどが該当する。
(4) 超高トラフィック
・パフォーマンスを重視して外部キー制約を外す判断はアリ。でも最初から外すべきではない。
(5) フレームワークがサポートしていない
・Railsとかはデフォルトで外部キーを無視するらしい。
(6) シャーディングしている
・テーブルを分割してると参照整合性制約を付加できない。
(必然的に、どこの領域にデータが入っているかわからないないので、参照整合性の付けようがない)
・その場合はアプリケーション側で参照整合性を担保する。
・シャーディングについては書籍のP.97に言及がある。
■外部キー制約のバージョン管理
・ソースはバージョン管理システムで管理することが一般的だが、外部キー制約は管理しないことが多い。
・23章にバージョン管理の話がある。
・開発時にはDB定義の変更とかも生じる。例えばテーブルが増えたり、分かれたりとか。
・そこで、DB定義をスクリプトにして、DB定義も含めてバージョン管理システムの管理下に入れましょう、というのがベストプラクティス。
■DBのマイグレーション
DBのマイグレーションをサポートするツールが増えてきている。
(1) Liquibase
・http://www.liquibase.org/
(2) Flyway : The agile database migration framework for Java
・http://flywaydb.org/
・flywayは時間的に進む方向しか管理できず、ダウンは無い(らしい)。
(3) Jiemamy
・http://jiemamy.org/display/PORTAL/Home
・以前、データベースリファクタリング読書会で紹介された。
(4) Railsの「マイグレーション(migrations)」
・直接SQLを使わずに、データベースのテーブルやカラムなどの構造を変更できる仕組みらしい。
・Railsはデフォルトで外部キーを無視する(らしい)。
・外部キー制約補助のためのGem「foreigner」というものがあるらしい。
・フレームワークに選択の余地を持たせている。
■DDLの生成
DDLを生成する手段としては大きく3パターンある。
(1) モデリングツールから生成
・ER/StudioなどでER図を作成し、そこかからDDLを生成させる。
(2) Excelツールから生成
・Excelでテーブル情報を書いておき、VBAマクロでDDLを生成させる。
(3) DSLから生成
・Railsとかはこの仕組みらしい。
・テーブル定義をDB非依存で略式機構で書く。(P.258のコラム参照)
・Railsプログラマは、カラムにアクセスするgetter/setterは使わないらしい。自動的にできるそうな。
■ORM(O/Rマッパ)
・Hibernateとかはモデル主導らしい。DDLも生成できる。
・DRY(Don't Repeat Yourself)の起点になる。
・既存のDBからリバースエンジニアリングでクラスを作れる。
・Eclipseプラグイン「ERMaster」を使うと、ER図を書いたりクラス生成とかができる。
http://ermaster.sourceforge.net/index_ja.html
・EXCEL → XML → JAXBという流れもある。ExcelでDB定義書いて、XMLに情報を履いて、Javaクラスを生成する。
■フィクスチャ(fixture)
・「フィクスチャ (fixture)」とは、データベースに入れるデータをシリアライズして格納したファイル群のことらしい。
・Railsだと、事前に用意したテストデータを読み込み、常にDBの内容を一定に保つための仕組みのことを、フィクスチャと呼ぶらしい。
・結果取得の遅延ができるらしい。行為が行われないと決まらない、というのを定義できるとか。
■外部キー制約の一時的な無効化
・ALTER TABLE DISABLE CONSTRANT
・外部キー制約を強制せず、外部キー制約の存在を明確にするためのコマンドらしい。(制約の無効化)
・書籍「データベースリファクタリング」のP.203に書いてある。
・セッションレベルで制約をオフにする。
・テストデータをDBに投入するときに一時的に外部キー制約を無効化したいときに使える。
■原則「迷ったら、寿命の長い方に寄せろ」
・アプリケーションコードよりデータベースの寿命の方が長い。データは移行しながらずっと使うので。
・更に、データベースよりデータの寿命の方が長い。
・なので、変なデータがDBにいったん入ってしまったら、その後、何十年も苦しむことになる。
・設計に迷う場合は、寿命の長い方にとって良い設計となるように寄せるべき。
■カスケード更新
・カスケード更新はあんまり使わないかも。
・4.5.1節でaccount_id列にON UPDATE CASCADEを定義しているが、そもそも主キーの付け替えなんてやらない。
・Bugsテーブルのstatus列にもON UPDATE CASCADEを定義しているが、これは10章のサーティーワンフレーバーなので、データは付け替えない。
・逆に、アプリの方はカスケード更新はよくある。すべてのO/Rマッパはカスケード削除はある。
・カスケード削除だと、ログには発行した1クエリしか残らない。なのでログから追えない。
(裏で子テーブルの削除が行われるが、この削除クエリはログには出ない)
■リレーションの種類
・リレーションには3種類ある。
①依存リレーション
②非依存リレーション
③多対多リレーション
・ORマッパは依存・非依存・多対多の設定が大事。設定することで、DDLをほとんど手で書かなくても済む。
■既存DBへの外部キー制約の追加
・既存DBにも頑張って外部キー制約を付けたほうが良い。
・ゴミデータが既存DBにないならば、外部キー制約の追加はそんなに大変ではない。
・「DBに変なデータが入ってしまったのでDBから削除します」となると、お客様への説明責任のコストがかかる。
・そうなるくらいなら、外部キー制約は張っておくべき。
・外部キー制約が無いDBが、顧客システムでなく社内システム場合は、「あえて追加しない」とい選択肢もアリ。
・DBをリファクタリングするかどうかは業務システムの特性による。
■新規DBへの外部キー制約の設定
・新規システムの場合は、外部キー制約は最初から付けておくべき。これは間違いなく言える。
・ハイトラフィックでシャーディングとかやらざるを得ない場合は、ノーガード戦法(外部キー制約を外す)でいくしかない。
ちなみにこの日の模造紙&付箋はこんなカンジ。

★感想:
キーレスエントリーは私にとって、非常に身近で興味深いテーマでした。
というのも、私の会社ではモデリングにER/Studioを、DBMSにHiRDBを使うことが多いのですが、ER/StudioからDDLを生成する際、DBMSとしてHiRDBを選択していると生成DDLに外部キー制約が付かないのです。。。
問い合せてみるとこれは仕様だそうで、手動で付けて対応しているとのこと。
これもマイナーなDBMSの定めか。。。orz
あと、やはり私も、テストデータの投入で困ったことはありますね。
順序性を考慮するのって、テストが複雑になるほど大変なわけで。
この日出てきた、外部キー制約の無効化、今度使ってみることにしよう。
あと、Railsの機構にも興味が出ました。
和田さんがいろいろ紹介してくださったんですが、私、Rails触ったことないので。。。
どっかで勉強してみたい。
最後に参加者の皆様、ありがとうございましたー
- 関連記事
-
- 「Scrum Boot Camp in NII」に参加しました
- SQLアンチパターン読書会 「キーレスエントリー」 に参加しました
- 「オブジェクト指向でコードが書けるようになろう。」に参加しました