web-dev-qa-db-ja.com

トリガー、アサーション、チェックの違いは何ですか(データベース内)

トリガー、アサーション、チェックの正確な違いを誰でも説明(またはサイトや論文を提案)できますか?

編集:私はデータベースではなく、他のシステムやプログラミング言語ではありません。

22
Am1rr3zA

トリガー-トリガーは、データベースでの更新、挿入、または削除の前または後に実行する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)

Balanceカラムに100未満の値を挿入しようとすると、エラーがスローされます。

アサーション-アサーションは、条件が満たされることを確認するか、またはデータベースオブジェクトで実行されるアクションを停止するSQLの一部です。テーブル全体またはデータベース全体をロックアウトすることを意味する場合があります。

事態をより混乱させるために-トリガーを使用してチェック制約を実施し、一部のDBではアサーションの代わりをすることができます(変更中のテーブルに関係のないコードを実行できるようにすることにより)。初心者にとってよくある間違いは、トリガーが必要なときにチェック制約を使用すること、またはチェック制約が必要なときにトリガーを使用することです。

例:アカウントを開設するすべての新規顧客の残高は100ドルでなければなりません。ただし、口座が開設されると、残高はその金額を下回る可能性があります。この場合、新しいレコードが挿入されたときにのみ条件を評価するため、トリガーを使用する必要があります。

56
jellomonkey

SQL標準では、ASSERTIONSとCHECK CONSTRAINTSの両方が、リレーショナル理論が「制約」と呼ぶものです。データベースに実際に含まれるデータが準拠しなければならない規則です。

2つの違いは、CHECK CONSTRAINTSはある意味ではるかに「単純」であるということです。これらは1つの単一の行のみに関連するルールであり、ASSERTIONは任意の数の他のテーブルまたは同じ数の他の行を含むことができますテーブル。それは明らかに、DBMSビルダーがそれをサポートすることを(はるかに!)より複雑にします。そして、それが、彼らがそうしない理由です:彼らはそれを行う方法を知らないだけです。

TRIGGERは、特定のテーブルで特定の種類の更新操作(挿入/削除/更新)が実行されるたびに実行する必要があるDBMSに宣言できる実行可能コードです。トリガーは例外を発生させる可能性があるため、トリガーはASSERTIONと同じものを実装するための手段です。ただし、トリガーの場合、すべてのコーディングを行う必要があるのはプログラマーであり、間違いを犯すことはありません。

編集

Onedaywhenのコメントが再。アサーション/チェックcnstr。は正しい。違いは、はるかに微妙です(そして紛らわしい)。実際、この標準では、CHECK制約のサブクエリが許可されています。 (ただし、ほとんどの製品はサポートしていません。そのため、私の「単一行に関連する」はほとんどのSQL製品に当てはまりますが、標準には当てはまりません。)まだ違いはありますか?はい、まだあります。偶数以上。

最初のケース:TABLE MEN(ID:INTEGER)およびTABLE WOMEN(ID:INTEGER)。 「MENテーブルとWOMENテーブルの両方にID値は表示されない」というルールを想像してください。それは単一のルールです。 ASSERTIONの意図は、データベース設計者がこの単一のルールを記述し[実行する]ことであり、DBMSはこれに対処する方法(もちろん、効率的)と、特定のルールに関係なくこのルールを実施する方法を知っていますデータベースの更新が行われます。この例では、DBMSは、INSERT INTO MENとINSERT INTO WOMENでこのルールをチェックする必要があることを認識しますが、DELETE FROM MEN/WOMENまたはINSERT INTO <anyothertable>をチェックする必要はありません。

