What you will be able to do
- Define a primary key, inline or out-of-line, including a composite key
- Say which constraint types Snowflake enforces on standard tables and which it only records
- Compare how constraints behave on standard tables and on hybrid tables
- Avoid constraint properties that stop a constraint from being created
Key concept
Declared (informational) constraints — On a standard Snowflake table, PRIMARY KEY, UNIQUE and FOREIGN KEY are stored as metadata that describes the model, but Snowflake does not check them. Only NOT NULL and CHECK actually reject bad rows, so keeping keys valid is the job of your pipeline.
1.Defining primary keys and the other key types
Snowflake supports five constraint types from the ANSI SQL standard. The primary key matters most for data integrity because it identifies each row. A PRIMARY KEY means two things at once: no two rows share the value, and the value is never NULL. A UNIQUE constraint keeps only the first rule, so a UNIQUE column can still contain NULLs. NOT NULL keeps only the second rule. A FOREIGN KEY links a column to a key in another table, or in the same table. A CHECK constraint applies a SQL expression to the values a row is allowed to hold.
There is also a limit on how many of each a table can have. A table can declare several unique keys and several foreign keys, but only one primary key. If a row needs more than one column to identify it, you don't add a second primary key. You define one composite primary key across several columns. The columns in a composite key are ordered, and each column has its own key sequence. That order comes back on the next page, when a foreign key has to reference the key.
Checkpoint 1 of 6· Check yourself
A modeller wants to mark both customer_id and email as unique on a CUSTOMERS table, and customer_id must also never be NULL. Which design is valid?
A table can have only one primary key, but it can have several unique keys. The primary key brings NOT NULL with it. UNIQUE does not, so a UNIQUE column can still hold NULLs.
“A table can have multiple unique keys and foreign keys, but only one primary key.”Source: docs.snowflake.com
Sources1
2.Inline and out-of-line constraint syntax
You can declare a constraint when you create the table with CREATE TABLE, or add it later with ALTER TABLE. There are two ways to write it. An inline constraint is part of a single column's definition, so it can only cover that one column. An out-of-line constraint is a separate clause that names its columns. It works for one column or several, and it is how you add a constraint to columns that already exist. Composite keys therefore have to be written out-of-line. NOT NULL is the reverse case: it can only be written inline.
Give your constraints names with CONSTRAINT <name>. Named constraints are easier to work with later, for example when you change one with ALTER TABLE … ALTER CONSTRAINT. If you leave the name out, the system generates one, and GET_DDL doesn't return that generated name. Also note that GET_DDL always rebuilds primary, unique and foreign keys as out-of-line clauses, even for a single-column key, so the DDL you get back may not look like the DDL you wrote.
ALTER TABLE table1
ADD COLUMN col3 VARCHAR NOT NULL CONSTRAINT uniq_col3 UNIQUE NOT ENFORCED;Checkpoint 2 of 6· Fill the gap
Which key type completes this documented example, which says the column is meant to hold distinct values but may contain NULLs?
ALTER TABLE table1
ADD COLUMN col3 VARCHAR NOT NULL CONSTRAINT uniq_col3 ? NOT ENFORCED;The constraint is named uniq_col3 and declares a unique key. UNIQUE allows NULLs. PRIMARY KEY would add NOT NULL, and CHECK needs an expression.
Source: docs.snowflake.comCheckpoint 3 of 6· Check yourself
You need a primary key on (order_id, line_no). Where must you declare it?
Inline constraints cover a single column only. A composite key needs an out-of-line clause, which you can write in either CREATE TABLE or ALTER TABLE.
“Multi-column constraints (composite unique or primary keys) can only be defined out-of-line.”Source: docs.snowflake.com
Sources1
3.Implementing constraints: what Snowflake actually enforces
This is the central point of the topic. A constraint is enforced when it stops a column from being changed in certain ways. Inserting or copying a NULL into a NOT NULL column raises an error, and a row that fails a CHECK expression is rejected. Primary, unique and foreign keys on standard tables are different: they are optional and not enforced. They exist mainly for data modelling purposes and compatibility with other databases, and to support client tools. For example, Tableau can use them for join culling. Snowflake also warns that violated constraints might cause unexpected downstream effects. If something depends on a key, your pipeline has to keep that key valid.
Hybrid tables work the other way. A hybrid table requires a primary key and enforces it. Its UNIQUE and FOREIGN KEY constraints are enforced whenever they are declared, and you can't mark them NOT ENFORCED.
| Constraint | Standard tables | Hybrid tables |
|---|---|---|
| PRIMARY KEY | Optional, not enforced | Required, enforced |
| FOREIGN KEY | Optional, not enforced | Optional, enforced (referential integrity) |
| UNIQUE | Optional, not enforced | Optional, enforced |
| NOT NULL | Optional, enforced | Optional, enforced |
| CHECK | Optional, enforced | Optional, enforced; can be defined only at table creation |
Checkpoint 4 of 6· Match them up
Match each constraint to how a standard Snowflake table treats it
Tap a term, then the definition that fits it.
On standard tables, only NOT NULL and CHECK reject data. The three key types are recorded as metadata.
“doesn’t enforce them, except for NOT NULL and CHECK constraints, which are always enforced.”Source: docs.snowflake.com
Checkpoint 5 of 6· Exam question
An analyst migrates an `orders` table from PostgreSQL into a standard Snowflake table declared with `order_id NUMBER PRIMARY KEY`. A nightly reload from the source accidentally replays the same file, and the COPY INTO command finishes without errors. A report now shows the same `order_id` twice. What explains this behavior?
Correct answer: A — Snowflake records primary keys on standard tables as metadata only, so COPY INTO accepted the repeated `order_id` values and the duplicates now sit in the table.
- A. Correct: on standard tables Snowflake stores PRIMARY KEY, UNIQUE and FOREIGN KEY as informational metadata and enforces only NOT NULL, so the replayed rows load without any error.
- B. Incorrect: `ON_ERROR` governs file parsing and data conversion errors, not key uniqueness. No load option makes a standard table reject duplicate keys.
- C. Incorrect: inline and out-of-line declarations behave identically in Snowflake. Neither style enforces uniqueness on a standard table.
- D. Incorrect: clustering keys only influence micro-partition organization and have no connection to constraint enforcement.
4.CHECK constraints and constraint properties
CHECK is the one constraint on a standard table that can enforce a business rule. Snowflake evaluates it on INSERT, UPDATE, MERGE and CTAS. A row is rejected only when the expression evaluates to FALSE. A NULL result lets the row through, so pair CHECK with NOT NULL if the column must always have a value. An inline CHECK can refer only to its own column. A rule that compares two columns has to be written out-of-line. The expression can't use UDFs, subqueries, aggregate functions, or non-deterministic functions such as RANDOM. Some loading paths don't support tables with CHECK constraints. For example, a COPY INTO into such a table fails.
CREATE TABLE test_check_constraint_orders (
order_id INT,
quantity INT CHECK (quantity > 0),
price NUMBER(10, 2));Key constraints also take properties such as ENFORCED, DEFERRABLE, ENABLE/DISABLE, VALIDATE/NOVALIDATE and RELY/NORELY. Snowflake accepts these to make migration from other databases easier, but on standard tables it does not act on them. The defaults are NOT ENFORCED, DISABLE and NOVALIDATE. One rule catches people out: if you set ENABLE or VALIDATE on a new primary, unique or foreign key, Snowflake does not create the constraint. RELY is the exception, because specifying RELY still creates the constraint. The session parameter UNSUPPORTED_DDL_ACTION decides whether these non-default values raise an error.
Checkpoint 6 of 6· Check yourself
A migration script creates a standard table with PRIMARY KEY (id) ENABLE VALIDATE, hoping this makes Snowflake enforce the key. What is the result?
ENABLE and VALIDATE are non-default values. For primary, unique and foreign keys, using them means the constraint isn't created at all.
“if you specify ENABLE or VALIDATE (the non-default values for these properties) when creating a new constraint, the constraint isn’t created.”Source: docs.snowflake.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A PRIMARY KEY on a standard Snowflake table blocks duplicate rows.Why is that wrong?
On standard tables, primary, unique and foreign keys are optional and not enforced. Only NOT NULL and CHECK reject data.
Covered in Implementing constraints: what Snowflake actually enforces
2.Adding ENABLE or VALIDATE to a primary key makes Snowflake check it.Why is that wrong?
These are non-default values. On primary, unique and foreign keys they stop the constraint from being created at all. Only RELY still creates it.
Covered in CHECK constraints and constraint properties
3.A UNIQUE column, like a primary key, cannot contain NULLs.Why is that wrong?
UNIQUE only guarantees distinct values. NOT NULL comes with PRIMARY KEY, not with UNIQUE.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“A PRIMARY KEY constraint implies that the column is both NOT NULL and UNIQUE.”
↩︎ Defining primary keys and the other key types“For multi-column constraints (composite primary keys or unique keys), the columns are ordered, and each column has a corresponding key sequence.”
↩︎ Defining primary keys and the other key types“Inline constraints are created as part of the column definition and can only be used for single-column constraints.”
↩︎ Inline and out-of-line constraint syntax“Table constraints, such as unique, primary, and foreign keys, are always reconstructed as out-of-line constraints, even if they consist of a single column.”
↩︎ Inline and out-of-line constraint syntax“An attempt to copy or insert a NULL value into a NOT NULL column results in an error.”
↩︎ Implementing constraints: what Snowflake actually enforces“If the condition evaluates to TRUE or NULL, the DML operation proceeds.”
↩︎ CHECK constraints and constraint properties“If you attempt to COPY INTO a table with CHECK constraints, the operation fails.”
↩︎ CHECK constraints and constraint properties“Unlike a PRIMARY KEY constraint, a column with a UNIQUE constraint can have NULL values.”
↩︎ Exam trap 3“A table can have multiple unique keys and foreign keys, but only one primary key.”
↩︎ Checkpoint - 2.
“provided primarily for data modeling purposes and compatibility with other databases”
↩︎ Implementing constraints: what Snowflake actually enforces“Primary key constraints are required and enforced on all hybrid tables, and other constraints are enforced when used.”
↩︎ Implementing constraints: what Snowflake actually enforces“doesn’t enforce them, except for NOT NULL and CHECK constraints, which are always enforced.”
↩︎ Key concept“doesn’t enforce them, except for NOT NULL and CHECK constraints, which are always enforced.”
↩︎ Checkpoint - 3.
“An inline CHECK constraint can reference only the column it’s defined on.”
↩︎ CHECK constraints and constraint properties“For standard tables, NOT NULL and CHECK are the only types of constraints that are enforced by Snowflake, regardless of this property.”
↩︎ Exam trap 1“This doesn’t apply to RELY. Specifying RELY does result in the creation of the new constraint.”
↩︎ Exam trap 2“Multi-column constraints (composite unique or primary keys) can only be defined out-of-line.”
↩︎ Checkpoint“For standard tables, NOT NULL and CHECK are the only types of constraints that are enforced by Snowflake, regardless of this property.”
↩︎ Prediction“if you specify ENABLE or VALIDATE (the non-default values for these properties) when creating a new constraint, the constraint isn’t created.”
↩︎ Checkpoint