制約の概要¶
Snowflakeは、次の制約の機能を提供します。
ANSI SQL標準の制約のタイプ。詳細については、 サポートされている制約のタイプ をご参照ください。
名前付き制約。
単一列および複数列の制約。
インラインおよびアウトラインの制約の作成。
制約の作成、変更、削除。
詳細については、 CREATE | ALTER TABLE ... CONSTRAINT をご参照ください。
サポートされている制約のタイプ¶
Snowflakeは、ANSI SQL標準で次の制約のタイプをサポートしています。
PRIMARY KEY :列のすべての値が区別され、列がNULL値を格納できないことを保証します。主キーは、テーブル内の各行を一意に識別します。
UNIQUE:列内のすべての値が異なることを保証します。PRIMARY KEY制約とは異なり、UNIQUE制約を持つ列はNULL値を持つことができます。
FOREIGN KEY :列または列のセットの値が別のテーブルまたは同じテーブルの値と一致することを要求することにより、参照整合性を強制します。
NOT NULL :列がNULL値を格納できないようにします。
CHECK:テーブルの1つ以上の列に挿入または更新できる値の条件としてSQL式を強制します。詳細については、 CHECKの制約 をご参照ください。
テーブルには複数の一意キーと外部キーを含めることができますが、主キーは1つしか含めることができません。PRIMARY KEY 制約は、列が NOT NULL と UNIQUE の両方であることを意味します。
すべての外部キーは、外部キーの各列の列タイプと一致する、対応する主キーまたは一意キーを参照する必要があります。外部キーの主キーは、外部キーとは異なるテーブル、または同じテーブルに存在できます。ハイブリッドテーブル にまたがってFOREIGN KEY制約を定義する場合、そのテーブルは同じデータベース内になければなりません。
次のテーブルは、制約の強制と制約が必要かどうかに関する、標準テーブルとハイブリッドテーブルの動作の違いをまとめたものです。
制約が*強制*されるのは、ある列が特定の方法で更新されないようにする場合です。例えば、NOT NULLと宣言された列は、NULL値を含むことはできません。NOT NULL列にNULL値をコピーまたは挿入しようとすると、エラーになります。ハイブリッドテーブルでは、PRIMARY KEY、FOREIGN KEY、UNIQUE制約にNOT ENFORCEDプロパティを設定することはできません。このプロパティを設定すると、
invalid constraint propertyエラーが発生します。制約は、テーブル内の1つ以上の列がそのような制約を持たなければならない場合に 必須 となります。これは、ハイブリッドテーブルの PRIMARY KEY 制約にのみ当てはまります。
機能 |
ハイブリッドテーブル |
標準テーブル |
|---|---|---|
PRIMARY KEYの制約 |
必須、強制 |
オプション、強制ではない |
FOREIGN KEYの制約 |
オプション、参照整合性の強制 |
オプション、強制ではない |
UNIQUEの制約 |
オプション、強制 |
オプション、強制ではない |
NOT NULLの制約 |
オプション、強制 |
オプション、強制 |
CHECKの制約 |
サポート対象外 |
オプション、強制 |
テーブルの制約¶
Snowflakeは永続テーブル、一時テーブル、仮テーブル、ハイブリッドテーブルの制約をサポートしています。すべてのデータ型の列に対して制約を定義でき、1つの制約に任意の数の列を含めることができます。
以下は、制約に関する考慮事項です。
CREATE TABLE ... LIKEまたはCREATE TABLE ... CLONEを使用してテーブルをコピーする場合は、外部キーを含むすべての既存のテーブルの制約が新しいテーブルにコピーされます。CREATE TABLE ... CLONEは、ハイブリッドテーブルではサポートされていません。
DROP、UNDROP、GET_DDLなどの追加のコマンドと関数は、制約が含まれるテーブルでサポートされます。スキーマとデータベースでもサポートされます。
Snowflake Time Travel では、Snowflakeはテーブルメタデータに旧バージョンの制約を保管しないため、テーブルの旧バージョンをコピーする場合はテーブルの現バージョンの制約が使用されます。
単一列制約と複数列制約¶
制約は、同じテーブルの単一の列または複数の列に定義できます。
複数列制約(複合主キーまたは一意キー)の場合、列は順序付けられ、各列には対応するキーシーケンスがあります。
インライン制約とアウトライン制約¶
制約は、テーブルの作成または変更時にインラインまたはアウトラインのいずれかで定義されます。
インライン制約は、列定義の一部として作成され、単一列制約にのみ使用できます。
アウトライン制約は、制約が作成される列を指定する別の句を使用して定義されます。これらは、単一列または複数列の制約の作成、および既存列の制約の作成のいずれかで使用できます。
GET_DDL の制約¶
GET_DDL が返すSQLステートメントには、制約を定義する句が含まれていますが、次にご注意ください。
NOT NULLやDEFAULTなどの単一列のみの制約は、列の定義に従ってインラインで再構築されます。一意、主、外部キーなどのテーブル制約は、単一の列で構成されている場合でも、常にアウトライン制約として再構築されます。
名前のない制約(つまり、システムが生成した名前を持つ制約)については、 GET_DDL はシステムが生成した名前を返しません。
CHECKの制約¶
CHECK制約は、テーブルの1つ以上の列に挿入または更新できる値の条件としてのSQL式を強制します。例えば、CHECK制約により、テーブルの quantity 列にゼロより大きい値のみが含まれる、またはテーブルの salary 列に特定の範囲の値のみが含まれることを確実にする場合があります。
次のSQLコマンドで、 CONSTRAINT句 を使用して、CHECK制約を指定できます。
CHECK_CONSTRAINTS ビュー をクエリすることにより、既存のCHECK制約についての情報を表示できます。
次のDML操作中、CHECK制約が強制されます。
条件がTRUEまたはNULLと評価された場合、DML操作は続行されます。条件がFALSEと評価された場合、CHECK制約は失敗します。
CHECK制約の例については、 標準テーブルの制約の例 をご参照ください。
使用上の注意¶
CHECK制約は常に強制されます。
次の ALTER TABLE コマンドとIcebergの同等のものを使用して、CHECK制約を扱えます。
ALTER TABLE ... RENAME CONSTRAINT
ALTER TABLE ... ADD [ CONSTRAINT <constraint_name> ] CHECK ( <expr> ) ENABLE [ VALIDATE | NOVALIDATE ]
CHECK制約のデフォルトであるENABLE VALIDATEは、すべての既存の行と、コマンドの実行後に挿入または更新されるすべての行に制約を強制します。ENABLE VALIDATEは新しいテーブルでのみサポートされ、既存のテーブルではサポートされません。
ENABLE NOVALIDATEは、コマンドの実行後に挿入または更新されたすべての行に制約を強制しますが、既存の行には制約を強制しません。
ALTER TABLE ... ALTER CONSTRAINT <constraint_name> ENABLE [ VALIDATE | NOVALIDATE ]
CHECK制約をNOVALIDATEからVALIDATEに変更した場合、VALIDATEに変更される前に、制約はすべての既存の行に適用されます。
ALTER TABLE ... DROP CONSTRAINT
次の ALTER TABLE コマンドとIcebergの同等のものは、CHECK制約が定義されている列に対して操作できます。
ALTER TABLE ... ALTER COLUMN
CHECK制約を変更しない操作のみがサポートされています。
ALTER TABLE ... RENAME COLUMN
名前が変更された列を参照するCHECK制約は、新しい列名を使用するように暗黙的に更新されます。
ALTER TABLE ... DROP COLUMN
削除される列が、別の列も参照する既存のCHECK制約で使用されている場合、操作は失敗します。この場合は、列を削除する前に制約を削除します。
インジェスチョン中に記録がCHECK制約に違反している場合、無効な記録が最初に検出されたときに、バッチ操作全体が失敗します。
制限事項¶
標準テーブルとSnowflake管理IcebergテーブルのみがCHECK制約をサポートします。ハイブリッドテーブルなど、その他のタイプのテーブルはCHECK制約をサポートしていません。
既存のCHECK制約に関連付けられた式をALTER TABLEコマンド使用して変更することはできません。式を変更するには、CHECK制約を削除して再作成します。
CREATE OR ALTER TABLEコマンドでCHECK制約を指定することはできません。
以下の操作はCHECK制約をサポートしていません。
CHECK制約付きのテーブルにCOPY INTOしようとすると、操作は失敗します。
CHECK制約があるターゲットテーブルでパイプを作成しようとすると、操作は失敗します。
CHECK制約を持つテーブルにストリーミングインジェスチョンを試みると、操作は失敗します。
CHECK制約があるIcebergテーブルに対して外部書き込みを試みると、操作は失敗します。