« Git はク○? | トップページ | xyzzy から sqlite を使う »

2009年4月25日 (土)

RDBMS の制約の使い方

制約というのは、一意性制約、参照整合性制約、チェック制約などのことです。

個人的には、 RDBMS の制約の典型的な使い方は、 トランザクションの並行実行によって発生する、競合状態 ( race condition ) の検出に使う、というものだと考えてまして。アプリケーション側で、レコード・ロックだの、テーブル・ロックだのやるくらいなら、 RDBMS に任せてしまうが良い、と考えています。

簡単なので、一意性制約の例を挙げますと。単に、テーブルに、値が重複してはならないフィールドの集まりがあるわけですな。

そうすると、2つ以上のトランザクションが、この制約を満たすために、テーブルに既に値があるかどうかを、 SELECT で確認して、それからレコードを INSERT するなり、 UPDATE するなりする、という状況が起きる。 いわゆる、 check-then-act な競合状態が起きるわけです。

ここで、アプリケーション側で RDBMS のロック機能を使って atomic にするというのは、あまりよろしくない。 RDBMS にこんな地雷を埋め込んでいると、新しくリリースされたアプリケーションが、同じ RDBMS を使って、デッド・ロック起こしたり、パフォーマンス障害を起こすのは時間の問題と考えて良いでしょう。

ですので、素直にテーブルのフィールドに一意性制約をつけて、 RDBMS に重複を検出させるのがよろしかろうと思います。 もちろん、アプリケーションのデータ・チェックで、重複回避のために値の存在確認はさせるべきです。RDBMS の制約は、あくまで競合状態の検出にのみ使います。

当然のことながら、 制約を安易に多用しますと、RDBMS 内でロックを多発させることになって、パフォーマンス劣化を引き起こします。 RDBMS の制約は、並行処理の設計の問題であって、単なる RDBMS の便利機能ではありません。アプリケーションのデータ・チェックの代用にはなりませんので、悪しからず。

制約違反が大量発生して RDBMS がとてつもなく遅くて困るって?

アプリケーションが、データ・チェックをさぼってないか、確認してください。本当にそれらの制約が必要なのか、もう一度よく検討してください。

もしそれが、競合状態の多発を意味しているのであれば、根本的にシステムの設計がまずい可能性があります。非同期にして直列処理することを考慮しましょう。ハードウエアのキャパシティ不足であるなら、ハードウエアの増強を検討しましょう。

|

« Git はク○? | トップページ | xyzzy から sqlite を使う »

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/80472/29275689

この記事へのトラックバック一覧です: RDBMS の制約の使い方:

» 2009-05-04 [Yet Another But Open]
アプリケーションが、データ・チェックをさぼってないか、確認してください。本当にそれらの制約が必要なのか、もう一度よく検討してください。 ronSpace: RDBMS の制約の使い方 Rack provides a common API for connecting web frameworks, web servers and layers of soft... [続きを読む]

受信: 2009年5月 4日 (月) 18時56分

« Git はク○? | トップページ | xyzzy から sqlite を使う »