What you will be able to do
- State which constraint types Snowflake enforces on standard tables compared with hybrid tables
- Explain what the ENABLE, VALIDATE and RELY properties do and what their defaults are
- Explain how RELY allows join elimination, and the risk of setting it on data that doesn't comply
1.Which constraints Snowflake actually enforces
Snowflake supports the five ANSI constraint types: PRIMARY KEY, UNIQUE, FOREIGN KEY, NOT NULL and CHECK. A table can have several unique keys and foreign keys but only one primary key. Whether a constraint is enforced depends on the table type, not on how you declare it.
| 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 |
On standard tables, NOT NULL and CHECK are the only constraints Snowflake enforces, and that holds whatever the ENFORCED property says. A duplicate primary key value or an orphaned foreign key loads without any error. On hybrid tables you can't set NOT ENFORCED on PRIMARY KEY, FOREIGN KEY or UNIQUE constraints.
CHECK constraints are checked during INSERT, UPDATE, MERGE and CREATE TABLE … AS SELECT. If the condition evaluates to TRUE or NULL, the operation goes ahead. If it evaluates to FALSE, the operation fails. This matters for ingestion design: a COPY INTO a table with CHECK constraints fails, and so does creating a pipe that targets one.
Checkpoint 1 of 6· Exam question
A data architect describes a Snowflake schema design where a central fact table storing sales transactions is directly joined to denormalized dimension tables such as CUSTOMER, PRODUCT, and DATE, each containing all descriptive attributes in a single table. Which data modeling approach does this describe?
Correct answer: A — Star schema
- A. This denormalized structure, with a central fact table connected directly to flat dimension tables, is the defining shape of this model. It favors simple, fast joins for reporting and BI tools over storage efficiency.
- B. This hub-link-satellite structure decomposes business keys, relationships, and descriptive attributes into separate table types rather than flat dimensions. It prioritizes auditability and resilience to source changes over query simplicity.
- C. This variant normalizes dimension tables into sub-dimensions, producing extra joins per dimension. That normalization reduces redundancy but adds the join complexity the scenario does not describe.
- D. This normalization level removes nearly all redundancy by decomposing tables on functional dependencies. It is rarely used for analytical fact/dimension reporting because of the many joins required.
Checkpoint 2 of 6· Check yourself
A standard table has CHECK (quantity > 0). An INSERT supplies a row where quantity is NULL. What happens?
A CHECK condition only blocks the operation when it evaluates to FALSE. Comparing NULL gives NULL, so the row is accepted.
“If the condition evaluates to TRUE or NULL, the DML operation proceeds.”Source: docs.snowflake.com
2.ENABLE, VALIDATE and RELY: Snowflake's extension properties
Key constraints accept a set of properties: [NOT] ENFORCED, [NOT] DEFERRABLE, INITIALLY {DEFERRED | IMMEDIATE}, ENABLE | DISABLE, VALIDATE | NOVALIDATE, and RELY | NORELY. The last three are Snowflake extensions, not ANSI properties. On standard tables, these properties are there to make migrating from other databases easier, and Snowflake neither enforces nor maintains them. You can change their defaults, but if you do, Snowflake doesn't create the constraint. The one exception is RELY.
| Property | What it specifies | Default |
|---|---|---|
| ENFORCED | NOT ENFORCED | Whether the constraint is enforced in a transaction | NOT ENFORCED |
| ENABLE | DISABLE | Whether the constraint is enabled; provided for compatibility with Oracle | DISABLE |
| VALIDATE | NOVALIDATE | Whether to validate existing data on the table when the constraint is created | NOVALIDATE for PRIMARY KEY and FOREIGN KEY; VALIDATE for CHECK |
| RELY | NORELY | Whether a NOVALIDATE constraint is taken into account during query rewrite | NORELY |
CHECK constraints use ENABLE with either VALIDATE or NOVALIDATE. ENABLE VALIDATE is the default. It applies the check to existing rows and to every later insert or update, but you can only use it on new tables. ENABLE NOVALIDATE applies the check only to rows inserted or updated after you run the command. If you later switch a CHECK from NOVALIDATE to VALIDATE, Snowflake checks all existing rows before making the change.
After a constraint exists, you can change some properties, such as RELY, with ALTER TABLE. Others, such as DEFERRABLE, can't be changed: you have to drop the constraint and create it again.
ALTER TABLE <table_name>
{ ALTER | MODIFY } {
CONSTRAINT <name>
| PRIMARY KEY
| { UNIQUE | FOREIGN KEY } (<column_name>, [ ... ] )
}
{ [ [ NOT ] ENFORCED ] [ VALIDATE | NOVALIDATE ] [ RELY | NORELY ] };Checkpoint 3 of 6· Match them up
Match each constraint property to what the documentation says about it
Tap a term, then the definition that fits it.
ENABLE and VALIDATE are mainly there for migration compatibility. RELY is the property the optimizer actually uses. DEFERRABLE can't be changed in place.
“Specifies whether a constraint in NOVALIDATE mode is taken into account during query rewrite.”Source: docs.snowflake.com
Checkpoint 4 of 6· Exam question
A BI team building executive dashboards in Tableau reports that ad hoc drill-down queries against the star-schema sales mart run consistently fast, even though analysts frequently change which dimensions they filter on. Which characteristic of the star schema design best explains this consistent performance?
Correct answer: A — Denormalized dimension tables mean each fact-to-dimension join touches only one table per dimension, keeping join depth shallow no matter which filters analysts pick.
- A. Because every dimension is one flat table, a fact row always reaches any attribute in a single join, so switching filter columns never adds join depth — this is what keeps performance consistent.
- B. Star schema dimensions are intentionally denormalized, not split into sub-tables, so this describes a different, more normalized design and does not match what is producing the consistent performance.
- C. Hubs and satellites are a Data Vault concept, not a feature of the star schema mart described here, so this does not explain the dashboard's query behavior.
- D. Point-in-time satellite versioning belongs to Data Vault history tracking; a star schema fact table in this scenario is not described as storing attribute version history.
3.RELY and join elimination
SELECT f.*
FROM fact_sales f
LEFT OUTER JOIN dim_products p
ON f.product_id = p.product_id;The join is unnecessary because the query doesn't use any dim_products column apart from the join key. If dim_products.product_id carries a UNIQUE or PRIMARY KEY constraint with RELY, Snowflake drops the reference to dim_products. The documentation shows the same optimization for an unnecessary self-join and for an unnecessary join on a primary key and foreign key. When a primary key and a foreign key are related, set RELY on both of them. Client tools can benefit too: Tableau, for example, uses constraints for join culling.
RELY doesn't check anything. It tells the optimizer to trust that the data meets the constraint, and making sure that's true is your job. If the data breaks the constraint, a query can return different results with RELY than with NORELY. It's worse for writes: DML and CTAS statements may insert incorrect data. The safe pattern is to verify integrity in the pipeline, set RELY, and keep verifying.
Checkpoint 5 of 6· Exam question
A retail analytics team maintains a star schema where the PRODUCT dimension stores category, subcategory, brand, and supplier name directly in one wide table. Six months after launch, the team notices they must update thousands of dimension rows whenever a supplier renames a brand, and storage for the dimension table has grown faster than the count of distinct products. Which TWO limitations of the star schema design explain what the team is experiencing? (Select 2)(Select 2)
Correct answers: A, B — Denormalizing descriptive attributes into one wide dimension table duplicates values like brand and supplier name across every row sharing them, so storage scales with row count, not distinct values.; Flattening hierarchical attributes such as category and subcategory into a single table means a rename at any level must propagate to every dimension row that references it, creating a wide update.
- A. Repeating brand and supplier text on every dimension row instead of normalizing it into a lookup table is exactly why storage grows faster than the count of distinct products — this is the standard denormalization trade-off in this design.
- B. Because category, subcategory, and brand live in one flat table, a single supplier rename has to be written to every row that mentions that supplier, which is the wide-reaching update the team observed.
- C. Splitting business keys from descriptive attributes into hubs and satellites is a Data Vault technique the team's design does not use, so it does not explain the behavior they are seeing.
- D. The design deliberately keeps dimension tables flat and denormalized rather than enforcing normalization rules, so there is no missing lookup table causing this; the wide table is the design as intended.
- E. The fact table holds numeric measures and foreign keys, not descriptive text like supplier name, so updating a supplier does not touch fact table rows at all and is unrelated to the issue described.
Checkpoint 6 of 6· Check yourself
RELY is set on the PRIMARY KEY of CUSTOMER and the FOREIGN KEY on ORDERS. A later load inserts orders with customer_id values that aren't in CUSTOMER. What is the risk?
RELY doesn't validate or enforce anything on standard tables. It lets the optimizer rewrite queries on the assumption that the data complies, so bad data can produce wrong results.
“If the integrity of your constraints is not maintained, the query results might differ if the RELY constraint property is set”Source: docs.snowflake.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Declaring a PRIMARY KEY or FOREIGN KEY on a standard table stops duplicate or orphaned rows from being loaded.Why is that wrong?
On standard tables, only NOT NULL and CHECK are enforced. Key constraints are informational, and only hybrid tables enforce them.
2.Setting RELY makes Snowflake validate the data against the constraint.Why is that wrong?
RELY only lets the optimizer take the constraint into account when it rewrites queries. Making sure the data complies is still your responsibility.
Covered in RELY and join elimination
3.You can add a CHECK constraint with ENABLE VALIDATE to an existing table to check the rows already in it.Why is that wrong?
ENABLE VALIDATE is only supported for new tables. On an existing table, ENABLE NOVALIDATE checks only rows inserted or updated afterwards.
Covered in ENABLE, VALIDATE and RELY: Snowflake's extension properties
Practise it for real
Show that key constraints on standard tables are informational metadata, then mark them for the optimizer to use with RELY
1.Run the CREATE OR REPLACE TABLE statements for salespeople and salesorders from Snowflake's table design documentation
Why: These give you a primary key and an out-of-line foreign key between two standard tables
You should see: Both tables are created, with constraints PK_SP_ID, PK_ORDER_ID and FK_SP_ID
2.Insert a row into salesorders whose sp_id has no matching row in salespeople
Why: This shows that FOREIGN KEY constraints are not enforced on standard tables
You should see: The insert succeeds without an error
3.Run SELECT GET_DDL('TABLE', 'mydb.public.salesorders'); using your own database name
Why: GET_DDL returns the constraints currently defined on the table
You should see: Key constraints appear as out-of-line clauses. The unnamed unique constraint is shown without its system-generated name.
4.Query INFORMATION_SCHEMA.TABLE_CONSTRAINTS for the schema, filtering on constraint_schema = 'PUBLIC'
Why: This lists every table constraint in the schema, which is useful for auditing a model
You should see: A row for each constraint, including SYS_CONSTRAINT_ names for the unnamed UNIQUE constraints
5.Delete the orphaned row, then use ALTER TABLE … ALTER CONSTRAINT … RELY on both pk_sp_id and fk_sp_id
Why: Set RELY only after the data complies, and set it on both related constraints
You should see: Both constraints now have the RELY property. No data is checked when you do this.
Stuck? Get a nudge
If the RELY step seems to have no effect, remember that RELY changes how the optimizer treats queries, not what data the table accepts.
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.”
↩︎ Which constraints Snowflake actually enforces“If you attempt to COPY INTO a table with CHECK constraints, the operation fails.”
↩︎ Which constraints Snowflake actually enforces“ENABLE NOVALIDATE enforces the constraint for all rows that are inserted or updated after you run the command”
↩︎ ENABLE, VALIDATE and RELY: Snowflake's extension properties“ENABLE VALIDATE is only supported for new tables, not for existing tables.”
↩︎ Exam trap 3“If the condition evaluates to TRUE or NULL, the DML operation proceeds.”
↩︎ Checkpoint - 2.
“For standard tables, NOT NULL and CHECK are the only types of constraints that are enforced by Snowflake”
↩︎ Which constraints Snowflake actually enforces“these properties are provided to facilitate migrating from other databases. They are not enforced or maintained by Snowflake.”
↩︎ ENABLE, VALIDATE and RELY: Snowflake's extension properties“changing the defaults results in Snowflake not creating the constraint”
↩︎ ENABLE, VALIDATE and RELY: Snowflake's extension properties“These properties are provided for compatibility with Oracle.”
↩︎ ENABLE, VALIDATE and RELY: Snowflake's extension properties“For related PRIMARY KEY and FOREIGN KEY constraints, set this property on both constraints.”
↩︎ RELY and join elimination“a violation of referential integrity occurs, DML and CTAS statements might insert incorrect data”
↩︎ RELY and join elimination“For standard tables, NOT NULL and CHECK are the only types of constraints that are enforced by Snowflake”
↩︎ Exam trap 1“For standard tables, it is your responsibility to enforce RELY constraints; otherwise, you might risk unintended behavior and unexpected results.”
↩︎ Exam trap 2“Specifies whether a constraint in NOVALIDATE mode is taken into account during query rewrite.”
↩︎ Checkpoint - 3.
“Some properties can be modified; for example, RELY.”
↩︎ ENABLE, VALIDATE and RELY: Snowflake's extension properties - 4.
“The join is unnecessary because the statement does not refer to any columns in the dim_products table on the right”
↩︎ RELY and join elimination“If the dim_products.product_id column has the UNIQUE or PRIMARY KEY constraint with the RELY property, Snowflake can identify this join as unnecessary”
↩︎ Prediction“If the integrity of your constraints is not maintained, the query results might differ if the RELY constraint property is set”
↩︎ Checkpoint - 5.
“Tableau supports using constraints to perform join culling (join elimination)”
↩︎ RELY and join elimination