チェック制約は、 SQLの整合性制約の一種で、データベーステーブルの各行が満たす必要のある要件を指定します。制約は述語である必要があります。これは、テーブルの 1 列または複数の列を参照できます。述語の結果は、NULLの有無に応じて、、 、 のいずれかになります。述語が と評価された場合、制約に違反していないため、行をテーブルに挿入または更新できます。これは、またはステートメント
の 節の述語とは逆になります。TRUEFALSEUNKNOWNUNKNOWNWHERESELECTUPDATE
たとえば、製品を含むテーブルでは、製品の価格と製品の数量が負でない値になるようにチェック制約を追加できます。
価格 >= 0
数量 >= 0
これらの制約が設定されていない場合、価格がマイナス (-30 ドル) または数量がマイナス (-3 個) になる可能性があります。
チェック制約は、データベース内のデータの妥当性を確認し、データの整合性を確保するために使用されます。データベース レベルで使用すると、データベースを使用するアプリケーションは、無効なデータを追加したり、有効なデータを変更したりすることができなくなり、アプリケーション自体が無効なデータを受け入れる場合でも、データが無効になります。
意味
各チェック制約は、次の構文を使用して
CREATE TABLEorステートメントで定義する必要があります。ALTER TABLE
テーブルテーブル名を作成する(
...、
CONSTRAINT制約名CHECK (述語)、
...
)
ALTER TABLEテーブル名 ADD CONSTRAINT制約名CHECK (述語)
チェック制約が単一の列のみを参照する場合は、制約を列定義の一部として指定できます。
テーブルテーブル名を作成する(
...
列名 型CHECK(述語)、
...
)
NOT NULL制約
制約は、述語を持つ次のチェック制約と機能的に同等です。
NOT NULLIS NOT NULL
チェック (列がNULL ではない)
一部のリレーショナルデータベース管理システムでは、上記の制約構文NOT NULLではなく制約構文を使用するとパフォーマンスを最適化できます。 [1]CHECK
一般的な制限
ほとんどのデータベース管理システムでは、チェック制約を単一行に制限し、定数と決定論的関数へのアクセスを許可していますが、他のテーブルのデータや、トランザクション分離のために現在のトランザクションに表示されないデータへのアクセスは許可していません。
このような制約は、実際にはテーブル チェック制約ではなく、行チェック制約です。これらの制約は、通常、行が直接更新されるときのみ検証され (パフォーマンス上の理由から)、暗黙のトリガーとして実装されることが多いためINSERT、UPDATEこれらの制限がなければ、間接的なアクションによって整合性制約に違反する可能性があります。さらに、これらのレコードに対する有効な変更も、制約によって妨げられますCHECK。危険な制約の例を次に示します。
CHECK ((select count(*) from invoices where invoices.customerId = customerId) < 1000)CHECK (dateInserted = CURRENT_DATE)CHECK (countItems = RAND())
ユーザー定義のトリガーを使用すると、これらの制限を回避できます。実装は似ていますが、トリガーはテーブルが直接変更された場合にのみ起動され、他のテーブルでの間接的で重要な変更を処理するのは設計者の責任であることが意味的に明らかです。一方、制約は、ユーザーの操作や設計者の先見性の欠如に関係なく、「常に真」となるように意図されています。
参考文献
- ^ PostgreSQL 13 ドキュメント、第 5 章データ定義、セクション 5.4.2.非 Null 制約、ウェブサイト: https://www.postgresql.org/docs/13/ddl-constraints.html、2021 年 1 月 9 日にアクセス
