sql >> データベース >  >> RDS >> Oracle

OracleのCheckステートメントでのサブクエリの使用

    CHECK制約はクエリに基づくことができないため、この種の問題を解決するための3つの基本的な方法があります。

    オプション1:トリガー

    最も単純なアプローチは、TANKにトリガーを設定して、TANKSにクエリを実行し、LEVELがCAPACITYを超えた場合に例外をスローすることです。ただし、この種の単純なアプローチの問題は、並行性の問題を正しく処理することがほぼ不可能であるということです。セッション1でCAPACITYが減少し、セッション2でLEVELが増加すると、両方のトランザクションがコミットされ、トリガーは違反を検出できなくなります。テーブルの一方または両方がめったに変更されない場合、これは問題にならない可能性がありますが、一般的には問題になります。

    オプション2:マテリアライズドビュー

    並行性の問題を解決するには、TANKテーブルとTANKSテーブルを結合するON COMMITマテリアライズド・ビューを作成してから、マテリアライズド・ビューにLEVEL<=CAPACITYであることを確認するCHECK制約を作成します。マテリアライズド・ビューに制約に違反するデータのみを含めることにより、データを2回保存することを回避することもできます。これには、両方のベーステーブルにマテリアライズドビューログが必要であり、挿入に少しオーバーヘッドが追加されます(ただし、トリガーを使用する場合よりは少なくなります)。チェックをcommit-timeにプッシュすると、並行性の問題は解決されますが、マテリアライズド・ビューのリフレッシュが失敗したためにCOMMIT操作が失敗する可能性があるため、例外管理の問題が少し発生します。アプリケーションは、その問題を処理し、その事実をユーザーに警告できる必要があります。

    オプション3:データモデルを変更する

    テーブルBの制限に依存するテーブルAの値がある場合、それは、Bの制限がテーブルAの属性である必要があることを示している可能性があります(テーブルBの属性である代わりに、またはそれに加えて)。もちろん、データモデルの詳細によって異なりますが、検討する価値がある場合がよくあります。



    1. MariaDBでのLPAD()のしくみ

    2. SQLiteでデータを暗号化する

    3. GROUP BY/SQLでの集計関数の混乱

    4. MySQLでテキスト列にデフォルト値を設定できないのはなぜですか?