しかし、DBMSはすべてを実行するのに十分ではありません。それで、何をする必要がありますか?データベース設計者は、2つのCHECK制約を自分のデータベースに追加する必要があります。1つはMENテーブルに(WOMENテーブルに対して新しく挿入されたMEN IDをチェック)、もう1つはWOMANテーブルに(逆方向にチェック)。最初の違いがあります:1つのルール、1つのアサーション、[〜#〜] two [〜#〜] CHECK制約。 CHECK制約は、ASSERTIONよりも抽象化のレベルが低いため、設計者は(a)ASSERTIONに違反する可能性があるすべての種類の更新、および(b)特定のチェックを実行する必要があることについて、より多くのことを考える必要があります。彼が(a)で見つけた特定の「更新の種類」のいずれかについて。 (私はまだ何が「何」で何が「HOW」であるかについて「絶対」ステートメントを作成するのは本当に好きではありませんが、CHECK制約はデータベースデザイナーによるより多くの「HOW」思考(手順)を必要とするのに対し、ASSERTIONsデータベース設計者が「WHAT」(宣言的)のみに集中できるようにします。)

2番目のケース(これは完全にはわかりませんが、一粒の塩を使用してください):平均的なRIルール。もちろん、REFERENCES句を使用してこれを指定するために使用されます。しかし、REFERENCES句が利用できなかったと想像してください。 「すべての注文は既知の顧客が行う必要があります」などのルールは、まさにそれ、つまりルールです。つまり、単一のアサーションです。ただし、このようなルールは常に2つの方法で違反する可能性があることはわかっています。ORDERの挿入(この例)とCUSTOMERの削除です。さて、前述のMAN/WOMENの例に沿って、CHECK制約を使用してこの単一のルール/ ASSERTIONを実装する場合、ORDERへの挿入時にCUSTOMERの存在をチェックするCHECK制約を記述する必要がありますが、 CUSTOMERからdeletionで必要なことは何でも行うと書いていますか?私が知る限り、それらは単にその目的のために設計されたものではありません。 2つ目の違いがあります。CHECK制約はINSERTのみに関連付けられています。ASSERTIONSは、DELETE時にもチェックされるルールを定義できます。

3番目のケース:テーブルCOMPOS(componentID:... percentage:INTEGER)と、「すべてのパーセンテージの合計は常に100でなければならない」というルールを想像してください。これは単一のルールであり、ASSERTIONはそれを指定できます。しかし、CHECK制約を使用してこのようなルールを強制する方法を想像してみてください。たとえば、3つの非ゼロ行が合計100になる有効なテーブルがある場合、このテーブルにどのように変更を適用できますか。チェック制約?合計が同じ割合になる他の置換行を追加したり、残りの行を更新したりせずに、行を削除または更新(減少)することはできません。挿入または更新(増加)についても同様です。少なくとも、遅延チェックを延期する必要がありますが、それから何をチェックしますか? 3番目の違いがあります:CHECK制約は個々の行を対象としていますが、ASSERTIONは複数の行を「スパン」するルール(つまり、行の集約に関するルール)を定義/表現することもできます。

11
Erwin Smout

アサーションはデータを変更せず、特定の条件のみをチェックします

トリガーは条件を確認し、データを変更できるため、より強力です

-------------------------------------------------- ------------------------------

アサーションはデータベース内の特定のテーブルにリンクされておらず、特定のイベントにリンクされていません

トリガーは特定のテーブルと特定のイベントにリンクされています

6
Mohamed Adel

データベース制約には、データベースの更新時に満たす必要がある条件が含まれます。 SQLでは、制約条件がfalseと評価された場合、更新は失敗し、データは変更されずに残り、DBMSはエラーを生成します。

CHECKASSERTIONはどちらも、SQL標準で定義されているデータベースの制約です。重要な違いは、CHECKが特定のベーステーブルに適用されるのに対し、ASSERTIONはデータベース全体に適用されることです。テーブルT1T2の結合行を合計10行に制限する制約を考えます。

CHECK (10 >= (
              SELECT COUNT(*)
                FROM (
                      SELECT *
                        FROM T1
                      UNION
                      SELECT * 
                        FROM T2
                     ) AS Tn
             ))

テーブルが空であると仮定します。これがASSERTIONとしてのみ適用され、ユーザーがT1に11行を挿入しようとした場合、更新は失敗します。制約がT1のみにCHECK制約として適用された場合も同様です。ただし、T2を対象とするステートメントがT1に適用される制約を引き起こさないので、制約がT1CHECK制約として適用された場合、制約のみが成功します。テスト済み。

ASSERTIONCHECKの両方を遅延させることができ(DEFERRABLEとして宣言されている場合)、データが一時的に制約条件に違反することを許可しますが、トランザクション内のみです。

サブクエリを含むASSERTIONおよびCHECK制約は、コア標準SQLの外部の機能であり、これらの機能をサポートする主要なSQL製品はありません。 MS Access(厳密には工業用製品ではありません)は、サブクエリを含むCHECK制約をサポートしますが、遅延可能な制約に加えて、制約テストは常に行ごとに実行されます。 。

CHECK制約と共通して、トリガーは特定のテーブルに適用されます。したがって、トリガーを使用して、CHECK制約ではなくASSERTION制約と同じロジックを実装できます。トリガーは手続き型コードであり、制約とは異なり、ユーザーはパフォーマンスやエラー処理などの懸念に対してはるかに多くの責任を負う必要があります。ほとんどの商用SQL製品はトリガーをサポートしています(前述のMS Accessはサポートしていません)。

2
onedaywhen

トリガーを起動するには式がtrueである必要がありますが、式がfalseの場合は常にチェックが評価されます。

0
Feri