DBMSがASSERTIONをサポートしないのはなぜですか?質問する

DBMSがASSERTIONをサポートしないのはなぜですか?質問する

最近、データベースのコースで ASSERTION について学んだのですが、教授は、SQL-92 標準であるにもかかわらず、主要なデータベースではサポートされていないと指摘しました。その理由を調べるために Google で検索してみましたが、このトピックに関する議論はないようです。

では、なぜ ASSERTION は大多数のリレーショナル データベース パッケージでサポートされていないのでしょうか? これは単にパフォーマンスの問題なのでしょうか、それとも本質的に難しい点があるのでしょうか?


可能であれば、それを実装しているデータベース パッケージも記載してください (例: 学術/教育用 DB がある場合)。また、この問題についてあまり議論されていないのはなぜでしょうか。SQL や SQL-92 の Wikipedia ページにも記載されていません。ただし、最初に主な質問に答えるか、コメントで答えてください。

私はないトリガーやその他の方法でそれを実装する方法を探しています。

ベストアンサー1

制約には、列レベル、行レベル、テーブルレベル、スキーマ レベルの 4 つのレベルがあります。

たとえば、テーブル レベルには、宣言されたソース テーブル以外のターゲット テーブルが含まれますが、ソース テーブルが変更された場合にのみチェックされます。理論上は、スキーマ レベルの制約は、スキーマ内のすべてのテーブルのすべての変更に対してチェックされますが、実際には、オプティマイザーはより詳細な方法で変更を検出できます。したがって、DBMS がスキーマ レベルの制約をサポートしている場合、実際にはテーブル レベルの制約はあまり役に立ちません。

現在、SQL製品ではスキーマレベルの制約をサポートしていませんCREATE ASSERTIONレッドビーDEC が管理していたときにはサポートされていましたが、現在はサポートされていません。 -- 更新: プライベート メッセージで、Sybase の SQL Anywhere はサポートしているCREATE ASSERTIONが、重大なエラーが発生し、このような制約に違反することがあるというアドバイスを受けました。

私が使用した中で、制約内のサブクエリをサポートし、テーブル レベルの制約を可能にする唯一の SQL ライクな製品はCHECK、Access データベース エンジン (ACE、Jet など) です。問題があるただし、まず、制約チェックを延期する SQL-92 機能 (または同等の機能) はサポートされていません。次に、テーブル レベルの制約は、SQL-92 標準で要求されているようにステートメントが完了したときではなく、影響を受ける各行に対してチェックされます。言うまでもなく、回避策は非常に面倒です。たとえば、制約を削除して、その際にテーブルをロックし、更新を実行し、制約を再作成します。スキーマ レベルの制約は、関係するすべてのテーブルに同じ制約を追加することで実現できると考えられますが、事実上実行不可能です。

おそらくこれらの理由から、アクセスチームはCHECK制約機能をこれまで公表してこなかった。まったく超えてJet 4.0の最初の発表(たとえば、Access ヘルプには記載されていません)。とはいえ、テーブル内制約 (たとえば、有効な状態の「履歴」一時テーブル内の順序付けられたキー) の場合、特に Access がトリガーのような機能 (ただし SQL ベースではない) を昨年初めて取得したことを考慮すると、この機能は適切に機能します。

もちろん、SQL にはUNIQUEテーブル レベルの制約と参照整合性制約がありますが、これらは特殊なケースです。したがって、実際に遭遇する制約はすべて、列レベルまたは行レベルのいずれかになります。

CHECK()MySQL では、 SQL DDL で使用してもエラーなく解析されますが、効果はありません。制約のない SQL 製品をユーザーが許容できるとは、私には理解できませんCHECK。PostgreSQL には優れた制約モデルがあります。ヒント、ヒント :)

では、なぜテーブル間制約がサポートされることがほとんどないのでしょうか。理由の 1 つは、歴史的な状況によるものであるに違いありません。@gbn が正しく特定しているように (「同時実行」というタイトルで)、Sybase/SQL Server ファミリの SQL 実装は、テーブル間制約チェックに対応できないモデルに基づいており、これは今後も変更される可能性は低いです。

