トリガー、アサーション、チェックの正確な違いを誰かが説明(またはサイトや論文を提案)できますか?また、それらをどこで使用すべきかについても説明できますか?
編集:私はデータベースを意味し、他のシステムやプログラミング言語ではありません。
トリガー、アサーション、チェックの正確な違いを誰かが説明(またはサイトや論文を提案)できますか?また、それらをどこで使用すべきかについても説明できますか?
編集:私はデータベースを意味し、他のシステムやプログラミング言語ではありません。
トリガー-トリガーは、データベースの更新、挿入、または削除の前または後に実行するSQLの一部です。平易な英語でのトリガーの例は、次のようになります。顧客レコードを更新する前に、現在のレコードのコピーを保存します。これは次のようになります。
CREATE TRIGGER triggerName
AFTER UPDATE
INSERT INTO CustomerLog (blah, blah, blah)
SELECT blah, blah, blah FROM deleted
アサーションとチェックの違いはもう少し曖昧で、多くのデータベースはアサーションさえサポートしていません。
チェック制約-チェックはSQLの一部であり、レコードに対してアクションを実行する前に条件が満たされていることを確認します。平易な英語では、これは次のようになります。すべての顧客は、自分のアカウントに少なくとも100ドルのアカウント残高が必要です。これは次のようになります。
ALTER TABLE accounts
ADD CONSTRAINT CK_minimumBalance
CHECK (balance >= 100)
バランス列に100未満の値を挿入しようとすると、エラーがスローされます。
アサーション-アサーションは、条件が満たされていることを確認する、またはデータベースオブジェクトで実行されるアクションを停止するSQLの一部です。これは、テーブル全体またはデータベース全体をロックアウトすることを意味する場合があります。
さらに混乱させるために、トリガーを使用してチェック制約を適用し、一部のDBではアサーションの代わりに使用できます(変更されるテーブルに関係のないコードを実行できるようにすることで)。初心者によくある間違いは、トリガーが必要な場合はチェック制約を使用し、チェック制約が必要な場合はトリガーを使用することです。
例:アカウントを開設するすべての新規顧客は、100ドルの残高を持っている必要があります。ただし、アカウントが開設されると、残高がその金額を下回る可能性があります。この場合、新しいレコードが挿入されたときにのみ条件を評価する必要があるため、トリガーを使用する必要があります。
SQL標準では、ASSERTIONSとCHECK CONSTRAINTSの両方が、リレーショナル理論で「制約」と呼ばれるものです。つまり、データベースに実際に含まれるデータが準拠する必要のあるルールです。
2つの違いは、チェック制約はある意味ではるかに「単純」であるということです。アサーションは他の任意の数のテーブル、または同じ内の他の任意の数の行を含むことができるのに対し、それらは1つの単一行のみに関連するルールです。テーブル。それは明らかに、DBMSビルダーがそれをサポートすることを(はるかに!)より複雑にします、そしてそれは彼らがそれをサポートしない理由です:彼らはそれを行う方法を知らないだけです。
TRIGGERは、特定の種類の更新操作(挿入/削除/更新)が特定のテーブルで実行されるたびに実行する必要があることをDBMSに宣言できる実行可能コードの一部です。トリガーは例外を発生させる可能性があるため、アサーションと同じことを実装するための手段です。ただし、トリガーを使用する場合でも、すべてのコーディングを行う必要があり、間違いを犯さないのはプログラマーです。
編集
ある日いつのコメントが再。アサーション/チェックcnstr。は正しい。違いははるかに微妙です(そして混乱します)。この標準では、実際にCHECK制約でのサブクエリが許可されています。(ただし、ほとんどの製品はこれをサポートしていないため、私の「単一行に関連する」はほとんどのSQL製品に当てはまりますが、標準には当てはまりません。)それでも違いはありますか?はい、まだあります。1つ以上でも。
最初のケース:TABLE MEN(ID:INTEGER)およびTABLE WOMEN(ID:INTEGER)。ここで、「MENテーブルとWOMENテーブルの両方にID値を表示できない」というルールを想像してみてください。それは単一のルールです。ASSERTIONの目的は、データベース設計者がこの単一のルールを記述し[そしてそれで実行]、DBMSがこれを[効率的に]処理する方法と、特定の方法に関係なくこのルールを適用する方法を知っていることです。データベースの更新が行われます。この例では、DBMSは、INSERTINTOMENおよびINSERTINTOWOMENでこのルールをチェックする必要があることを認識していますが、DELETE FROM MEN/WOMENまたはINSERTINTO<anyothertable>ではチェックを実行する必要はありません。
しかし、DBMSはそれをすべて行うには十分に賢くはありません。では、何をする必要がありますか?データベース設計者は、データベースに2つのCHECK制約を追加する必要があります。1つはMENテーブル(新しく挿入されたMEN IDをWOMENテーブルと照合)、もう1つはWOMANテーブル(逆のチェック)です。最初の違いがあります:1つのルール、1つのアサーション、2つのCHECK制約。CHECK制約は、設計者が(a)ASSERTIONに違反する可能性のあるすべての種類の更新、および(b)どの特定のチェックを実行する必要があるかについて自分自身で考える必要があるため、ASSERTIONよりも抽象化のレベルが低くなります。彼が(a)で見つけた特定の「更新の種類」のいずれかのために。(私はまだ「何」で何が「HOW」であるかについて「絶対」ステートメントを作成するのは本当に好きではありませんが、CHECK制約はデータベース設計者によるより多くの「HOW」思考(手続き型)を必要としますが、ASSERTIONSデータベース設計者が「何」(宣言型)に専念できるようにします。)
2番目のケース(これについては完全にはわかりませんが、一粒の塩を使ってください):平均的なRIルールです。もちろん、REFERENCES句を使用してこれを指定することに慣れています。しかし、REFERENCES句が利用できなかったと想像してください。「すべての注文は既知の顧客が行う必要があります」のようなルールは、実際にはまさにそのルールであり、したがって、単一のアサーションです。ただし、このようなルールは、ORDERの挿入(この例では)とCUSTOMERの削除の2つの方法で常に違反される可能性があることは誰もが知っています。さて、前述のMAN / WOMENの例に沿って、CHECK制約を使用してこの単一のルール/ ASSERTIONを実装する場合は、ORDERへの挿入時にCUSTOMERの存在をチェックするCHECK制約を作成する必要がありますが、どのようなCHECK制約が可能でしょうか。削除時に必要なことは何でもするように書きます顧客から?私の知る限り、それらは単にその目的のために設計されたものではありません。2番目の違いがあります。CHECK制約はINSERTに排他的に関連付けられており、ASSERTIONSはDELETE時にもチェックされるルールを定義できます。
3番目のケース:テーブルCOMPOS(componentID:..。percentage:INTEGER)と、「すべてのパーセンテージの合計は常に100に等しくなければならない」というルールを想像してみてください。これは単一のルールであり、ASSERTIONはそれを指定できます。しかし、CHECK制約を使用してこのようなルールを適用する方法を想像してみてください...たとえば、ゼロ以外の3つの行を合計すると100になる有効なテーブルがある場合、このテーブルに変更を適用して存続できるようにするにはどうすればよいでしょうか。 CHECK制約?同じ割合になる他の置換行を追加したり、残りの行を更新したりせずに、行を削除または更新(減少)することはできません。挿入または更新(増加)についても同様です。少なくとも遅延制約チェックが必要です。それでは、何をチェックしますか?3番目の違いがあります:
アサーションはデータを変更せず、特定の条件のみをチェックします
は条件をチェックし、データを変更できるため、トリガーはより強力です
アサーションはデータベース内の特定のテーブルにリンクされておらず、特定のイベントにリンクされていません
トリガーは特定のテーブルと特定のイベントにリンクされています
データベース制約には、データベースの更新時に満たす必要のある条件が含まれます。SQLでは、制約条件がfalseと評価された場合、更新は失敗し、データは変更されず、DBMSはエラーを生成します。
CHECK
とは両方ともASSERTION
、SQL標準によって定義されたデータベースの制約です。重要な違いは、aCHECK
が特定のベーステーブルに適用されるのに対し、anASSERTION
はデータベース全体に適用されることです。T1
テーブル内の結合された行をT2
合計10行に制限する制約について考えてみます。
CHECK (10 >= (
SELECT COUNT(*)
FROM (
SELECT *
FROM T1
UNION
SELECT *
FROM T2
) AS Tn
))
テーブルが空であると想定します。これがASSERTION
唯一の方法として適用され、ユーザーが11行を挿入しようとするとT1
、更新は失敗します。CHECK
制約がのみへの制約として適用された場合も同じことが当てはまりますT1
。ただし、制約が制約として適用されたCHECK
場合T2
、ステートメントターゲティングでは適用された制約がテストさT1
れないため、制約のみが成功します。T1
anASSERTION
とaの両方CHECK
を延期して(として宣言されている場合DEFERRABLE
)、データが一時的に制約条件に違反することを許可しますが、トランザクション内でのみ可能です。
ASSERTION
CHECK
サブクエリに関連する制約はコア標準SQLの外部の機能であり、主要なSQL製品はいずれもこれらの機能をサポートしていません。MS Access(厳密には工業用製品ではありません)はCHECK
、サブクエリを含む制約をサポートしますが、延期可能な制約はサポートしません。さらに、制約テストは常に行ごとに実行されます。実際の結果、機能は非常に制限されます。
CHECK
制約と共通して、トリガーは特定のテーブルに適用されます。CHECK
したがって、トリガーを使用して、制約と同じロジックを実装できますが、。は実装できませんASSERTION
。トリガーは手続き型コードであり、制約とは異なり、ユーザーはパフォーマンスやエラー処理などの懸念に対してはるかに多くの責任を負う必要があります。ほとんどの商用SQL製品はトリガーをサポートしています(前述のMS Accessはサポートしていません)。
トリガーを起動するには式がtrueである必要がありますが、式がfalseの場合は常にチェックが評価されます。