これを逆に考えてみましょう。もしあなたが今SQL製品を作るとしたら、 を含めますか?もしそうするなら、制約CREATE ASSERTIONも実装する必要があるでしょう(DEFERRABLE多重割り当ておそらく、より優れたモデルです。しかし、「従来の」オプティマイザを構築するルートを進むと、より多くの研究と経験を活用できます。また、スキーマ レベルの制約に対する商業的な需要がないことがわかるかもしれません (MySQL が CHECK 制約なしでも実現できるのであれば...)。PostgreSQL がそれを行わないのであれば、誰も行わないと思います。

本当の問題は、ほとんどの産業用製品がすでにトリガー機能を開発しており、ユーザーが任意の複雑さの「制約」を記述できる(さらに、何かが起こったことを知らせるために電子メールを送信するなど、さらに多くのことができる)ということだと思います。確かに、それらは宣言的ではなく手続き的であり、プログラマーは真の制約があればシステムが処理する多くの余分な作業を行う必要があり、パフォーマンスはそれほど良くありません。しかし、実際にはそれらは今日の実際の製品に存在し、ベンダーに「刑務所から逃げるカード」を提供しています。顧客はテーブルを叩いて彼らのために働いていない?

学術/教育言語に関しては、@Damien_The_Unbelieverが正しく指摘しているように、チュートリアル D CONSTRAINT常に「スキーマ」レベルであるため、定義上、任意の複雑さのグローバル制約が許容されます。この種の機能を備えた独自のDBMS(!!)を設計する場合は、既存のSQL DBMSをストレージとして使用しながらD仕様を実装することを検討してください。データフォーやった。


一つの疑問が私を悩ませています。既存の「業界標準」の SQL DBMS がトリガーをサポートしているのに、なぜ内部で単純に宣言をトリガーにマッピングしないのでしょうかCREATE ASSERTION。その答えは、従来のテクノロジではパフォーマンスがひどいものになることを DBMS が知っているからではないかと長い間疑っていました。

より満足のいく答えは、データベース専門家のための応用数学 Lex de Haan、Toon Koppelaars 著、第 11 章。トリガーを使用してマルチタプル制約を強制するときに使用するさまざまな実行モデルを定義します。最も洗練された (ただし、非常に実行可能な) モデルは EM6 と呼ばれ、次の手順が含まれます。

  1. 正式な仕様を制約検証クエリに変換します。
  2. 遷移効果を維持するためのコードを開発します。
  3. 制約検証クエリが必要な場合にのみ実行されるようにする遷移効果 (TE) クエリを考案します (例: チェックを更新された行のみに制限できますか? DELETE がこの制約に違反することはありますか? 制約のチェックを必要とするために UPDATE が関与する必要がある特定の列のみがありますか? など)
  4. TE クエリで検証クエリで使用できる値を提供することにより、制約検証クエリを最適化する手段を見つけます。
  5. データ整合性 (DI) コードにシリアル化戦略を考案して追加します。[つまり、トランザクションが別のトランザクションが書き込んでいる「不良」データを読み取ることができない同時実行性の問題を解決します]。

そして彼らは次のように主張します(しゃれではありません!):

DBMS ベンダーが、任意の複雑な述語を受け入れ、効率的な遷移効果 (TE) クエリ、最小限の検証クエリ、および最適なシリアル化コードを計算し、実行モデル EM6 を実装するアルゴリズムをプログラムすることは不可能だと考えられるため、将来これらのベンダーがマルチタプル制約を実用的かつ使用可能で許容可能な方法で完全にサポートすることは期待できません。私たちが期待できる最善のことは、データベース研究者が最初により一般的な制約のクラスを考え出し、それらの便利な省略形を開発することです。次に、DBMS ベンダーは、これらの省略形と一致する新しい宣言的構造を提供し、これらの一般的な制約のクラスを DBMS に簡単に記述できるようにする必要があります。このような一般的なクラス宣言があれば、DBMS ベンダーは、制約を実装するための EM6 のような実行モデルを裏で提供するアルゴリズムをプログラムできるはずです。

データベース制約の一般的なクラスの 1 つは外部キーであり、もちろんこれはすでに広く実装されています。

おすすめ記事